Repository: TanStack/table Branch: alpha Commit: 2a4533e9177b Files: 2187 Total size: 3.5 MB Directory structure: gitextract_yn2n45g7/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── config.yml │ ├── pull_request_template │ └── workflows/ │ ├── autofix.yml │ ├── pr.yml │ └── release.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .nx/ │ └── workflows/ │ └── dynamic-changesets.yaml ├── .prettierignore ├── .vscode/ │ └── extensions.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs/ │ ├── config.json │ ├── enterprise/ │ │ └── ag-grid.md │ ├── faq.md │ ├── framework/ │ │ ├── angular/ │ │ │ ├── angular-table.md │ │ │ ├── guide/ │ │ │ │ ├── migrating.md │ │ │ │ ├── rendering.md │ │ │ │ ├── table-composition.md │ │ │ │ └── table-state.md │ │ │ └── reference/ │ │ │ ├── classes/ │ │ │ │ ├── FlexRenderCell.md │ │ │ │ ├── FlexRenderComponentInstance.md │ │ │ │ ├── FlexRenderDirective.md │ │ │ │ ├── TanStackTable.md │ │ │ │ ├── TanStackTableCell.md │ │ │ │ └── TanStackTableHeader.md │ │ │ ├── functions/ │ │ │ │ ├── createTableHook.md │ │ │ │ ├── flexRenderComponent.md │ │ │ │ ├── injectFlexRenderContext.md │ │ │ │ ├── injectTable.md │ │ │ │ ├── injectTableCellContext.md │ │ │ │ ├── injectTableContext.md │ │ │ │ └── injectTableHeaderContext.md │ │ │ ├── index.md │ │ │ ├── interfaces/ │ │ │ │ ├── AngularReactivityFlags.md │ │ │ │ ├── FlexRenderComponent.md │ │ │ │ ├── TanStackTableCellContext.md │ │ │ │ └── TanStackTableHeaderContext.md │ │ │ ├── type-aliases/ │ │ │ │ ├── AngularTable.md │ │ │ │ ├── AppAngularTable.md │ │ │ │ ├── AppCellContext.md │ │ │ │ ├── AppColumnHelper.md │ │ │ │ ├── AppHeaderContext.md │ │ │ │ ├── CreateTableContextOptions.md │ │ │ │ ├── CreateTableHookResult.md │ │ │ │ ├── FlexRenderComponentProps.md │ │ │ │ ├── FlexRenderContent.md │ │ │ │ └── FlexRenderInputContent.md │ │ │ └── variables/ │ │ │ ├── FlexRender.md │ │ │ ├── TanStackTableCellToken.md │ │ │ ├── TanStackTableHeaderToken.md │ │ │ └── TanStackTableToken.md │ │ ├── lit/ │ │ │ ├── guide/ │ │ │ │ └── table-state.md │ │ │ └── lit-table.md │ │ ├── preact/ │ │ │ └── guide/ │ │ │ └── create-table-hook.md │ │ ├── react/ │ │ │ ├── guide/ │ │ │ │ ├── create-table-hook.md │ │ │ │ ├── migrating.md │ │ │ │ ├── table-state.md │ │ │ │ └── use-legacy-table.md │ │ │ ├── react-table.md │ │ │ └── reference/ │ │ │ ├── index/ │ │ │ │ ├── functions/ │ │ │ │ │ ├── FlexRender-1.md │ │ │ │ │ ├── Subscribe.md │ │ │ │ │ ├── createTableHook.md │ │ │ │ │ ├── flexRender.md │ │ │ │ │ └── useTable.md │ │ │ │ ├── index.md │ │ │ │ ├── interfaces/ │ │ │ │ │ ├── AppCellComponent.md │ │ │ │ │ ├── AppCellPropsWithSelector.md │ │ │ │ │ ├── AppCellPropsWithoutSelector.md │ │ │ │ │ ├── AppHeaderComponent.md │ │ │ │ │ ├── AppHeaderPropsWithSelector.md │ │ │ │ │ ├── AppHeaderPropsWithoutSelector.md │ │ │ │ │ ├── AppTableComponent.md │ │ │ │ │ ├── AppTablePropsWithSelector.md │ │ │ │ │ └── AppTablePropsWithoutSelector.md │ │ │ │ └── type-aliases/ │ │ │ │ ├── AppCellContext.md │ │ │ │ ├── AppColumnHelper.md │ │ │ │ ├── AppHeaderContext.md │ │ │ │ ├── AppReactTable.md │ │ │ │ ├── CreateTableHookOptions.md │ │ │ │ ├── FlexRenderProps.md │ │ │ │ ├── ReactTable.md │ │ │ │ ├── Renderable.md │ │ │ │ └── SubscribeProps.md │ │ │ ├── index.md │ │ │ └── legacy/ │ │ │ ├── functions/ │ │ │ │ ├── getCoreRowModel.md │ │ │ │ ├── getExpandedRowModel.md │ │ │ │ ├── getFacetedMinMaxValues.md │ │ │ │ ├── getFacetedRowModel.md │ │ │ │ ├── getFacetedUniqueValues.md │ │ │ │ ├── getFilteredRowModel.md │ │ │ │ ├── getGroupedRowModel.md │ │ │ │ ├── getPaginationRowModel.md │ │ │ │ ├── getSortedRowModel.md │ │ │ │ ├── legacyCreateColumnHelper.md │ │ │ │ └── useLegacyTable.md │ │ │ ├── index.md │ │ │ ├── interfaces/ │ │ │ │ └── LegacyRowModelOptions.md │ │ │ └── type-aliases/ │ │ │ ├── LegacyCell.md │ │ │ ├── LegacyColumn.md │ │ │ ├── LegacyColumnDef.md │ │ │ ├── LegacyHeader.md │ │ │ ├── LegacyHeaderGroup.md │ │ │ ├── LegacyReactTable.md │ │ │ ├── LegacyRow.md │ │ │ ├── LegacyTable.md │ │ │ └── LegacyTableOptions.md │ │ ├── solid/ │ │ │ ├── guide/ │ │ │ │ └── table-state.md │ │ │ └── solid-table.md │ │ ├── svelte/ │ │ │ ├── guide/ │ │ │ │ └── table-state.md │ │ │ └── svelte-table.md │ │ ├── vanilla/ │ │ │ ├── guide/ │ │ │ │ └── table-state.md │ │ │ └── table-core.md │ │ └── vue/ │ │ ├── guide/ │ │ │ └── table-state.md │ │ └── vue-table.md │ ├── guide/ │ │ ├── cells.md │ │ ├── column-defs.md │ │ ├── column-faceting.md │ │ ├── column-filtering.md │ │ ├── column-ordering.md │ │ ├── column-pinning.md │ │ ├── column-sizing.md │ │ ├── column-visibility.md │ │ ├── columns.md │ │ ├── custom-features.md │ │ ├── data.md │ │ ├── expanding.md │ │ ├── features.md │ │ ├── filters.md │ │ ├── fuzzy-filtering.md │ │ ├── global-faceting.md │ │ ├── global-filtering.md │ │ ├── grouping.md │ │ ├── header-groups.md │ │ ├── headers.md │ │ ├── pagination.md │ │ ├── pinning.md │ │ ├── row-models.md │ │ ├── row-pinning.md │ │ ├── row-selection.md │ │ ├── rows.md │ │ ├── sorting.md │ │ ├── tables.md │ │ └── virtualization.md │ ├── installation.md │ ├── introduction.md │ ├── overview.md │ ├── reference/ │ │ ├── @tanstack/ │ │ │ └── namespaces/ │ │ │ ├── filterFn_arrIncludes/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_arrIncludesAll/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_arrIncludesSome/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_equals/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_equalsString/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_equalsStringSensitive/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_greaterThan/ │ │ │ │ ├── functions/ │ │ │ │ │ └── resolveFilterValue.md │ │ │ │ └── index.md │ │ │ ├── filterFn_greaterThanOrEqualTo/ │ │ │ │ ├── functions/ │ │ │ │ │ └── resolveFilterValue.md │ │ │ │ └── index.md │ │ │ ├── filterFn_inNumberRange/ │ │ │ │ ├── functions/ │ │ │ │ │ ├── autoRemove.md │ │ │ │ │ └── resolveFilterValue.md │ │ │ │ └── index.md │ │ │ ├── filterFn_includesString/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_includesStringSensitive/ │ │ │ │ ├── functions/ │ │ │ │ │ └── autoRemove.md │ │ │ │ └── index.md │ │ │ ├── filterFn_lessThan/ │ │ │ │ ├── functions/ │ │ │ │ │ └── resolveFilterValue.md │ │ │ │ └── index.md │ │ │ ├── filterFn_lessThanOrEqualTo/ │ │ │ │ ├── functions/ │ │ │ │ │ └── resolveFilterValue.md │ │ │ │ └── index.md │ │ │ └── filterFn_weakEquals/ │ │ │ ├── functions/ │ │ │ │ └── autoRemove.md │ │ │ └── index.md │ │ ├── functions/ │ │ │ ├── assignPrototypeAPIs.md │ │ │ ├── assignTableAPIs.md │ │ │ ├── buildHeaderGroups.md │ │ │ ├── callMemoOrStaticFn.md │ │ │ ├── cell_getContext.md │ │ │ ├── cell_getIsAggregated.md │ │ │ ├── cell_getIsGrouped.md │ │ │ ├── cell_getIsPlaceholder.md │ │ │ ├── cell_getValue.md │ │ │ ├── cell_renderValue.md │ │ │ ├── column_clearSorting.md │ │ │ ├── column_getAfter.md │ │ │ ├── column_getAggregationFn.md │ │ │ ├── column_getAutoAggregationFn.md │ │ │ ├── column_getAutoFilterFn.md │ │ │ ├── column_getAutoSortDir.md │ │ │ ├── column_getAutoSortFn.md │ │ │ ├── column_getCanFilter.md │ │ │ ├── column_getCanGlobalFilter.md │ │ │ ├── column_getCanGroup.md │ │ │ ├── column_getCanHide.md │ │ │ ├── column_getCanMultiSort.md │ │ │ ├── column_getCanPin.md │ │ │ ├── column_getCanResize.md │ │ │ ├── column_getCanSort.md │ │ │ ├── column_getFacetedMinMaxValues.md │ │ │ ├── column_getFacetedRowModel.md │ │ │ ├── column_getFacetedUniqueValues.md │ │ │ ├── column_getFilterFn.md │ │ │ ├── column_getFilterIndex.md │ │ │ ├── column_getFilterValue.md │ │ │ ├── column_getFirstSortDir.md │ │ │ ├── column_getFlatColumns.md │ │ │ ├── column_getGroupedIndex.md │ │ │ ├── column_getIndex.md │ │ │ ├── column_getIsFiltered.md │ │ │ ├── column_getIsFirstColumn.md │ │ │ ├── column_getIsGrouped.md │ │ │ ├── column_getIsLastColumn.md │ │ │ ├── column_getIsPinned.md │ │ │ ├── column_getIsResizing.md │ │ │ ├── column_getIsSorted.md │ │ │ ├── column_getIsVisible.md │ │ │ ├── column_getLeafColumns.md │ │ │ ├── column_getNextSortingOrder.md │ │ │ ├── column_getPinnedIndex.md │ │ │ ├── column_getSize.md │ │ │ ├── column_getSortFn.md │ │ │ ├── column_getSortIndex.md │ │ │ ├── column_getStart.md │ │ │ ├── column_getToggleGroupingHandler.md │ │ │ ├── column_getToggleSortingHandler.md │ │ │ ├── column_getToggleVisibilityHandler.md │ │ │ ├── column_pin.md │ │ │ ├── column_resetSize.md │ │ │ ├── column_setFilterValue.md │ │ │ ├── column_toggleGrouping.md │ │ │ ├── column_toggleSorting.md │ │ │ ├── column_toggleVisibility.md │ │ │ ├── constructCell.md │ │ │ ├── constructColumn.md │ │ │ ├── constructColumnFacetingFeature.md │ │ │ ├── constructColumnFilteringFeature.md │ │ │ ├── constructColumnGroupingFeature.md │ │ │ ├── constructColumnOrderingFeature.md │ │ │ ├── constructColumnPinningFeature.md │ │ │ ├── constructColumnResizingFeature.md │ │ │ ├── constructColumnSizingFeature.md │ │ │ ├── constructColumnVisibilityFeature.md │ │ │ ├── constructCoreCellsFeature.md │ │ │ ├── constructCoreColumnsFeature.md │ │ │ ├── constructCoreHeadersFeature.md │ │ │ ├── constructCoreRowModelsFeature.md │ │ │ ├── constructCoreRowsFeature.md │ │ │ ├── constructCoreTablesFeature.md │ │ │ ├── constructGlobalFilteringFeature.md │ │ │ ├── constructHeader.md │ │ │ ├── constructRow.md │ │ │ ├── constructRowExpandingFeature.md │ │ │ ├── constructRowPaginationFeature.md │ │ │ ├── constructRowPinningFeature.md │ │ │ ├── constructRowSelectionFeature.md │ │ │ ├── constructRowSortingFeature.md │ │ │ ├── constructTable.md │ │ │ ├── constructTableHelper.md │ │ │ ├── createColumnHelper.md │ │ │ ├── createCoreRowModel.md │ │ │ ├── createExpandedRowModel.md │ │ │ ├── createFacetedMinMaxValues.md │ │ │ ├── createFacetedRowModel.md │ │ │ ├── createFacetedUniqueValues.md │ │ │ ├── createFilteredRowModel.md │ │ │ ├── createGroupedRowModel.md │ │ │ ├── createPaginatedRowModel.md │ │ │ ├── createSortedRowModel.md │ │ │ ├── createTableStore.md │ │ │ ├── expandRows.md │ │ │ ├── flattenBy.md │ │ │ ├── functionalUpdate.md │ │ │ ├── getDefaultColumnFiltersState.md │ │ │ ├── getDefaultColumnOrderState.md │ │ │ ├── getDefaultColumnPinningState.md │ │ │ ├── getDefaultColumnResizingState.md │ │ │ ├── getDefaultColumnSizingColumnDef.md │ │ │ ├── getDefaultColumnSizingState.md │ │ │ ├── getDefaultColumnVisibilityState.md │ │ │ ├── getDefaultExpandedState.md │ │ │ ├── getDefaultGroupingState.md │ │ │ ├── getDefaultPaginationState.md │ │ │ ├── getDefaultRowPinningState.md │ │ │ ├── getDefaultRowSelectionState.md │ │ │ ├── getDefaultSortingState.md │ │ │ ├── getFunctionNameInfo.md │ │ │ ├── getInitialTableState.md │ │ │ ├── getMemoFnMeta.md │ │ │ ├── header_getContext.md │ │ │ ├── header_getLeafHeaders.md │ │ │ ├── header_getResizeHandler.md │ │ │ ├── header_getSize.md │ │ │ ├── header_getStart.md │ │ │ ├── isFunction.md │ │ │ ├── isNumberArray.md │ │ │ ├── isRowSelected.md │ │ │ ├── isSubRowSelected.md │ │ │ ├── isTouchStartEvent.md │ │ │ ├── makeStateUpdater.md │ │ │ ├── memo.md │ │ │ ├── noop.md │ │ │ ├── orderColumns.md │ │ │ ├── passiveEventSupported.md │ │ │ ├── row_getAllCells.md │ │ │ ├── row_getAllCellsByColumnId.md │ │ │ ├── row_getAllVisibleCells.md │ │ │ ├── row_getCanExpand.md │ │ │ ├── row_getCanMultiSelect.md │ │ │ ├── row_getCanPin.md │ │ │ ├── row_getCanSelect.md │ │ │ ├── row_getCanSelectSubRows.md │ │ │ ├── row_getCenterVisibleCells.md │ │ │ ├── row_getGroupingValue.md │ │ │ ├── row_getIsAllParentsExpanded.md │ │ │ ├── row_getIsAllSubRowsSelected.md │ │ │ ├── row_getIsExpanded.md │ │ │ ├── row_getIsGrouped.md │ │ │ ├── row_getIsPinned.md │ │ │ ├── row_getIsSelected.md │ │ │ ├── row_getIsSomeSelected.md │ │ │ ├── row_getLeafRows.md │ │ │ ├── row_getLeftVisibleCells.md │ │ │ ├── row_getParentRow.md │ │ │ ├── row_getParentRows.md │ │ │ ├── row_getPinnedIndex.md │ │ │ ├── row_getRightVisibleCells.md │ │ │ ├── row_getToggleExpandedHandler.md │ │ │ ├── row_getToggleSelectedHandler.md │ │ │ ├── row_getUniqueValues.md │ │ │ ├── row_getValue.md │ │ │ ├── row_getVisibleCells.md │ │ │ ├── row_pin.md │ │ │ ├── row_renderValue.md │ │ │ ├── row_toggleExpanded.md │ │ │ ├── row_toggleSelected.md │ │ │ ├── selectRowsFn.md │ │ │ ├── shouldAutoRemoveFilter.md │ │ │ ├── tableFeatures.md │ │ │ ├── tableMemo.md │ │ │ ├── tableOptions.md │ │ │ ├── table_autoResetExpanded.md │ │ │ ├── table_autoResetPageIndex.md │ │ │ ├── table_firstPage.md │ │ │ ├── table_getAllColumns.md │ │ │ ├── table_getAllFlatColumns.md │ │ │ ├── table_getAllFlatColumnsById.md │ │ │ ├── table_getAllLeafColumns.md │ │ │ ├── table_getBottomRows.md │ │ │ ├── table_getCanNextPage.md │ │ │ ├── table_getCanPreviousPage.md │ │ │ ├── table_getCanSomeRowsExpand.md │ │ │ ├── table_getCenterFlatHeaders.md │ │ │ ├── table_getCenterFooterGroups.md │ │ │ ├── table_getCenterHeaderGroups.md │ │ │ ├── table_getCenterLeafColumns.md │ │ │ ├── table_getCenterLeafHeaders.md │ │ │ ├── table_getCenterRows.md │ │ │ ├── table_getCenterTotalSize.md │ │ │ ├── table_getCenterVisibleLeafColumns.md │ │ │ ├── table_getColumn.md │ │ │ ├── table_getCoreRowModel.md │ │ │ ├── table_getDefaultColumnDef.md │ │ │ ├── table_getExpandedDepth.md │ │ │ ├── table_getExpandedRowModel.md │ │ │ ├── table_getFilteredRowModel.md │ │ │ ├── table_getFilteredSelectedRowModel.md │ │ │ ├── table_getFlatHeaders.md │ │ │ ├── table_getFooterGroups.md │ │ │ ├── table_getGlobalAutoFilterFn.md │ │ │ ├── table_getGlobalFacetedMinMaxValues.md │ │ │ ├── table_getGlobalFacetedRowModel.md │ │ │ ├── table_getGlobalFacetedUniqueValues.md │ │ │ ├── table_getGlobalFilterFn.md │ │ │ ├── table_getGroupedRowModel.md │ │ │ ├── table_getGroupedSelectedRowModel.md │ │ │ ├── table_getHeaderGroups.md │ │ │ ├── table_getIsAllColumnsVisible.md │ │ │ ├── table_getIsAllPageRowsSelected.md │ │ │ ├── table_getIsAllRowsExpanded.md │ │ │ ├── table_getIsAllRowsSelected.md │ │ │ ├── table_getIsSomeColumnsPinned.md │ │ │ ├── table_getIsSomeColumnsVisible.md │ │ │ ├── table_getIsSomePageRowsSelected.md │ │ │ ├── table_getIsSomeRowsExpanded.md │ │ │ ├── table_getIsSomeRowsPinned.md │ │ │ ├── table_getIsSomeRowsSelected.md │ │ │ ├── table_getLeafHeaders.md │ │ │ ├── table_getLeftFlatHeaders.md │ │ │ ├── table_getLeftFooterGroups.md │ │ │ ├── table_getLeftHeaderGroups.md │ │ │ ├── table_getLeftLeafColumns.md │ │ │ ├── table_getLeftLeafHeaders.md │ │ │ ├── table_getLeftTotalSize.md │ │ │ ├── table_getLeftVisibleLeafColumns.md │ │ │ ├── table_getOrderColumnsFn.md │ │ │ ├── table_getPageCount.md │ │ │ ├── table_getPageOptions.md │ │ │ ├── table_getPaginatedRowModel.md │ │ │ ├── table_getPinnedLeafColumns.md │ │ │ ├── table_getPinnedVisibleLeafColumns.md │ │ │ ├── table_getPreExpandedRowModel.md │ │ │ ├── table_getPreFilteredRowModel.md │ │ │ ├── table_getPreGroupedRowModel.md │ │ │ ├── table_getPrePaginatedRowModel.md │ │ │ ├── table_getPreSelectedRowModel.md │ │ │ ├── table_getPreSortedRowModel.md │ │ │ ├── table_getRightFlatHeaders.md │ │ │ ├── table_getRightFooterGroups.md │ │ │ ├── table_getRightHeaderGroups.md │ │ │ ├── table_getRightLeafColumns.md │ │ │ ├── table_getRightLeafHeaders.md │ │ │ ├── table_getRightTotalSize.md │ │ │ ├── table_getRightVisibleLeafColumns.md │ │ │ ├── table_getRow.md │ │ │ ├── table_getRowCount.md │ │ │ ├── table_getRowId.md │ │ │ ├── table_getRowModel.md │ │ │ ├── table_getSelectedRowModel.md │ │ │ ├── table_getSortedRowModel.md │ │ │ ├── table_getToggleAllColumnsVisibilityHandler.md │ │ │ ├── table_getToggleAllPageRowsSelectedHandler.md │ │ │ ├── table_getToggleAllRowsExpandedHandler.md │ │ │ ├── table_getToggleAllRowsSelectedHandler.md │ │ │ ├── table_getTopRows.md │ │ │ ├── table_getTotalSize.md │ │ │ ├── table_getVisibleFlatColumns.md │ │ │ ├── table_getVisibleLeafColumns.md │ │ │ ├── table_lastPage.md │ │ │ ├── table_mergeOptions.md │ │ │ ├── table_nextPage.md │ │ │ ├── table_previousPage.md │ │ │ ├── table_reset.md │ │ │ ├── table_resetColumnFilters.md │ │ │ ├── table_resetColumnOrder.md │ │ │ ├── table_resetColumnPinning.md │ │ │ ├── table_resetColumnSizing.md │ │ │ ├── table_resetColumnVisibility.md │ │ │ ├── table_resetExpanded.md │ │ │ ├── table_resetGlobalFilter.md │ │ │ ├── table_resetGrouping.md │ │ │ ├── table_resetHeaderSizeInfo.md │ │ │ ├── table_resetPageIndex.md │ │ │ ├── table_resetPageSize.md │ │ │ ├── table_resetPagination.md │ │ │ ├── table_resetRowPinning.md │ │ │ ├── table_resetRowSelection.md │ │ │ ├── table_resetSorting.md │ │ │ ├── table_setColumnFilters.md │ │ │ ├── table_setColumnOrder.md │ │ │ ├── table_setColumnPinning.md │ │ │ ├── table_setColumnResizing.md │ │ │ ├── table_setColumnSizing.md │ │ │ ├── table_setColumnVisibility.md │ │ │ ├── table_setExpanded.md │ │ │ ├── table_setGlobalFilter.md │ │ │ ├── table_setGrouping.md │ │ │ ├── table_setOptions.md │ │ │ ├── table_setPageIndex.md │ │ │ ├── table_setPageSize.md │ │ │ ├── table_setPagination.md │ │ │ ├── table_setRowPinning.md │ │ │ ├── table_setRowSelection.md │ │ │ ├── table_setSorting.md │ │ │ ├── table_toggleAllColumnsVisible.md │ │ │ ├── table_toggleAllPageRowsSelected.md │ │ │ ├── table_toggleAllRowsExpanded.md │ │ │ └── table_toggleAllRowsSelected.md │ │ ├── index.md │ │ ├── interfaces/ │ │ │ ├── API.md │ │ │ ├── AggregationFns.md │ │ │ ├── CachedRowModel_Core.md │ │ │ ├── CachedRowModel_Expanded.md │ │ │ ├── CachedRowModel_Faceted.md │ │ │ ├── CachedRowModel_Filtered.md │ │ │ ├── CachedRowModel_Grouped.md │ │ │ ├── CachedRowModel_Paginated.md │ │ │ ├── CachedRowModel_Plugins.md │ │ │ ├── CachedRowModel_Sorted.md │ │ │ ├── CachedRowModels_Plugins.md │ │ │ ├── CellContext.md │ │ │ ├── Cell_Cell.md │ │ │ ├── Cell_ColumnGrouping.md │ │ │ ├── Cell_Core.md │ │ │ ├── Cell_CoreProperties.md │ │ │ ├── Cell_Plugins.md │ │ │ ├── ColumnDef_ColumnFiltering.md │ │ │ ├── ColumnDef_ColumnGrouping.md │ │ │ ├── ColumnDef_ColumnPinning.md │ │ │ ├── ColumnDef_ColumnResizing.md │ │ │ ├── ColumnDef_ColumnSizing.md │ │ │ ├── ColumnDef_ColumnVisibility.md │ │ │ ├── ColumnDef_GlobalFiltering.md │ │ │ ├── ColumnDef_Plugins.md │ │ │ ├── ColumnDef_RowSorting.md │ │ │ ├── ColumnDefaultOptions.md │ │ │ ├── ColumnFilter.md │ │ │ ├── ColumnMeta.md │ │ │ ├── ColumnOrderDefaultOptions.md │ │ │ ├── ColumnPinningDefaultOptions.md │ │ │ ├── ColumnPinningState.md │ │ │ ├── ColumnSort.md │ │ │ ├── Column_Column.md │ │ │ ├── Column_ColumnFaceting.md │ │ │ ├── Column_ColumnFiltering.md │ │ │ ├── Column_ColumnGrouping.md │ │ │ ├── Column_ColumnOrdering.md │ │ │ ├── Column_ColumnPinning.md │ │ │ ├── Column_ColumnResizing.md │ │ │ ├── Column_ColumnSizing.md │ │ │ ├── Column_ColumnVisibility.md │ │ │ ├── Column_Core.md │ │ │ ├── Column_CoreProperties.md │ │ │ ├── Column_GlobalFiltering.md │ │ │ ├── Column_Plugins.md │ │ │ ├── Column_RowSorting.md │ │ │ ├── CoreFeatures.md │ │ │ ├── CreateRowModel_Core.md │ │ │ ├── CreateRowModel_Expanded.md │ │ │ ├── CreateRowModel_Faceted.md │ │ │ ├── CreateRowModel_Filtered.md │ │ │ ├── CreateRowModel_Grouped.md │ │ │ ├── CreateRowModel_Paginated.md │ │ │ ├── CreateRowModel_Plugins.md │ │ │ ├── CreateRowModel_Sorted.md │ │ │ ├── CreateRowModels_Plugins.md │ │ │ ├── FilterFn.md │ │ │ ├── FilterFns.md │ │ │ ├── FilterMeta.md │ │ │ ├── HeaderContext.md │ │ │ ├── HeaderGroup_Core.md │ │ │ ├── HeaderGroup_Header.md │ │ │ ├── HeaderGroup_Plugins.md │ │ │ ├── Header_ColumnResizing.md │ │ │ ├── Header_ColumnSizing.md │ │ │ ├── Header_Core.md │ │ │ ├── Header_CoreProperties.md │ │ │ ├── Header_Header.md │ │ │ ├── Header_Plugins.md │ │ │ ├── IdIdentifier.md │ │ │ ├── PaginationDefaultOptions.md │ │ │ ├── PaginationState.md │ │ │ ├── Plugins.md │ │ │ ├── PrototypeAPI.md │ │ │ ├── ResolvedColumnFilter.md │ │ │ ├── RowModel.md │ │ │ ├── RowModelFns_ColumnFiltering.md │ │ │ ├── RowModelFns_ColumnGrouping.md │ │ │ ├── RowModelFns_Core.md │ │ │ ├── RowModelFns_Plugins.md │ │ │ ├── RowModelFns_RowSorting.md │ │ │ ├── RowPinningDefaultOptions.md │ │ │ ├── RowPinningState.md │ │ │ ├── Row_ColumnFiltering.md │ │ │ ├── Row_ColumnGrouping.md │ │ │ ├── Row_ColumnPinning.md │ │ │ ├── Row_ColumnVisibility.md │ │ │ ├── Row_Core.md │ │ │ ├── Row_CoreProperties.md │ │ │ ├── Row_Plugins.md │ │ │ ├── Row_Row.md │ │ │ ├── Row_RowExpanding.md │ │ │ ├── Row_RowPinning.md │ │ │ ├── Row_RowSelection.md │ │ │ ├── SortFn.md │ │ │ ├── SortFns.md │ │ │ ├── StockFeatures.md │ │ │ ├── StringHeaderIdentifier.md │ │ │ ├── TableFeature.md │ │ │ ├── TableFeatures.md │ │ │ ├── TableMeta.md │ │ │ ├── TableOptions_Cell.md │ │ │ ├── TableOptions_ColumnFiltering.md │ │ │ ├── TableOptions_ColumnGrouping.md │ │ │ ├── TableOptions_ColumnOrdering.md │ │ │ ├── TableOptions_ColumnPinning.md │ │ │ ├── TableOptions_ColumnResizing.md │ │ │ ├── TableOptions_ColumnSizing.md │ │ │ ├── TableOptions_ColumnVisibility.md │ │ │ ├── TableOptions_Columns.md │ │ │ ├── TableOptions_Core.md │ │ │ ├── TableOptions_GlobalFiltering.md │ │ │ ├── TableOptions_Plugins.md │ │ │ ├── TableOptions_RowExpanding.md │ │ │ ├── TableOptions_RowPagination.md │ │ │ ├── TableOptions_RowPinning.md │ │ │ ├── TableOptions_RowSelection.md │ │ │ ├── TableOptions_RowSorting.md │ │ │ ├── TableOptions_Rows.md │ │ │ ├── TableOptions_Table.md │ │ │ ├── TableState_ColumnFiltering.md │ │ │ ├── TableState_ColumnGrouping.md │ │ │ ├── TableState_ColumnOrdering.md │ │ │ ├── TableState_ColumnPinning.md │ │ │ ├── TableState_ColumnResizing.md │ │ │ ├── TableState_ColumnSizing.md │ │ │ ├── TableState_ColumnVisibility.md │ │ │ ├── TableState_GlobalFiltering.md │ │ │ ├── TableState_Plugins.md │ │ │ ├── TableState_RowExpanding.md │ │ │ ├── TableState_RowPagination.md │ │ │ ├── TableState_RowPinning.md │ │ │ ├── TableState_RowSelection.md │ │ │ ├── TableState_RowSorting.md │ │ │ ├── Table_ColumnFaceting.md │ │ │ ├── Table_ColumnFiltering.md │ │ │ ├── Table_ColumnGrouping.md │ │ │ ├── Table_ColumnOrdering.md │ │ │ ├── Table_ColumnPinning.md │ │ │ ├── Table_ColumnResizing.md │ │ │ ├── Table_ColumnSizing.md │ │ │ ├── Table_ColumnVisibility.md │ │ │ ├── Table_Columns.md │ │ │ ├── Table_CoreProperties.md │ │ │ ├── Table_GlobalFiltering.md │ │ │ ├── Table_Headers.md │ │ │ ├── Table_Plugins.md │ │ │ ├── Table_RowExpanding.md │ │ │ ├── Table_RowModels_Core.md │ │ │ ├── Table_RowModels_Expanded.md │ │ │ ├── Table_RowModels_Faceted.md │ │ │ ├── Table_RowModels_Filtered.md │ │ │ ├── Table_RowModels_Grouped.md │ │ │ ├── Table_RowModels_Paginated.md │ │ │ ├── Table_RowModels_Sorted.md │ │ │ ├── Table_RowPagination.md │ │ │ ├── Table_RowPinning.md │ │ │ ├── Table_RowSelection.md │ │ │ ├── Table_RowSorting.md │ │ │ ├── Table_Rows.md │ │ │ ├── Table_Table.md │ │ │ └── columnResizingState.md │ │ ├── type-aliases/ │ │ │ ├── APIObject.md │ │ │ ├── AccessorColumnDef.md │ │ │ ├── AccessorFn.md │ │ │ ├── AccessorFnColumnDef.md │ │ │ ├── AccessorFnColumnDefBase.md │ │ │ ├── AccessorKeyColumnDef.md │ │ │ ├── AccessorKeyColumnDefBase.md │ │ │ ├── AggregationFn.md │ │ │ ├── AggregationFnOption.md │ │ │ ├── AssignCellPrototype.md │ │ │ ├── AssignColumnPrototype.md │ │ │ ├── AssignHeaderPrototype.md │ │ │ ├── AssignRowPrototype.md │ │ │ ├── BuiltInAggregationFn.md │ │ │ ├── BuiltInFilterFn.md │ │ │ ├── BuiltInSortFn.md │ │ │ ├── CachedRowModel_All.md │ │ │ ├── CachedRowModels.md │ │ │ ├── Cell.md │ │ │ ├── CellData.md │ │ │ ├── Column.md │ │ │ ├── ColumnDef.md │ │ │ ├── ColumnDefBase.md │ │ │ ├── ColumnDefBase_All.md │ │ │ ├── ColumnDefResolved.md │ │ │ ├── ColumnDefTemplate.md │ │ │ ├── ColumnFilterAutoRemoveTestFn.md │ │ │ ├── ColumnFiltersState.md │ │ │ ├── ColumnHelper.md │ │ │ ├── ColumnOrderState.md │ │ │ ├── ColumnPinningPosition.md │ │ │ ├── ColumnResizeDirection.md │ │ │ ├── ColumnResizeMode.md │ │ │ ├── ColumnResizingDefaultOptions.md │ │ │ ├── ColumnSizingDefaultOptions.md │ │ │ ├── ColumnSizingState.md │ │ │ ├── ColumnVisibilityState.md │ │ │ ├── Column_Internal.md │ │ │ ├── ConstructTableAPIs.md │ │ │ ├── CreateRowModels.md │ │ │ ├── CreateRowModels_All.md │ │ │ ├── CustomAggregationFns.md │ │ │ ├── CustomFilterFns.md │ │ │ ├── CustomSortFns.md │ │ │ ├── DebugOptions.md │ │ │ ├── DeepKeys.md │ │ │ ├── DeepValue.md │ │ │ ├── DisplayColumnDef.md │ │ │ ├── ExpandedState.md │ │ │ ├── ExpandedStateList.md │ │ │ ├── ExtractFeatureTypes.md │ │ │ ├── FilterFnOption.md │ │ │ ├── GetDefaultColumnDef.md │ │ │ ├── GetDefaultStateSelector.md │ │ │ ├── GetDefaultTableOptions.md │ │ │ ├── GetInitialState.md │ │ │ ├── Getter.md │ │ │ ├── GroupColumnDef.md │ │ │ ├── GroupingColumnMode.md │ │ │ ├── GroupingState.md │ │ │ ├── Header.md │ │ │ ├── HeaderGroup.md │ │ │ ├── IdentifiedColumnDef.md │ │ │ ├── InitRowInstanceData.md │ │ │ ├── MemoFnMeta.md │ │ │ ├── NoInfer.md │ │ │ ├── OnChangeFn.md │ │ │ ├── PartialKeys.md │ │ │ ├── Prettify.md │ │ │ ├── PrototypeAPIObject.md │ │ │ ├── RequiredKeys.md │ │ │ ├── Row.md │ │ │ ├── RowData.md │ │ │ ├── RowModelFns.md │ │ │ ├── RowModelFns_All.md │ │ │ ├── RowPinningPosition.md │ │ │ ├── RowSelectionState.md │ │ │ ├── SortDirection.md │ │ │ ├── SortFnOption.md │ │ │ ├── SortingState.md │ │ │ ├── StringOrTemplateHeader.md │ │ │ ├── Table.md │ │ │ ├── TableHelperOptions.md │ │ │ ├── TableHelper_Core.md │ │ │ ├── TableOptions.md │ │ │ ├── TableOptions_All.md │ │ │ ├── TableState.md │ │ │ ├── TableState_All.md │ │ │ ├── Table_Core.md │ │ │ ├── Table_Internal.md │ │ │ ├── Table_RowModels.md │ │ │ ├── TransformFilterValueFn.md │ │ │ ├── UnionToIntersection.md │ │ │ ├── Updater.md │ │ │ └── VisibilityDefaultOptions.md │ │ └── variables/ │ │ ├── $internalMemoFnMeta.md │ │ ├── aggregationFn_count.md │ │ ├── aggregationFn_extent.md │ │ ├── aggregationFn_max.md │ │ ├── aggregationFn_mean.md │ │ ├── aggregationFn_median.md │ │ ├── aggregationFn_min.md │ │ ├── aggregationFn_sum.md │ │ ├── aggregationFn_unique.md │ │ ├── aggregationFn_uniqueCount.md │ │ ├── aggregationFns.md │ │ ├── columnFacetingFeature.md │ │ ├── columnFilteringFeature.md │ │ ├── columnGroupingFeature.md │ │ ├── columnOrderingFeature.md │ │ ├── columnPinningFeature.md │ │ ├── columnResizingFeature.md │ │ ├── columnSizingFeature.md │ │ ├── columnVisibilityFeature.md │ │ ├── coreCellsFeature.md │ │ ├── coreColumnsFeature.md │ │ ├── coreFeatures.md │ │ ├── coreHeadersFeature.md │ │ ├── coreRowModelsFeature.md │ │ ├── coreRowsFeature.md │ │ ├── coreTablesFeature.md │ │ ├── filterFn_arrHas.md │ │ ├── filterFn_arrIncludes.md │ │ ├── filterFn_arrIncludesAll.md │ │ ├── filterFn_arrIncludesSome.md │ │ ├── filterFn_equals.md │ │ ├── filterFn_equalsString.md │ │ ├── filterFn_equalsStringSensitive.md │ │ ├── filterFn_greaterThan.md │ │ ├── filterFn_greaterThanOrEqualTo.md │ │ ├── filterFn_inNumberRange.md │ │ ├── filterFn_includesString.md │ │ ├── filterFn_includesStringSensitive.md │ │ ├── filterFn_lessThan.md │ │ ├── filterFn_lessThanOrEqualTo.md │ │ ├── filterFn_weakEquals.md │ │ ├── filterFns.md │ │ ├── globalFilteringFeature.md │ │ ├── reSplitAlphaNumeric.md │ │ ├── rowExpandingFeature.md │ │ ├── rowPaginationFeature.md │ │ ├── rowPinningFeature.md │ │ ├── rowSelectionFeature.md │ │ ├── rowSortingFeature.md │ │ ├── sortFn_alphanumeric.md │ │ ├── sortFn_alphanumericCaseSensitive.md │ │ ├── sortFn_basic.md │ │ ├── sortFn_datetime.md │ │ ├── sortFn_text.md │ │ ├── sortFn_textCaseSensitive.md │ │ ├── sortFns.md │ │ └── stockFeatures.md │ └── vanilla.md ├── eslint.config.js ├── examples/ │ ├── angular/ │ │ ├── basic/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.routes.ts │ │ │ │ │ └── app.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── basic-app-table/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ └── app.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── column-ordering/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── column-pinning/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── column-pinning-sticky/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── column-resizing-performant/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── makeData.ts │ │ │ │ │ └── resizable-cell/ │ │ │ │ │ └── resizable-cell.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── column-visibility/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ └── app.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── composable-tables/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── cell-components.ts │ │ │ │ │ │ ├── header-components.ts │ │ │ │ │ │ ├── products-table/ │ │ │ │ │ │ │ ├── products-table.html │ │ │ │ │ │ │ └── products-table.ts │ │ │ │ │ │ ├── table-components.ts │ │ │ │ │ │ └── users-table/ │ │ │ │ │ │ ├── users-table.html │ │ │ │ │ │ └── users-table.ts │ │ │ │ │ ├── makeData.ts │ │ │ │ │ └── table.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.spec.json │ │ ├── custom-plugin/ │ │ │ ├── .gitignore │ │ │ ├── .vscode/ │ │ │ │ ├── extensions.json │ │ │ │ ├── launch.json │ │ │ │ ├── mcp.json │ │ │ │ └── tasks.json │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.css │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── density/ │ │ │ │ │ │ └── density-feature.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── editable/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── editable-cell/ │ │ │ │ │ │ └── editable-cell.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── expanding/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── expandable-cell/ │ │ │ │ │ │ └── expandable-cell.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── filters/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── debounced-input/ │ │ │ │ │ │ └── debounced-input.ts │ │ │ │ │ ├── makeData.ts │ │ │ │ │ └── table-filter/ │ │ │ │ │ └── table-filter.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── grouping/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── columns.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── remote-data/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.server.ts │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.routes.server.ts │ │ │ │ │ └── app.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.server.ts │ │ │ │ ├── main.ts │ │ │ │ ├── server.ts │ │ │ │ └── styles.scss │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── row-dnd/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.css │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── drag-handle-cell/ │ │ │ │ │ │ └── drag-handle-cell.ts │ │ │ │ │ └── makeData.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── row-selection/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── makeData.ts │ │ │ │ │ ├── selection-column/ │ │ │ │ │ │ └── selection-column.ts │ │ │ │ │ ├── table-filter/ │ │ │ │ │ │ └── table-filter.ts │ │ │ │ │ └── table.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ ├── row-selection-signal/ │ │ │ ├── .devcontainer/ │ │ │ │ └── devcontainer.json │ │ │ ├── .editorconfig │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.component.html │ │ │ │ │ ├── app.component.ts │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── filter.ts │ │ │ │ │ ├── makeData.ts │ │ │ │ │ └── selection-column.component.ts │ │ │ │ ├── assets/ │ │ │ │ │ └── .gitkeep │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.scss │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.spec.json │ │ ├── signal-input/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── angular.json │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── app/ │ │ │ │ │ ├── app.config.ts │ │ │ │ │ ├── app.html │ │ │ │ │ ├── app.ts │ │ │ │ │ ├── makeData.ts │ │ │ │ │ └── person-table/ │ │ │ │ │ ├── person-table.html │ │ │ │ │ └── person-table.ts │ │ │ │ ├── index.html │ │ │ │ ├── main.ts │ │ │ │ └── styles.css │ │ │ ├── tsconfig.app.json │ │ │ └── tsconfig.json │ │ └── sub-components/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── angular.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app/ │ │ │ │ ├── app.config.ts │ │ │ │ ├── app.html │ │ │ │ ├── app.ts │ │ │ │ ├── expandable-cell.ts │ │ │ │ ├── makeData.ts │ │ │ │ └── sub-component/ │ │ │ │ └── sub-component.ts │ │ │ ├── index.html │ │ │ ├── main.ts │ │ │ └── styles.css │ │ ├── tsconfig.app.json │ │ └── tsconfig.json │ ├── lit/ │ │ ├── basic/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── main.ts │ │ │ ├── tsconfig.json │ │ │ ├── twind.config.ts │ │ │ └── vite.config.js │ │ ├── column-sizing/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ └── tsconfig.json │ │ ├── filters/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── row-selection/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── sorting/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── sorting-dynamic-data/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ └── virtualized-rows/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ ├── twind.config.ts │ │ └── vite.config.js │ ├── preact/ │ │ ├── basic/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ └── sorting/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── react/ │ │ ├── basic-external-state/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-external-store/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-shadcn/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── components.json │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── components/ │ │ │ │ │ └── ui/ │ │ │ │ │ ├── button.tsx │ │ │ │ │ └── table.tsx │ │ │ │ ├── index.css │ │ │ │ ├── lib/ │ │ │ │ │ └── utils.ts │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-use-app-table/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-use-legacy-table/ │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-use-table/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-dnd/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-groups/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-ordering/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-pinning/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-pinning-split/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-pinning-sticky/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-resizing/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-resizing-performant/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-sizing/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-visibility/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── composable-tables/ │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── components/ │ │ │ │ │ ├── cell-components.tsx │ │ │ │ │ ├── header-components.tsx │ │ │ │ │ └── table-components.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ └── table.ts │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── custom-plugin/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── expanding/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── filters/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── filters-faceted/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── filters-fuzzy/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── grouping/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── kitchen-sink-shadcn/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── components.json │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── components/ │ │ │ │ │ ├── data-table/ │ │ │ │ │ │ ├── data-table-filter-list.tsx │ │ │ │ │ │ ├── data-table-pagination.tsx │ │ │ │ │ │ ├── data-table-sort-list.tsx │ │ │ │ │ │ └── data-table-view-options.tsx │ │ │ │ │ └── ui/ │ │ │ │ │ ├── badge.tsx │ │ │ │ │ ├── button.tsx │ │ │ │ │ ├── calendar.tsx │ │ │ │ │ ├── checkbox.tsx │ │ │ │ │ ├── command.tsx │ │ │ │ │ ├── dialog.tsx │ │ │ │ │ ├── dropdown-menu.tsx │ │ │ │ │ ├── faceted.tsx │ │ │ │ │ ├── input.tsx │ │ │ │ │ ├── popover.tsx │ │ │ │ │ ├── progress.tsx │ │ │ │ │ ├── select.tsx │ │ │ │ │ ├── sortable.tsx │ │ │ │ │ ├── table.tsx │ │ │ │ │ └── tooltip.tsx │ │ │ │ ├── lib/ │ │ │ │ │ ├── composition.ts │ │ │ │ │ ├── data-table.ts │ │ │ │ │ ├── make-data.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── main.tsx │ │ │ │ ├── styles/ │ │ │ │ │ └── globals.css │ │ │ │ └── types/ │ │ │ │ └── index.ts │ │ │ ├── tailwind.config.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── pagination/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── row-dnd/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── row-pinning/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── row-selection/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── sorting/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── sub-components/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── virtualized-columns/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── virtualized-columns-experimental/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── virtualized-infinite-scrolling/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── virtualized-rows/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── virtualized-rows-experimental/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── with-tanstack-form/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── form.tsx │ │ │ │ ├── index.css │ │ │ │ ├── main.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── with-tanstack-query/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── fetchData.ts │ │ │ │ ├── index.css │ │ │ │ └── main.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ └── with-tanstack-router/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── api/ │ │ │ │ ├── data.json │ │ │ │ ├── types.ts │ │ │ │ └── user.ts │ │ │ ├── components/ │ │ │ │ ├── debouncedInput.tsx │ │ │ │ └── table.tsx │ │ │ ├── hooks/ │ │ │ │ └── useFilters.ts │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── routeTree.gen.ts │ │ │ ├── routes/ │ │ │ │ ├── __root.tsx │ │ │ │ ├── anotherRoute.tsx │ │ │ │ └── index.tsx │ │ │ └── utils/ │ │ │ ├── cleanEmptyParams.ts │ │ │ ├── tableSortMapper.ts │ │ │ └── userColumns.tsx │ │ ├── tsconfig.json │ │ └── vite.config.js │ ├── solid/ │ │ ├── basic-app-table/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── basic-external-state/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── basic-external-store/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── basic-use-table/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── column-groups/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── column-ordering/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── column-visibility/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── composable-tables/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── cell-components.tsx │ │ │ │ │ ├── header-components.tsx │ │ │ │ │ └── table-components.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ └── table.ts │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── filters/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── ColumnFilter.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── filters-faceted/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── ColumnFilter.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── row-selection/ │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ ├── sorting/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.ts │ │ └── with-tanstack-query/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── fetchData.ts │ │ │ ├── index.css │ │ │ └── index.tsx │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── svelte/ │ │ ├── basic/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── vite-env.d.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-snippets/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── snippets.svelte │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── basic-table-helper/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ └── main.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-groups/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ └── main.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-ordering/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-pinning/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── column-visibility/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ └── main.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── filtering/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── row-selection/ │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.svelte │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── svelte.config.js │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ └── sorting/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.svelte │ │ │ ├── Header.svelte │ │ │ ├── index.css │ │ │ ├── main.ts │ │ │ ├── makeData.ts │ │ │ ├── tableHelper.svelte.ts │ │ │ └── vite-env.d.ts │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.js │ ├── vanilla/ │ │ ├── basic/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── createTable.ts │ │ │ │ ├── index.css │ │ │ │ └── main.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ ├── pagination/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── createTable.ts │ │ │ │ ├── index.css │ │ │ │ ├── main.ts │ │ │ │ └── makeData.ts │ │ │ ├── tsconfig.json │ │ │ └── vite.config.js │ │ └── sorting/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── createTable.ts │ │ │ ├── index.css │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.js │ └── vue/ │ ├── basic/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ └── main.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── column-ordering/ │ │ ├── .gitignore │ │ ├── .vscode/ │ │ │ └── extensions.json │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── column-pinning/ │ │ ├── .gitignore │ │ ├── .vscode/ │ │ │ └── extensions.json │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── filters/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── DebouncedInput.vue │ │ │ ├── Filter.vue │ │ │ ├── main.ts │ │ │ └── tableHelper.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── pagination/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── pagination-controlled/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ ├── main.ts │ │ │ └── useService.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── row-selection/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── IndeterminateCheckbox.vue │ │ │ ├── env.d.ts │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── sorting/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ ├── env.d.ts │ │ │ ├── main.ts │ │ │ └── makeData.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── sub-components/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── env.d.ts │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── App.vue │ │ │ └── main.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ └── virtualized-rows/ │ ├── .gitignore │ ├── README.md │ ├── env.d.ts │ ├── index.html │ ├── package.json │ ├── src/ │ │ ├── App.vue │ │ ├── env.d.ts │ │ ├── index.css │ │ ├── main.ts │ │ └── makeData.ts │ ├── tsconfig.json │ └── vite.config.ts ├── knip.json ├── media/ │ └── logo.sketch ├── nx.json ├── package.json ├── packages/ │ ├── angular-table/ │ │ ├── eslint.config.js │ │ ├── ng-package.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── flex-render/ │ │ │ │ ├── context.ts │ │ │ │ ├── flags.ts │ │ │ │ ├── flexRenderComponent.ts │ │ │ │ ├── flexRenderComponentFactory.ts │ │ │ │ ├── renderer.ts │ │ │ │ └── view.ts │ │ │ ├── flexRender.ts │ │ │ ├── helpers/ │ │ │ │ ├── cell.ts │ │ │ │ ├── createTableHook.ts │ │ │ │ ├── flexRenderCell.ts │ │ │ │ ├── header.ts │ │ │ │ └── table.ts │ │ │ ├── index.ts │ │ │ ├── injectTable.ts │ │ │ └── lazySignalInitializer.ts │ │ ├── tests/ │ │ │ ├── angularReactivityFeature.test.ts │ │ │ ├── benchmarks/ │ │ │ │ ├── injectTable.benchmark.ts │ │ │ │ └── setup.ts │ │ │ ├── flex-render/ │ │ │ │ ├── flex-render-component.test-d.ts │ │ │ │ ├── flex-render-table.test.ts │ │ │ │ └── flex-render.unit.test.ts │ │ │ ├── injectTable.test.ts │ │ │ ├── lazy-init.test.ts │ │ │ ├── test-setup.ts │ │ │ └── test-utils.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ ├── tsconfig.test.json │ │ └── vite.config.ts │ ├── lit-table/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── TableController.ts │ │ │ ├── flexRender.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── match-sorter-utils/ │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ └── remove-accents.ts │ │ ├── tests/ │ │ │ ├── match-sorter-utils.test.ts │ │ │ └── test-setup.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── preact-table/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── FlexRender.tsx │ │ │ ├── Subscribe.ts │ │ │ ├── createTableHook.tsx │ │ │ ├── index.ts │ │ │ └── useTable.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── react-table/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── FlexRender.tsx │ │ │ ├── Subscribe.ts │ │ │ ├── createTableHook.tsx │ │ │ ├── index.ts │ │ │ ├── legacy.ts │ │ │ ├── useLegacyTable.ts │ │ │ └── useTable.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── react-table-devtools/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── ReactTableDevtools.tsx │ │ │ ├── index.ts │ │ │ ├── plugin.tsx │ │ │ └── production.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── solid-table/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── FlexRender.tsx │ │ │ ├── createTable.ts │ │ │ ├── createTableHook.tsx │ │ │ └── index.tsx │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── solid-table-devtools/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── TableDevtools.tsx │ │ │ ├── index.ts │ │ │ ├── plugin.tsx │ │ │ ├── production/ │ │ │ │ ├── TableDevtools.tsx │ │ │ │ └── plugin.tsx │ │ │ └── production.ts │ │ ├── tsconfig.build.json │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── svelte-table/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── FlexRender.svelte │ │ │ ├── Subscribe.svelte │ │ │ ├── createTable.svelte.ts │ │ │ ├── createTableHelper.ts │ │ │ ├── createTableState.svelte.ts │ │ │ ├── global.d.ts │ │ │ ├── index.ts │ │ │ └── render-component.ts │ │ ├── svelte.config.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── table-core/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── core/ │ │ │ │ ├── cells/ │ │ │ │ │ ├── constructCell.ts │ │ │ │ │ ├── coreCellsFeature.ts │ │ │ │ │ ├── coreCellsFeature.types.ts │ │ │ │ │ └── coreCellsFeature.utils.ts │ │ │ │ ├── columns/ │ │ │ │ │ ├── constructColumn.ts │ │ │ │ │ ├── coreColumnsFeature.ts │ │ │ │ │ ├── coreColumnsFeature.types.ts │ │ │ │ │ └── coreColumnsFeature.utils.ts │ │ │ │ ├── coreFeatures.ts │ │ │ │ ├── headers/ │ │ │ │ │ ├── buildHeaderGroups.ts │ │ │ │ │ ├── constructHeader.ts │ │ │ │ │ ├── coreHeadersFeature.ts │ │ │ │ │ ├── coreHeadersFeature.types.ts │ │ │ │ │ └── coreHeadersFeature.utils.ts │ │ │ │ ├── row-models/ │ │ │ │ │ ├── coreRowModelsFeature.ts │ │ │ │ │ ├── coreRowModelsFeature.types.ts │ │ │ │ │ ├── coreRowModelsFeature.utils.ts │ │ │ │ │ └── createCoreRowModel.ts │ │ │ │ ├── rows/ │ │ │ │ │ ├── constructRow.ts │ │ │ │ │ ├── coreRowsFeature.ts │ │ │ │ │ ├── coreRowsFeature.types.ts │ │ │ │ │ └── coreRowsFeature.utils.ts │ │ │ │ └── table/ │ │ │ │ ├── constructTable.ts │ │ │ │ ├── coreTablesFeature.ts │ │ │ │ ├── coreTablesFeature.types.ts │ │ │ │ └── coreTablesFeature.utils.ts │ │ │ ├── features/ │ │ │ │ ├── column-faceting/ │ │ │ │ │ ├── columnFacetingFeature.ts │ │ │ │ │ ├── columnFacetingFeature.types.ts │ │ │ │ │ ├── columnFacetingFeature.utils.ts │ │ │ │ │ ├── createFacetedMinMaxValues.ts │ │ │ │ │ ├── createFacetedRowModel.ts │ │ │ │ │ └── createFacetedUniqueValues.ts │ │ │ │ ├── column-filtering/ │ │ │ │ │ ├── columnFilteringFeature.ts │ │ │ │ │ ├── columnFilteringFeature.types.ts │ │ │ │ │ ├── columnFilteringFeature.utils.ts │ │ │ │ │ ├── createFilteredRowModel.ts │ │ │ │ │ └── filterRowsUtils.ts │ │ │ │ ├── column-grouping/ │ │ │ │ │ ├── columnGroupingFeature.ts │ │ │ │ │ ├── columnGroupingFeature.types.ts │ │ │ │ │ ├── columnGroupingFeature.utils.ts │ │ │ │ │ └── createGroupedRowModel.ts │ │ │ │ ├── column-ordering/ │ │ │ │ │ ├── columnOrderingFeature.ts │ │ │ │ │ ├── columnOrderingFeature.types.ts │ │ │ │ │ └── columnOrderingFeature.utils.ts │ │ │ │ ├── column-pinning/ │ │ │ │ │ ├── columnPinningFeature.ts │ │ │ │ │ ├── columnPinningFeature.types.ts │ │ │ │ │ └── columnPinningFeature.utils.ts │ │ │ │ ├── column-resizing/ │ │ │ │ │ ├── columnResizingFeature.ts │ │ │ │ │ ├── columnResizingFeature.types.ts │ │ │ │ │ └── columnResizingFeature.utils.ts │ │ │ │ ├── column-sizing/ │ │ │ │ │ ├── columnSizingFeature.ts │ │ │ │ │ ├── columnSizingFeature.types.ts │ │ │ │ │ └── columnSizingFeature.utils.ts │ │ │ │ ├── column-visibility/ │ │ │ │ │ ├── columnVisibilityFeature.ts │ │ │ │ │ ├── columnVisibilityFeature.types.ts │ │ │ │ │ └── columnVisibilityFeature.utils.ts │ │ │ │ ├── global-filtering/ │ │ │ │ │ ├── globalFilteringFeature.ts │ │ │ │ │ ├── globalFilteringFeature.types.ts │ │ │ │ │ └── globalFilteringFeature.utils.ts │ │ │ │ ├── row-expanding/ │ │ │ │ │ ├── createExpandedRowModel.ts │ │ │ │ │ ├── rowExpandingFeature.ts │ │ │ │ │ ├── rowExpandingFeature.types.ts │ │ │ │ │ └── rowExpandingFeature.utils.ts │ │ │ │ ├── row-pagination/ │ │ │ │ │ ├── createPaginatedRowModel.ts │ │ │ │ │ ├── rowPaginationFeature.ts │ │ │ │ │ ├── rowPaginationFeature.types.ts │ │ │ │ │ └── rowPaginationFeature.utils.ts │ │ │ │ ├── row-pinning/ │ │ │ │ │ ├── rowPinningFeature.ts │ │ │ │ │ ├── rowPinningFeature.types.ts │ │ │ │ │ └── rowPinningFeature.utils.ts │ │ │ │ ├── row-selection/ │ │ │ │ │ ├── rowSelectionFeature.ts │ │ │ │ │ ├── rowSelectionFeature.types.ts │ │ │ │ │ └── rowSelectionFeature.utils.ts │ │ │ │ ├── row-sorting/ │ │ │ │ │ ├── createSortedRowModel.ts │ │ │ │ │ ├── rowSortingFeature.ts │ │ │ │ │ ├── rowSortingFeature.types.ts │ │ │ │ │ └── rowSortingFeature.utils.ts │ │ │ │ ├── stockFeatures.ts │ │ │ │ └── table-reactivity/ │ │ │ │ └── tableReactivityFeature.ts │ │ │ ├── fns/ │ │ │ │ ├── aggregationFns.ts │ │ │ │ ├── filterFns.ts │ │ │ │ └── sortFns.ts │ │ │ ├── helpers/ │ │ │ │ ├── columnHelper.ts │ │ │ │ ├── tableFeatures.ts │ │ │ │ ├── tableHelper.ts │ │ │ │ └── tableOptions.ts │ │ │ ├── index.ts │ │ │ ├── types/ │ │ │ │ ├── Cell.ts │ │ │ │ ├── Column.ts │ │ │ │ ├── ColumnDef.ts │ │ │ │ ├── Header.ts │ │ │ │ ├── HeaderGroup.ts │ │ │ │ ├── Row.ts │ │ │ │ ├── RowModel.ts │ │ │ │ ├── RowModelFns.ts │ │ │ │ ├── Table.ts │ │ │ │ ├── TableFeatures.ts │ │ │ │ ├── TableOptions.ts │ │ │ │ ├── TableState.ts │ │ │ │ └── type-utils.ts │ │ │ └── utils.ts │ │ ├── tests/ │ │ │ ├── fixtures/ │ │ │ │ ├── data/ │ │ │ │ │ ├── generateTestColumnDefs.ts │ │ │ │ │ ├── generateTestData.ts │ │ │ │ │ └── types.ts │ │ │ │ └── setup/ │ │ │ │ └── test-setup.ts │ │ │ ├── helpers/ │ │ │ │ ├── generateTestRows.ts │ │ │ │ ├── generateTestTable.ts │ │ │ │ ├── rowPinningHelpers.ts │ │ │ │ └── testUtils.ts │ │ │ ├── implementation/ │ │ │ │ └── features/ │ │ │ │ ├── row-pinning/ │ │ │ │ │ └── rowPinningFeature.test.ts │ │ │ │ └── row-selection/ │ │ │ │ └── rowSelectionFeature.test.ts │ │ │ ├── performance/ │ │ │ │ └── features/ │ │ │ │ └── column-grouping/ │ │ │ │ └── columnGroupingFeature.test.ts │ │ │ └── unit/ │ │ │ ├── core/ │ │ │ │ ├── cells/ │ │ │ │ │ └── constructCell.test.ts │ │ │ │ ├── columns/ │ │ │ │ │ └── constructColumn.test.ts │ │ │ │ ├── headers/ │ │ │ │ │ └── constructHeader.test.ts │ │ │ │ ├── rows/ │ │ │ │ │ └── constructRow.test.ts │ │ │ │ └── table/ │ │ │ │ └── constructTable.test.ts │ │ │ ├── features/ │ │ │ │ ├── column-ordering/ │ │ │ │ │ └── columnOrderingFeature.utils.test.ts │ │ │ │ ├── column-pinning/ │ │ │ │ │ └── columnPinningFeature.utils.test.ts │ │ │ │ ├── column-resizing/ │ │ │ │ │ └── columnResizingFeature.utils.test.ts │ │ │ │ ├── column-visibility/ │ │ │ │ │ └── columnVisibilityFeature.utils.test.ts │ │ │ │ └── row-pinning/ │ │ │ │ └── rowPinningFeature.utils.test.ts │ │ │ ├── fns/ │ │ │ │ └── filterFns.test.ts │ │ │ └── utils.test.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── table-devtools/ │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── TableContextProvider.tsx │ │ │ ├── TableDevtools.tsx │ │ │ ├── components/ │ │ │ │ ├── ColumnsPanel.tsx │ │ │ │ ├── FeaturesPanel.tsx │ │ │ │ ├── OptionsPanel.tsx │ │ │ │ ├── ResizableSplit.tsx │ │ │ │ ├── RowsPanel.tsx │ │ │ │ ├── Shell.tsx │ │ │ │ └── StatePanel.tsx │ │ │ ├── core.tsx │ │ │ ├── index.ts │ │ │ ├── production.ts │ │ │ ├── styles/ │ │ │ │ ├── tokens.ts │ │ │ │ └── use-styles.ts │ │ │ ├── tableTarget.ts │ │ │ └── useTableStore.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ └── vue-table/ │ ├── eslint.config.js │ ├── package.json │ ├── src/ │ │ ├── FlexRender.ts │ │ ├── createTableHelper.ts │ │ ├── index.ts │ │ ├── merge-proxy.ts │ │ └── useTable.ts │ ├── tsconfig.json │ └── vite.config.ts ├── pnpm-workspace.yaml ├── prettier.config.js ├── scripts/ │ ├── config.js │ ├── generateDocs.js │ ├── publish.js │ ├── types.d.ts │ └── verify-links.ts ├── tsconfig.json └── vitest.workspace.mjs ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto eol=lf ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: tannerlinsley ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: '🐛 Bug report' description: Report a reproducible bug or regression body: - type: markdown attributes: value: | Thank you for reporting an issue :pray:. This issue tracker is for reporting reproducible bugs or regression's found in [react-table](https://github.com/tanstack/table) If you have a question about how to achieve or implement something and are struggling, please post a question inside of react-table's [Discussions tab](https://github.com/tanstack/table/discussions) instead of filing an issue. Before submitting a new bug/issue, please check the links below to see if there is a solution or question posted there already: - TanStack Table's [Discussions tab](https://github.com/tanstack/table/discussions) - TanStack Table's [Open Issues](https://github.com/tanstack/table/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) - TanStack Table's [Closed Issues](https://github.com/tanstack/table/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed) The more information you fill in, the better the community can help you. - type: input id: tanstack-table-version attributes: label: TanStack Table version description: | - Please let us know the exact version of the TanStack Table framework adapter that you were using when the issue occurred. If you are using an older version, check to see if your bug has already been solved in the latest version. Please don't just put in "latest", as this is subject to change. - The latest "table-core" version is placeholder: | e.g. v8.11.6 validations: required: true - type: input id: framework-library-version attributes: label: Framework/Library version description: Which framework and what version of that framework are you using? placeholder: | e.g. React v17.0.2 validations: required: true - type: textarea id: description attributes: label: Describe the bug and the steps to reproduce it description: Provide a clear and concise description of the challenge you are running into, and the steps we should take to try to reproduce your bug. validations: required: true - type: input id: link attributes: label: Your Minimal, Reproducible Example - (Sandbox Highly Recommended) description: | Please add a link to a minimal reproduction. Note: - Your bug may get fixed much faster if we can run your code and it doesn't have dependencies other than React. - To create a shareable code example for web, you can use CodeSandbox (https://codesandbox.io/s/new) or Stackblitz (https://stackblitz.com/). - Please make sure the example is complete and runnable without prior dependencies and free of unnecessary abstractions - Feel free to fork any of the official CodeSandbox examples to reproduce your issue: https://github.com/tanstack/table/tree/main/examples/ - For React Native, you can use: https://snack.expo.dev/ - For TypeScript related issues only, a TypeScript Playground link might be sufficient: https://www.typescriptlang.org/play - Please read these tips for providing a minimal example: https://stackoverflow.com/help/mcve. placeholder: | e.g. Code Sandbox, Stackblitz, TypeScript Playground, etc. validations: required: true - type: textarea id: screenshots_or_videos attributes: label: Screenshots or Videos (Optional) description: | If applicable, add screenshots or a video to help explain your problem. For more information on the supported file image/file types and the file size limits, please refer to the following link: https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/attaching-files placeholder: | You can drag your video or image files inside of this editor ↓ - type: dropdown attributes: options: - No, because I do not know how - No, because I do not have time to dig into it - Maybe, I'll investigate and start debugging - Yes, I think I know how to fix it and will discuss it in the comments of this issue - Yes, I am also opening a PR that solves the problem along side this issue label: Do you intend to try to help solve this bug with your own PR? description: | If you think you know the cause of the problem, the fastest way to get it fixed is to suggest a fix, or fix it yourself! However, it is ok if you cannot solve this yourself and are just wanting help. - type: checkboxes id: agrees-to-terms attributes: label: Terms & Code of Conduct description: By submitting this issue, you agree to follow our Code of Conduct and can verify that you have followed the requirements outlined above to the best of your ability. options: - label: I agree to follow this project's Code of Conduct required: true - label: I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed. required: true ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: 🤔 Feature Requests & Questions url: https://github.com/TanStack/table/discussions about: Please ask and answer questions here. - name: 💬 Community Chat url: https://discord.gg/mQd7egN about: A dedicated discord server hosted by TanStack - name: 🦋 TanStack Bluesky url: https://bsky.app/profile/tanstack.com about: Stay up to date with new releases of our libraries ================================================ FILE: .github/pull_request_template ================================================ ## 🎯 Changes ## ✅ Checklist - [ ] I have followed the steps in the [Contributing guide](https://github.com/TanStack/table/blob/main/CONTRIBUTING.md). - [ ] I have tested this code locally with `pnpm test:pr`. ================================================ FILE: .github/workflows/autofix.yml ================================================ name: autofix.ci # needed to securely identify the workflow on: pull_request: push: branches: [main, alpha, beta, rc] concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.ref }} cancel-in-progress: true permissions: contents: read jobs: autofix: name: autofix runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6.0.1 with: fetch-depth: 0 - name: Setup Tools uses: tanstack/config/.github/setup@main - name: Fix formatting run: pnpm format - name: Apply fixes uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a with: commit-message: 'ci: apply automated fixes' ================================================ FILE: .github/workflows/pr.yml ================================================ name: PR on: pull_request: paths-ignore: - 'docs/**' - 'media/**' - '**/*.md' concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.ref }} cancel-in-progress: true env: NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} permissions: contents: read jobs: test: name: Test runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6.0.1 with: fetch-depth: 0 - name: Start Nx Agents run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/dynamic-changesets.yaml" - name: Setup Tools uses: tanstack/config/.github/setup@main - name: Get base and head commits for `nx affected` uses: nrwl/nx-set-shas@v4.4.0 with: main-branch-name: main - name: Run Checks run: pnpm run test:pr --parallel=3 - name: Stop Nx Agents if: ${{ always() }} run: npx nx-cloud stop-all-agents preview: name: Preview runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6.0.1 with: fetch-depth: 0 - name: Setup Tools uses: tanstack/config/.github/setup@main - name: Build Packages run: pnpm run build:all - name: Publish Previews run: pnpx pkg-pr-new publish --pnpm --compact './packages/*' --template './examples/*/*' ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: workflow_dispatch: inputs: tag: description: override release tag required: false push: branches: [main, alpha, beta, rc] concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.ref }} cancel-in-progress: true env: NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} permissions: contents: write id-token: write jobs: release: name: Release if: github.repository_owner == 'TanStack' runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6.0.1 with: fetch-depth: 0 - name: Start Nx Agents run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/dynamic-changesets.yaml" - name: Setup Tools uses: tanstack/config/.github/setup@main - name: Run Tests run: pnpm run test:ci --parallel=3 - name: Stop Nx Agents if: ${{ always() }} run: npx nx-cloud stop-all-agents - name: Publish run: | git config --global user.name 'Tanner Linsley' git config --global user.email 'tannerlinsley@users.noreply.github.com' pnpm run cipublish env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ inputs.tag }} ================================================ FILE: .gitignore ================================================ # See https://help.github.com/ignore-files/ for more about ignoring files. # dependencies node_modules package-lock.json yarn.lock # builds build dist lib es artifacts .rpt2_cache coverage *.tgz # misc .DS_Store .env .env.local .env.development.local .env.test.local .env.production.local .next .svelte-kit npm-debug.log* yarn-debug.log* yarn-error.log* .history size-plugin.json stats-hydration.json stats-react.json stats.html .vscode/settings.json .idea *.log .DS_Store .cache .idea .pnpm-store package-lock.json yarn.lock *.tsbuildinfo *.tsbuildinfo .svelte-kit .nx/cache .nx/workspace-data vite.config.js.timestamp-* vite.config.ts.timestamp-* .angular ================================================ FILE: .npmrc ================================================ provenance=true ================================================ FILE: .nvmrc ================================================ 24.8.0 ================================================ FILE: .nx/workflows/dynamic-changesets.yaml ================================================ distribute-on: small-changeset: 3 linux-medium-js medium-changeset: 6 linux-medium-js large-changeset: 10 linux-medium-js ================================================ FILE: .prettierignore ================================================ **/.nx/ **/.nx/cache **/.svelte-kit **/build **/coverage **/dist **/docs **/old-examples **/examples/**/*.svelte pnpm-lock.yaml .angular ================================================ FILE: .vscode/extensions.json ================================================ { "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] } ================================================ FILE: CODE_OF_CONDUCT.md ================================================ --- title: Code of Conduct id: code-of-conduct --- # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at TANNERLINSLEY@GMAIL.COM. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq ================================================ FILE: CONTRIBUTING.md ================================================ --- title: Contributing id: contributing --- # Contributing ## Questions If you have questions about implementation details, help or support, then please use our dedicated community forum at [Github Discussions](https://github.com/tanstack/table/discussions) **PLEASE NOTE:** If you choose to instead open an issue for your question, your issue will be immediately closed and redirected to the forum. ## Reporting Issues If you have found what you think is a bug, please [file an issue](https://github.com/tanstack/table/issues/new). **PLEASE NOTE:** Issues that are identified as implementation questions or non-issues will be immediately closed and redirected to [Github Discussions](https://github.com/tanstack/table/discussions) ## Suggesting new features If you are here to suggest a feature, first create an issue if it does not already exist. From there, we will discuss use-cases for the feature and then finally discuss how it could be implemented. ## Development Before proceeding with development, ensure you match one of the following criteria: - Fixing a small bug - Fixing a larger issue that has been previously discussed and agreed-upon by maintainers - Adding a new feature that has been previously discussed and agreed-upon by maintainers ## Development Workflow - Fork this repository, we prefer the `feat-*` branch name style - Ensure you have `pnpm` installed - Install projects dependencies and linkages by running `pnpm install` - Auto-build and auto-test files as you edit by running `pnpm dev` - Implement your changes and tests - To run examples, follow their individual directions. Usually this includes: - cd into the example directory - Do NOT install dependencies again or do any linking. Nx already handles this for you. Only run install from the project root. - Starting the dev server with `pnpm dev` or `pnpm start` (from the example directory) - To test in your own projects: - Build/watch for changes with `pnpm build`/`pnpm dev` - Document your changes in the appropriate documentation website markdown pages - Commit your work and open a pull request - Submit PR for review ## Adding a new example - Clone an existing example into the appropriate `examples` directory - Name it the example name in kebab-case - Update the new example's package.json to match the new example name and any other details - Check dependencies for unused packages - Install any additional packages to the example that you may need - Update the docs/config.json file to include the new example in the navigation sidebar - Commit the example eg. `docs: Add example-name` ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2016 Tanner Linsley Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================
TanStack Table

npm downloads github stars bundle size
semantic-release Best of JS Follow @TanStack
### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) # TanStack Table > [!NOTE] > You may know TanStack Table by the adapter names: > > - [Angular Table](https://tanstack.com/table/alpha/docs/framework/angular/angular-table) > - [Lit Table](https://tanstack.com/table/alpha/docs/framework/lit/lit-table) > - [React Table](https://tanstack.com/table/alpha/docs/framework/react/react-table) > - [Solid Table](https://tanstack.com/table/alpha/docs/framework/solid/solid-table) > - [Svelte Table](https://tanstack.com/table/alpha/docs/framework/svelte/svelte-table) > - [Vue Table](https://tanstack.com/table/alpha/docs/framework/vue/vue-table) A headless table library for building powerful datagrids with full control over markup, styles, and behavior. - Framework‑agnostic core with bindings for React, Vue & Solid - 100% customizable — bring your own UI, components, and styles - Sorting, filtering, grouping, aggregation & row selection - Lightweight, virtualizable & server‑side friendly ### Read the Docs → ## Get Involved - We welcome issues and pull requests! - Participate in [GitHub discussions](https://github.com/TanStack/table/discussions) - Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ) - See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions ## Partners
CodeRabbit Cloudflare AG Grid
Table & you?

We're looking for TanStack Table Partners to join our mission! Partner with us to push the boundaries of TanStack Table and build amazing things together.

LET'S CHAT
## Explore the TanStack Ecosystem - TanStack Config – Tooling for JS/TS packages - TanStack DB – Reactive sync client store - TanStack DevTools – Unified devtools panel - TanStack Form – Type‑safe form state - TanStack Pacer – Debouncing, throttling, batching
- TanStack Query – Async state & caching - TanStack Ranger – Range & slider primitives - TanStack Router – Type‑safe routing, caching & URL state - TanStack Start – Full‑stack SSR & streaming - TanStack Store – Reactive data store - TanStack Virtual – Virtualized rendering … and more at TanStack.com » ================================================ FILE: docs/config.json ================================================ { "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", "docSearch": { "appId": "74SF5EKVW9", "apiKey": "9fc015a3310be6669ed66c6c459f319f", "indexName": "tanstack-table" }, "sections": [ { "label": "Getting Started", "children": [ { "label": "Introduction", "to": "introduction" }, { "label": "Overview", "to": "overview" }, { "label": "Installation", "to": "installation" }, { "label": "FAQ", "to": "faq" } ], "frameworks": [ { "label": "angular", "children": [ { "label": "Angular Table Adapter", "to": "framework/angular/angular-table" }, { "label": "Migrating to V9", "to": "framework/angular/guide/migrating" }, { "label": "Rendering components", "to": "framework/angular/guide/rendering" }, { "label": "Table composition", "to": "framework/angular/guide/table-composition" } ] }, { "label": "lit", "children": [ { "label": "Lit Table Adapter", "to": "framework/lit/lit-table" } ] }, { "label": "react", "children": [ { "label": "React Table Adapter", "to": "framework/react/react-table" }, { "label": "createTableHook Guide", "to": "framework/react/guide/create-table-hook" }, { "label": "Migrating to V9", "to": "framework/react/guide/migrating" }, { "label": "useLegacyTable Guide", "to": "framework/react/guide/use-legacy-table" } ] }, { "label": "preact", "children": [ { "label": "createTableHook Guide", "to": "framework/preact/guide/create-table-hook" } ] }, { "label": "solid", "children": [ { "label": "Solid Table Adapter", "to": "framework/solid/solid-table" } ] }, { "label": "svelte", "children": [ { "label": "Svelte Table Adapter", "to": "framework/svelte/svelte-table" } ] }, { "label": "vue", "children": [ { "label": "Vue Table Adapter", "to": "framework/vue/vue-table" } ] }, { "label": "vanilla", "children": [ { "label": "Vanilla JS (No Framework)", "to": "vanilla" } ] } ] }, { "label": "Core Guides", "children": [ { "label": "Data", "to": "guide/data" }, { "label": "Column Defs", "to": "guide/column-defs" }, { "label": "Table Instance", "to": "guide/tables" }, { "label": "Row Models", "to": "guide/row-models" }, { "label": "Rows", "to": "guide/rows" }, { "label": "Cells", "to": "guide/cells" }, { "label": "Header Groups", "to": "guide/header-groups" }, { "label": "Headers", "to": "guide/headers" }, { "label": "Columns", "to": "guide/columns" } ], "frameworks": [ { "label": "angular", "children": [ { "label": "Table State", "to": "framework/angular/guide/table-state" } ] }, { "label": "lit", "children": [ { "label": "Table State", "to": "framework/lit/guide/table-state" } ] }, { "label": "react", "children": [ { "label": "Table State", "to": "framework/react/guide/table-state" } ] }, { "label": "solid", "children": [ { "label": "Table State", "to": "framework/solid/guide/table-state" } ] }, { "label": "svelte", "children": [ { "label": "Table State", "to": "framework/svelte/guide/table-state" } ] }, { "label": "vue", "children": [ { "label": "Table State", "to": "framework/vue/guide/table-state" } ] }, { "label": "vanilla", "children": [ { "label": "Table State", "to": "framework/vanilla/guide/table-state" } ] } ] }, { "label": "Feature Guides", "children": [ { "label": "Column Ordering", "to": "guide/column-ordering" }, { "label": "Column Pinning", "to": "guide/column-pinning" }, { "label": "Column Sizing", "to": "guide/column-sizing" }, { "label": "Column Visibility", "to": "guide/column-visibility" }, { "label": "Column Filtering", "to": "guide/column-filtering" }, { "label": "Global Filtering", "to": "guide/global-filtering" }, { "label": "Fuzzy Filtering", "to": "guide/fuzzy-filtering" }, { "label": "Column Faceting", "to": "guide/column-faceting" }, { "label": "Global Faceting", "to": "guide/global-faceting" }, { "label": "Grouping", "to": "guide/grouping" }, { "label": "Expanding", "to": "guide/expanding" }, { "label": "Pagination", "to": "guide/pagination" }, { "label": "Row Pinning", "to": "guide/row-pinning" }, { "label": "Row Selection", "to": "guide/row-selection" }, { "label": "Sorting", "to": "guide/sorting" }, { "label": "Virtualization", "to": "guide/virtualization" }, { "label": "Custom Features", "to": "guide/custom-features" } ] }, { "label": "API Reference", "children": [ { "label": "Core API Reference", "to": "reference/index" } ], "frameworks": [ { "label": "angular", "children": [ { "label": "Angular API Reference", "to": "framework/angular/reference/index" } ] }, { "label": "react", "children": [ { "label": "React API Reference", "to": "framework/react/reference/index" } ] } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Table API Reference", "children": [ { "label": "Table", "to": "reference/type-aliases/Table" }, { "label": "Table_Core", "to": "reference/type-aliases/Table_Core" }, { "label": "Table_CoreProperties", "to": "reference/interfaces/Table_CoreProperties" }, { "label": "Table_Table", "to": "reference/interfaces/Table_Table" }, { "label": "Table_Columns", "to": "reference/interfaces/Table_Columns" }, { "label": "Table_Rows", "to": "reference/interfaces/Table_Rows" }, { "label": "Table_Headers", "to": "reference/interfaces/Table_Headers" }, { "label": "Table_Plugins", "to": "reference/interfaces/Table_Plugins" }, { "label": "TableOptions", "to": "reference/type-aliases/TableOptions" }, { "label": "TableOptions_All", "to": "reference/type-aliases/TableOptions_All" }, { "label": "TableOptions_Core", "to": "reference/interfaces/TableOptions_Core" }, { "label": "TableOptions_Table", "to": "reference/interfaces/TableOptions_Table" }, { "label": "TableOptions_Columns", "to": "reference/interfaces/TableOptions_Columns" }, { "label": "TableOptions_Rows", "to": "reference/interfaces/TableOptions_Rows" }, { "label": "TableOptions_Cell", "to": "reference/interfaces/TableOptions_Cell" }, { "label": "TableOptions_Plugins", "to": "reference/interfaces/TableOptions_Plugins" }, { "label": "TableState", "to": "reference/type-aliases/TableState" }, { "label": "TableState_All", "to": "reference/type-aliases/TableState_All" }, { "label": "TableState_Plugins", "to": "reference/interfaces/TableState_Plugins" }, { "label": "TableMeta", "to": "reference/interfaces/TableMeta" }, { "label": "TableFeature", "to": "reference/interfaces/TableFeature" }, { "label": "TableFeatures", "to": "reference/interfaces/TableFeatures" }, { "label": "StockFeatures", "to": "reference/interfaces/StockFeatures" }, { "label": "CoreFeatures", "to": "reference/interfaces/CoreFeatures" }, { "label": "constructTable", "to": "reference/functions/constructTable" }, { "label": "constructTableHelper", "to": "reference/functions/constructTableHelper" }, { "label": "createTableStore", "to": "reference/functions/createTableStore" }, { "label": "tableOptions", "to": "reference/functions/tableOptions" }, { "label": "tableFeatures", "to": "reference/functions/tableFeatures" }, { "label": "getInitialTableState", "to": "reference/functions/getInitialTableState" }, { "label": "table_setOptions", "to": "reference/functions/table_setOptions" }, { "label": "table_mergeOptions", "to": "reference/functions/table_mergeOptions" }, { "label": "table_reset", "to": "reference/functions/table_reset" }, { "label": "table_getRowModel", "to": "reference/functions/table_getRowModel" }, { "label": "table_getRow", "to": "reference/functions/table_getRow" }, { "label": "table_getRowCount", "to": "reference/functions/table_getRowCount" }, { "label": "table_getRowId", "to": "reference/functions/table_getRowId" }, { "label": "TableHelperOptions", "to": "reference/type-aliases/TableHelperOptions" }, { "label": "TableHelper_Core", "to": "reference/type-aliases/TableHelper_Core" }, { "label": "OnChangeFn", "to": "reference/type-aliases/OnChangeFn" }, { "label": "Updater", "to": "reference/type-aliases/Updater" }, { "label": "DebugOptions", "to": "reference/type-aliases/DebugOptions" } ], "frameworks": [ { "label": "react", "children": [ { "label": "useTable", "to": "framework/react/reference/index/functions/useTable" }, { "label": "createTableHook", "to": "framework/react/reference/index/functions/createTableHook" }, { "label": "ReactTable", "to": "framework/react/reference/index/type-aliases/ReactTable" }, { "label": "AppReactTable", "to": "framework/react/reference/index/type-aliases/AppReactTable" }, { "label": "CreateTableHookOptions", "to": "framework/react/reference/index/type-aliases/CreateTableHookOptions" }, { "label": "Subscribe", "to": "framework/react/reference/index/functions/Subscribe" }, { "label": "SubscribeProps", "to": "framework/react/reference/index/type-aliases/SubscribeProps" }, { "label": "FlexRender", "to": "framework/react/reference/index/functions/FlexRender-1" }, { "label": "flexRender", "to": "framework/react/reference/index/functions/flexRender" }, { "label": "FlexRenderProps", "to": "framework/react/reference/index/type-aliases/FlexRenderProps" }, { "label": "Renderable", "to": "framework/react/reference/index/type-aliases/Renderable" }, { "label": "AppTableComponent", "to": "framework/react/reference/index/interfaces/AppTableComponent" }, { "label": "AppTablePropsWithSelector", "to": "framework/react/reference/index/interfaces/AppTablePropsWithSelector" }, { "label": "AppTablePropsWithoutSelector", "to": "framework/react/reference/index/interfaces/AppTablePropsWithoutSelector" } ] }, { "label": "angular", "children": [ { "label": "injectTable", "to": "framework/angular/reference/functions/injectTable" }, { "label": "createTableHook", "to": "framework/angular/reference/functions/createTableHook" }, { "label": "AngularTable", "to": "framework/angular/reference/type-aliases/AngularTable" }, { "label": "AppAngularTable", "to": "framework/angular/reference/type-aliases/AppAngularTable" }, { "label": "CreateTableHookResult", "to": "framework/angular/reference/type-aliases/CreateTableHookResult" }, { "label": "CreateTableContextOptions", "to": "framework/angular/reference/type-aliases/CreateTableContextOptions" }, { "label": "flexRenderComponent", "to": "framework/angular/reference/functions/flexRenderComponent" }, { "label": "FlexRenderComponent", "to": "framework/angular/reference/interfaces/FlexRenderComponent" }, { "label": "FlexRenderContent", "to": "framework/angular/reference/type-aliases/FlexRenderContent" }, { "label": "FlexRenderInputContent", "to": "framework/angular/reference/type-aliases/FlexRenderInputContent" }, { "label": "FlexRenderComponentProps", "to": "framework/angular/reference/type-aliases/FlexRenderComponentProps" }, { "label": "FlexRender", "to": "framework/angular/reference/variables/FlexRender" }, { "label": "FlexRenderDirective", "to": "framework/angular/reference/classes/FlexRenderDirective" }, { "label": "FlexRenderCell", "to": "framework/angular/reference/classes/FlexRenderCell" }, { "label": "TanStackTable", "to": "framework/angular/reference/classes/TanStackTable" }, { "label": "TanStackTableToken", "to": "framework/angular/reference/variables/TanStackTableToken" }, { "label": "injectTableContext", "to": "framework/angular/reference/functions/injectTableContext" }, { "label": "AngularReactivityFlags", "to": "framework/angular/reference/interfaces/AngularReactivityFlags" } ] } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Column API Reference", "children": [ { "label": "Column", "to": "reference/type-aliases/Column" }, { "label": "Column_Core", "to": "reference/interfaces/Column_Core" }, { "label": "Column_CoreProperties", "to": "reference/interfaces/Column_CoreProperties" }, { "label": "Column_Column", "to": "reference/interfaces/Column_Column" }, { "label": "Column_Plugins", "to": "reference/interfaces/Column_Plugins" }, { "label": "ColumnDef", "to": "reference/type-aliases/ColumnDef" }, { "label": "ColumnDefBase", "to": "reference/type-aliases/ColumnDefBase" }, { "label": "AccessorColumnDef", "to": "reference/type-aliases/AccessorColumnDef" }, { "label": "DisplayColumnDef", "to": "reference/type-aliases/DisplayColumnDef" }, { "label": "GroupColumnDef", "to": "reference/type-aliases/GroupColumnDef" }, { "label": "ColumnDefTemplate", "to": "reference/type-aliases/ColumnDefTemplate" }, { "label": "ColumnHelper", "to": "reference/type-aliases/ColumnHelper" }, { "label": "ColumnDefaultOptions", "to": "reference/interfaces/ColumnDefaultOptions" }, { "label": "ColumnMeta", "to": "reference/interfaces/ColumnMeta" }, { "label": "createColumnHelper", "to": "reference/functions/createColumnHelper" }, { "label": "constructColumn", "to": "reference/functions/constructColumn" }, { "label": "column_getFlatColumns", "to": "reference/functions/column_getFlatColumns" }, { "label": "column_getLeafColumns", "to": "reference/functions/column_getLeafColumns" }, { "label": "column_getIndex", "to": "reference/functions/column_getIndex" }, { "label": "column_getIsFirstColumn", "to": "reference/functions/column_getIsFirstColumn" }, { "label": "column_getIsLastColumn", "to": "reference/functions/column_getIsLastColumn" }, { "label": "column_getSize", "to": "reference/functions/column_getSize" }, { "label": "column_getStart", "to": "reference/functions/column_getStart" }, { "label": "column_getAfter", "to": "reference/functions/column_getAfter" }, { "label": "AccessorFn", "to": "reference/type-aliases/AccessorFn" }, { "label": "DeepKeys", "to": "reference/type-aliases/DeepKeys" }, { "label": "DeepValue", "to": "reference/type-aliases/DeepValue" } ], "frameworks": [ { "label": "react", "children": [ { "label": "AppColumnHelper", "to": "framework/react/reference/index/type-aliases/AppColumnHelper" } ] }, { "label": "angular", "children": [ { "label": "AppColumnHelper", "to": "framework/angular/reference/type-aliases/AppColumnHelper" } ] } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Row API Reference", "children": [ { "label": "Row", "to": "reference/type-aliases/Row" }, { "label": "Row_Core", "to": "reference/interfaces/Row_Core" }, { "label": "Row_CoreProperties", "to": "reference/interfaces/Row_CoreProperties" }, { "label": "Row_Row", "to": "reference/interfaces/Row_Row" }, { "label": "Row_Plugins", "to": "reference/interfaces/Row_Plugins" }, { "label": "RowData", "to": "reference/type-aliases/RowData" }, { "label": "RowModel", "to": "reference/interfaces/RowModel" }, { "label": "constructRow", "to": "reference/functions/constructRow" }, { "label": "row_getValue", "to": "reference/functions/row_getValue" }, { "label": "row_getUniqueValues", "to": "reference/functions/row_getUniqueValues" }, { "label": "row_renderValue", "to": "reference/functions/row_renderValue" }, { "label": "row_getAllCells", "to": "reference/functions/row_getAllCells" }, { "label": "row_getAllCellsByColumnId", "to": "reference/functions/row_getAllCellsByColumnId" }, { "label": "row_getVisibleCells", "to": "reference/functions/row_getVisibleCells" }, { "label": "row_getLeftVisibleCells", "to": "reference/functions/row_getLeftVisibleCells" }, { "label": "row_getCenterVisibleCells", "to": "reference/functions/row_getCenterVisibleCells" }, { "label": "row_getRightVisibleCells", "to": "reference/functions/row_getRightVisibleCells" }, { "label": "row_getAllVisibleCells", "to": "reference/functions/row_getAllVisibleCells" }, { "label": "row_getLeafRows", "to": "reference/functions/row_getLeafRows" }, { "label": "row_getParentRow", "to": "reference/functions/row_getParentRow" }, { "label": "row_getParentRows", "to": "reference/functions/row_getParentRows" }, { "label": "RowModelFns", "to": "reference/type-aliases/RowModelFns" }, { "label": "RowModelFns_Core", "to": "reference/interfaces/RowModelFns_Core" }, { "label": "RowModelFns_Plugins", "to": "reference/interfaces/RowModelFns_Plugins" }, { "label": "createCoreRowModel", "to": "reference/functions/createCoreRowModel" }, { "label": "createFilteredRowModel", "to": "reference/functions/createFilteredRowModel" }, { "label": "createSortedRowModel", "to": "reference/functions/createSortedRowModel" }, { "label": "createGroupedRowModel", "to": "reference/functions/createGroupedRowModel" }, { "label": "createExpandedRowModel", "to": "reference/functions/createExpandedRowModel" }, { "label": "createPaginatedRowModel", "to": "reference/functions/createPaginatedRowModel" }, { "label": "createFacetedRowModel", "to": "reference/functions/createFacetedRowModel" }, { "label": "createFacetedMinMaxValues", "to": "reference/functions/createFacetedMinMaxValues" }, { "label": "createFacetedUniqueValues", "to": "reference/functions/createFacetedUniqueValues" }, { "label": "Table_RowModels_Core", "to": "reference/interfaces/Table_RowModels_Core" }, { "label": "Table_RowModels_Filtered", "to": "reference/interfaces/Table_RowModels_Filtered" }, { "label": "Table_RowModels_Sorted", "to": "reference/interfaces/Table_RowModels_Sorted" }, { "label": "Table_RowModels_Grouped", "to": "reference/interfaces/Table_RowModels_Grouped" }, { "label": "Table_RowModels_Expanded", "to": "reference/interfaces/Table_RowModels_Expanded" }, { "label": "Table_RowModels_Paginated", "to": "reference/interfaces/Table_RowModels_Paginated" }, { "label": "Table_RowModels_Faceted", "to": "reference/interfaces/Table_RowModels_Faceted" } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Cell API Reference", "children": [ { "label": "Cell", "to": "reference/type-aliases/Cell" }, { "label": "Cell_Core", "to": "reference/interfaces/Cell_Core" }, { "label": "Cell_CoreProperties", "to": "reference/interfaces/Cell_CoreProperties" }, { "label": "Cell_Cell", "to": "reference/interfaces/Cell_Cell" }, { "label": "Cell_ColumnGrouping", "to": "reference/interfaces/Cell_ColumnGrouping" }, { "label": "Cell_Plugins", "to": "reference/interfaces/Cell_Plugins" }, { "label": "CellContext", "to": "reference/interfaces/CellContext" }, { "label": "CellData", "to": "reference/type-aliases/CellData" }, { "label": "constructCell", "to": "reference/functions/constructCell" }, { "label": "cell_getContext", "to": "reference/functions/cell_getContext" }, { "label": "cell_getValue", "to": "reference/functions/cell_getValue" }, { "label": "cell_renderValue", "to": "reference/functions/cell_renderValue" }, { "label": "cell_getIsGrouped", "to": "reference/functions/cell_getIsGrouped" }, { "label": "cell_getIsPlaceholder", "to": "reference/functions/cell_getIsPlaceholder" }, { "label": "cell_getIsAggregated", "to": "reference/functions/cell_getIsAggregated" } ], "frameworks": [ { "label": "react", "children": [ { "label": "AppCellContext", "to": "framework/react/reference/index/type-aliases/AppCellContext" }, { "label": "AppCellComponent", "to": "framework/react/reference/index/interfaces/AppCellComponent" }, { "label": "AppCellPropsWithSelector", "to": "framework/react/reference/index/interfaces/AppCellPropsWithSelector" }, { "label": "AppCellPropsWithoutSelector", "to": "framework/react/reference/index/interfaces/AppCellPropsWithoutSelector" } ] }, { "label": "angular", "children": [ { "label": "AppCellContext", "to": "framework/angular/reference/type-aliases/AppCellContext" }, { "label": "TanStackTableCell", "to": "framework/angular/reference/classes/TanStackTableCell" }, { "label": "TanStackTableCellToken", "to": "framework/angular/reference/variables/TanStackTableCellToken" }, { "label": "TanStackTableCellContext", "to": "framework/angular/reference/interfaces/TanStackTableCellContext" }, { "label": "injectTableCellContext", "to": "framework/angular/reference/functions/injectTableCellContext" } ] } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Header API Reference", "children": [ { "label": "Header", "to": "reference/type-aliases/Header" }, { "label": "Header_Core", "to": "reference/interfaces/Header_Core" }, { "label": "Header_CoreProperties", "to": "reference/interfaces/Header_CoreProperties" }, { "label": "Header_Header", "to": "reference/interfaces/Header_Header" }, { "label": "Header_Plugins", "to": "reference/interfaces/Header_Plugins" }, { "label": "HeaderGroup", "to": "reference/type-aliases/HeaderGroup" }, { "label": "HeaderGroup_Core", "to": "reference/interfaces/HeaderGroup_Core" }, { "label": "HeaderGroup_Header", "to": "reference/interfaces/HeaderGroup_Header" }, { "label": "HeaderGroup_Plugins", "to": "reference/interfaces/HeaderGroup_Plugins" }, { "label": "HeaderContext", "to": "reference/interfaces/HeaderContext" }, { "label": "constructHeader", "to": "reference/functions/constructHeader" }, { "label": "buildHeaderGroups", "to": "reference/functions/buildHeaderGroups" }, { "label": "header_getContext", "to": "reference/functions/header_getContext" }, { "label": "header_getLeafHeaders", "to": "reference/functions/header_getLeafHeaders" }, { "label": "header_getSize", "to": "reference/functions/header_getSize" }, { "label": "header_getStart", "to": "reference/functions/header_getStart" }, { "label": "header_getResizeHandler", "to": "reference/functions/header_getResizeHandler" }, { "label": "table_getHeaderGroups", "to": "reference/functions/table_getHeaderGroups" }, { "label": "table_getLeftHeaderGroups", "to": "reference/functions/table_getLeftHeaderGroups" }, { "label": "table_getCenterHeaderGroups", "to": "reference/functions/table_getCenterHeaderGroups" }, { "label": "table_getRightHeaderGroups", "to": "reference/functions/table_getRightHeaderGroups" }, { "label": "table_getFooterGroups", "to": "reference/functions/table_getFooterGroups" }, { "label": "table_getLeftFooterGroups", "to": "reference/functions/table_getLeftFooterGroups" }, { "label": "table_getCenterFooterGroups", "to": "reference/functions/table_getCenterFooterGroups" }, { "label": "table_getRightFooterGroups", "to": "reference/functions/table_getRightFooterGroups" }, { "label": "table_getFlatHeaders", "to": "reference/functions/table_getFlatHeaders" }, { "label": "table_getLeftFlatHeaders", "to": "reference/functions/table_getLeftFlatHeaders" }, { "label": "table_getCenterFlatHeaders", "to": "reference/functions/table_getCenterFlatHeaders" }, { "label": "table_getRightFlatHeaders", "to": "reference/functions/table_getRightFlatHeaders" }, { "label": "table_getLeafHeaders", "to": "reference/functions/table_getLeafHeaders" }, { "label": "table_getLeftLeafHeaders", "to": "reference/functions/table_getLeftLeafHeaders" }, { "label": "table_getCenterLeafHeaders", "to": "reference/functions/table_getCenterLeafHeaders" }, { "label": "table_getRightLeafHeaders", "to": "reference/functions/table_getRightLeafHeaders" } ], "frameworks": [ { "label": "react", "children": [ { "label": "AppHeaderContext", "to": "framework/react/reference/index/type-aliases/AppHeaderContext" }, { "label": "AppHeaderComponent", "to": "framework/react/reference/index/interfaces/AppHeaderComponent" }, { "label": "AppHeaderPropsWithSelector", "to": "framework/react/reference/index/interfaces/AppHeaderPropsWithSelector" }, { "label": "AppHeaderPropsWithoutSelector", "to": "framework/react/reference/index/interfaces/AppHeaderPropsWithoutSelector" } ] }, { "label": "angular", "children": [ { "label": "AppHeaderContext", "to": "framework/angular/reference/type-aliases/AppHeaderContext" }, { "label": "TanStackTableHeader", "to": "framework/angular/reference/classes/TanStackTableHeader" }, { "label": "TanStackTableHeaderToken", "to": "framework/angular/reference/variables/TanStackTableHeaderToken" }, { "label": "TanStackTableHeaderContext", "to": "framework/angular/reference/interfaces/TanStackTableHeaderContext" }, { "label": "injectTableHeaderContext", "to": "framework/angular/reference/functions/injectTableHeaderContext" }, { "label": "injectFlexRenderContext", "to": "framework/angular/reference/functions/injectFlexRenderContext" } ] } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Features API Reference", "children": [ { "label": "stockFeatures", "to": "reference/variables/stockFeatures" }, { "label": "coreFeatures", "to": "reference/variables/coreFeatures" }, { "label": "coreCellsFeature", "to": "reference/variables/coreCellsFeature" }, { "label": "coreColumnsFeature", "to": "reference/variables/coreColumnsFeature" }, { "label": "coreHeadersFeature", "to": "reference/variables/coreHeadersFeature" }, { "label": "coreRowModelsFeature", "to": "reference/variables/coreRowModelsFeature" }, { "label": "coreRowsFeature", "to": "reference/variables/coreRowsFeature" }, { "label": "coreTablesFeature", "to": "reference/variables/coreTablesFeature" }, { "label": "columnFilteringFeature", "to": "reference/variables/columnFilteringFeature" }, { "label": "columnFacetingFeature", "to": "reference/variables/columnFacetingFeature" }, { "label": "columnGroupingFeature", "to": "reference/variables/columnGroupingFeature" }, { "label": "columnOrderingFeature", "to": "reference/variables/columnOrderingFeature" }, { "label": "columnPinningFeature", "to": "reference/variables/columnPinningFeature" }, { "label": "columnResizingFeature", "to": "reference/variables/columnResizingFeature" }, { "label": "columnSizingFeature", "to": "reference/variables/columnSizingFeature" }, { "label": "columnVisibilityFeature", "to": "reference/variables/columnVisibilityFeature" }, { "label": "globalFilteringFeature", "to": "reference/variables/globalFilteringFeature" }, { "label": "rowExpandingFeature", "to": "reference/variables/rowExpandingFeature" }, { "label": "rowPaginationFeature", "to": "reference/variables/rowPaginationFeature" }, { "label": "rowPinningFeature", "to": "reference/variables/rowPinningFeature" }, { "label": "rowSelectionFeature", "to": "reference/variables/rowSelectionFeature" }, { "label": "rowSortingFeature", "to": "reference/variables/rowSortingFeature" }, { "label": "Column_ColumnFiltering", "to": "reference/interfaces/Column_ColumnFiltering" }, { "label": "Column_ColumnFaceting", "to": "reference/interfaces/Column_ColumnFaceting" }, { "label": "Column_ColumnGrouping", "to": "reference/interfaces/Column_ColumnGrouping" }, { "label": "Column_ColumnOrdering", "to": "reference/interfaces/Column_ColumnOrdering" }, { "label": "Column_ColumnPinning", "to": "reference/interfaces/Column_ColumnPinning" }, { "label": "Column_ColumnResizing", "to": "reference/interfaces/Column_ColumnResizing" }, { "label": "Column_ColumnSizing", "to": "reference/interfaces/Column_ColumnSizing" }, { "label": "Column_ColumnVisibility", "to": "reference/interfaces/Column_ColumnVisibility" }, { "label": "Column_GlobalFiltering", "to": "reference/interfaces/Column_GlobalFiltering" }, { "label": "Column_RowSorting", "to": "reference/interfaces/Column_RowSorting" }, { "label": "Table_ColumnFiltering", "to": "reference/interfaces/Table_ColumnFiltering" }, { "label": "Table_ColumnFaceting", "to": "reference/interfaces/Table_ColumnFaceting" }, { "label": "Table_ColumnGrouping", "to": "reference/interfaces/Table_ColumnGrouping" }, { "label": "Table_ColumnOrdering", "to": "reference/interfaces/Table_ColumnOrdering" }, { "label": "Table_ColumnPinning", "to": "reference/interfaces/Table_ColumnPinning" }, { "label": "Table_ColumnResizing", "to": "reference/interfaces/Table_ColumnResizing" }, { "label": "Table_ColumnSizing", "to": "reference/interfaces/Table_ColumnSizing" }, { "label": "Table_ColumnVisibility", "to": "reference/interfaces/Table_ColumnVisibility" }, { "label": "Table_GlobalFiltering", "to": "reference/interfaces/Table_GlobalFiltering" }, { "label": "Table_RowExpanding", "to": "reference/interfaces/Table_RowExpanding" }, { "label": "Table_RowPagination", "to": "reference/interfaces/Table_RowPagination" }, { "label": "Table_RowPinning", "to": "reference/interfaces/Table_RowPinning" }, { "label": "Table_RowSelection", "to": "reference/interfaces/Table_RowSelection" }, { "label": "Table_RowSorting", "to": "reference/interfaces/Table_RowSorting" }, { "label": "Row_ColumnFiltering", "to": "reference/interfaces/Row_ColumnFiltering" }, { "label": "Row_ColumnGrouping", "to": "reference/interfaces/Row_ColumnGrouping" }, { "label": "Row_ColumnPinning", "to": "reference/interfaces/Row_ColumnPinning" }, { "label": "Row_ColumnVisibility", "to": "reference/interfaces/Row_ColumnVisibility" }, { "label": "Row_RowExpanding", "to": "reference/interfaces/Row_RowExpanding" }, { "label": "Row_RowPinning", "to": "reference/interfaces/Row_RowPinning" }, { "label": "Row_RowSelection", "to": "reference/interfaces/Row_RowSelection" }, { "label": "Header_ColumnResizing", "to": "reference/interfaces/Header_ColumnResizing" }, { "label": "Header_ColumnSizing", "to": "reference/interfaces/Header_ColumnSizing" }, { "label": "TableOptions_ColumnFiltering", "to": "reference/interfaces/TableOptions_ColumnFiltering" }, { "label": "TableOptions_ColumnGrouping", "to": "reference/interfaces/TableOptions_ColumnGrouping" }, { "label": "TableOptions_ColumnOrdering", "to": "reference/interfaces/TableOptions_ColumnOrdering" }, { "label": "TableOptions_ColumnPinning", "to": "reference/interfaces/TableOptions_ColumnPinning" }, { "label": "TableOptions_ColumnResizing", "to": "reference/interfaces/TableOptions_ColumnResizing" }, { "label": "TableOptions_ColumnSizing", "to": "reference/interfaces/TableOptions_ColumnSizing" }, { "label": "TableOptions_ColumnVisibility", "to": "reference/interfaces/TableOptions_ColumnVisibility" }, { "label": "TableOptions_GlobalFiltering", "to": "reference/interfaces/TableOptions_GlobalFiltering" }, { "label": "TableOptions_RowExpanding", "to": "reference/interfaces/TableOptions_RowExpanding" }, { "label": "TableOptions_RowPagination", "to": "reference/interfaces/TableOptions_RowPagination" }, { "label": "TableOptions_RowPinning", "to": "reference/interfaces/TableOptions_RowPinning" }, { "label": "TableOptions_RowSelection", "to": "reference/interfaces/TableOptions_RowSelection" }, { "label": "TableOptions_RowSorting", "to": "reference/interfaces/TableOptions_RowSorting" }, { "label": "TableState_ColumnFiltering", "to": "reference/interfaces/TableState_ColumnFiltering" }, { "label": "TableState_ColumnGrouping", "to": "reference/interfaces/TableState_ColumnGrouping" }, { "label": "TableState_ColumnOrdering", "to": "reference/interfaces/TableState_ColumnOrdering" }, { "label": "TableState_ColumnPinning", "to": "reference/interfaces/TableState_ColumnPinning" }, { "label": "TableState_ColumnResizing", "to": "reference/interfaces/TableState_ColumnResizing" }, { "label": "TableState_ColumnSizing", "to": "reference/interfaces/TableState_ColumnSizing" }, { "label": "TableState_ColumnVisibility", "to": "reference/interfaces/TableState_ColumnVisibility" }, { "label": "TableState_GlobalFiltering", "to": "reference/interfaces/TableState_GlobalFiltering" }, { "label": "TableState_RowExpanding", "to": "reference/interfaces/TableState_RowExpanding" }, { "label": "TableState_RowPagination", "to": "reference/interfaces/TableState_RowPagination" }, { "label": "TableState_RowPinning", "to": "reference/interfaces/TableState_RowPinning" }, { "label": "TableState_RowSelection", "to": "reference/interfaces/TableState_RowSelection" }, { "label": "TableState_RowSorting", "to": "reference/interfaces/TableState_RowSorting" }, { "label": "ColumnDef_ColumnFiltering", "to": "reference/interfaces/ColumnDef_ColumnFiltering" }, { "label": "ColumnDef_ColumnGrouping", "to": "reference/interfaces/ColumnDef_ColumnGrouping" }, { "label": "ColumnDef_ColumnPinning", "to": "reference/interfaces/ColumnDef_ColumnPinning" }, { "label": "ColumnDef_ColumnResizing", "to": "reference/interfaces/ColumnDef_ColumnResizing" }, { "label": "ColumnDef_ColumnSizing", "to": "reference/interfaces/ColumnDef_ColumnSizing" }, { "label": "ColumnDef_ColumnVisibility", "to": "reference/interfaces/ColumnDef_ColumnVisibility" }, { "label": "ColumnDef_GlobalFiltering", "to": "reference/interfaces/ColumnDef_GlobalFiltering" }, { "label": "ColumnDef_RowSorting", "to": "reference/interfaces/ColumnDef_RowSorting" }, { "label": "ColumnDef_Plugins", "to": "reference/interfaces/ColumnDef_Plugins" }, { "label": "ColumnPinningState", "to": "reference/interfaces/ColumnPinningState" }, { "label": "ColumnSort", "to": "reference/interfaces/ColumnSort" }, { "label": "ColumnFilter", "to": "reference/interfaces/ColumnFilter" }, { "label": "PaginationState", "to": "reference/interfaces/PaginationState" }, { "label": "RowPinningState", "to": "reference/interfaces/RowPinningState" }, { "label": "columnResizingState", "to": "reference/interfaces/columnResizingState" }, { "label": "ColumnFiltersState", "to": "reference/type-aliases/ColumnFiltersState" }, { "label": "ColumnOrderState", "to": "reference/type-aliases/ColumnOrderState" }, { "label": "ColumnSizingState", "to": "reference/type-aliases/ColumnSizingState" }, { "label": "ColumnVisibilityState", "to": "reference/type-aliases/ColumnVisibilityState" }, { "label": "ExpandedState", "to": "reference/type-aliases/ExpandedState" }, { "label": "GroupingState", "to": "reference/type-aliases/GroupingState" }, { "label": "RowSelectionState", "to": "reference/type-aliases/RowSelectionState" }, { "label": "SortingState", "to": "reference/type-aliases/SortingState" }, { "label": "FilterFn", "to": "reference/interfaces/FilterFn" }, { "label": "FilterFns", "to": "reference/interfaces/FilterFns" }, { "label": "FilterMeta", "to": "reference/interfaces/FilterMeta" }, { "label": "SortFn", "to": "reference/interfaces/SortFn" }, { "label": "SortFns", "to": "reference/interfaces/SortFns" }, { "label": "AggregationFns", "to": "reference/interfaces/AggregationFns" }, { "label": "filterFns", "to": "reference/variables/filterFns" }, { "label": "sortFns", "to": "reference/variables/sortFns" }, { "label": "aggregationFns", "to": "reference/variables/aggregationFns" } ] }, { "collapsible": true, "defaultCollapsed": true, "label": "Legacy API Reference", "children": [], "frameworks": [ { "label": "react", "children": [ { "label": "Legacy API Overview", "to": "framework/react/reference/legacy/index" }, { "label": "useLegacyTable", "to": "framework/react/reference/legacy/functions/useLegacyTable" }, { "label": "legacyCreateColumnHelper", "to": "framework/react/reference/legacy/functions/legacyCreateColumnHelper" }, { "label": "getCoreRowModel", "to": "framework/react/reference/legacy/functions/getCoreRowModel" }, { "label": "getFilteredRowModel", "to": "framework/react/reference/legacy/functions/getFilteredRowModel" }, { "label": "getSortedRowModel", "to": "framework/react/reference/legacy/functions/getSortedRowModel" }, { "label": "getGroupedRowModel", "to": "framework/react/reference/legacy/functions/getGroupedRowModel" }, { "label": "getExpandedRowModel", "to": "framework/react/reference/legacy/functions/getExpandedRowModel" }, { "label": "getPaginationRowModel", "to": "framework/react/reference/legacy/functions/getPaginationRowModel" }, { "label": "getFacetedRowModel", "to": "framework/react/reference/legacy/functions/getFacetedRowModel" }, { "label": "getFacetedMinMaxValues", "to": "framework/react/reference/legacy/functions/getFacetedMinMaxValues" }, { "label": "getFacetedUniqueValues", "to": "framework/react/reference/legacy/functions/getFacetedUniqueValues" }, { "label": "LegacyRowModelOptions", "to": "framework/react/reference/legacy/interfaces/LegacyRowModelOptions" }, { "label": "LegacyTable", "to": "framework/react/reference/legacy/type-aliases/LegacyTable" }, { "label": "LegacyTableOptions", "to": "framework/react/reference/legacy/type-aliases/LegacyTableOptions" }, { "label": "LegacyReactTable", "to": "framework/react/reference/legacy/type-aliases/LegacyReactTable" }, { "label": "LegacyColumnDef", "to": "framework/react/reference/legacy/type-aliases/LegacyColumnDef" }, { "label": "LegacyColumn", "to": "framework/react/reference/legacy/type-aliases/LegacyColumn" }, { "label": "LegacyRow", "to": "framework/react/reference/legacy/type-aliases/LegacyRow" }, { "label": "LegacyCell", "to": "framework/react/reference/legacy/type-aliases/LegacyCell" }, { "label": "LegacyHeader", "to": "framework/react/reference/legacy/type-aliases/LegacyHeader" }, { "label": "LegacyHeaderGroup", "to": "framework/react/reference/legacy/type-aliases/LegacyHeaderGroup" } ] } ] }, { "label": "Enterprise", "children": [ { "label": "AG Grid", "to": "enterprise/ag-grid" } ] }, { "label": "Basic Examples", "children": [], "frameworks": [ { "label": "angular", "children": [ { "to": "framework/angular/examples/basic", "label": "Basic" }, { "to": "framework/angular/examples/basic-app-table", "label": "Basic (App Table)" } ] }, { "label": "lit", "children": [ { "to": "framework/lit/examples/basic", "label": "Basic" } ] }, { "label": "react", "children": [ { "to": "framework/react/examples/basic-use-table", "label": "Basic (useTable)" }, { "to": "framework/react/examples/basic-use-app-table", "label": "Basic (useAppTable)" }, { "to": "framework/react/examples/basic-use-legacy-table", "label": "Basic (useLegacyTable)" }, { "to": "framework/react/examples/basic-external-state", "label": "Basic (External State)" }, { "to": "framework/react/examples/basic-external-store", "label": "Basic (External Store)" }, { "to": "framework/react/examples/basic-shadcn", "label": "Shadcn Basic" }, { "to": "framework/react/examples/column-groups", "label": "Header Groups" } ] }, { "label": "solid", "children": [ { "to": "framework/solid/examples/basic-use-table", "label": "Basic (createTable)" }, { "to": "framework/solid/examples/basic-app-table", "label": "Basic (createAppTable)" }, { "to": "framework/solid/examples/basic-external-state", "label": "Basic (External State)" }, { "to": "framework/solid/examples/basic-external-store", "label": "Basic (External Store)" }, { "to": "framework/solid/examples/column-groups", "label": "Header Groups" } ] }, { "label": "svelte", "children": [ { "to": "framework/svelte/examples/basic", "label": "Basic" }, { "to": "framework/svelte/examples/basic-snippets", "label": "Basic Snippets" }, { "to": "framework/svelte/examples/basic-table-helper", "label": "Basic with Helpers" }, { "to": "framework/svelte/examples/column-groups", "label": "Header Groups" } ] }, { "label": "vue", "children": [ { "to": "framework/vue/examples/basic", "label": "Basic" } ] }, { "label": "preact", "children": [ { "to": "framework/preact/examples/basic", "label": "Basic" } ] }, { "label": "vanilla", "children": [ { "to": "framework/vanilla/examples/basic", "label": "Basic" } ] } ] }, { "label": "Feature Examples", "children": [], "frameworks": [ { "label": "angular", "children": [ { "to": "framework/angular/examples/filters", "label": "Column Filters" }, { "to": "framework/angular/examples/column-ordering", "label": "Column Ordering" }, { "to": "framework/angular/examples/column-pinning", "label": "Column Pinning" }, { "to": "framework/angular/examples/column-pinning-sticky", "label": "Column Pinning (Sticky)" }, { "to": "framework/angular/examples/column-resizing-performant", "label": "Column Resizing" }, { "to": "framework/angular/examples/column-visibility", "label": "Column Visibility" }, { "to": "framework/angular/examples/expanding", "label": "Row Expanding" }, { "to": "framework/angular/examples/grouping", "label": "Column Grouping" }, { "to": "framework/angular/examples/row-selection", "label": "Row Selection" }, { "to": "framework/angular/examples/row-selection-signal", "label": "Row Selection (Signal)" } ] }, { "label": "lit", "children": [ { "to": "framework/lit/examples/column-sizing", "label": "Column Sizing" }, { "to": "framework/lit/examples/filters", "label": "Filters" }, { "to": "framework/lit/examples/row-selection", "label": "Row Selection" }, { "to": "framework/lit/examples/sorting", "label": "Sorting" }, { "to": "framework/lit/examples/sorting-dynamic-data", "label": "Sorting (Dynamic Data)" } ] }, { "label": "react", "children": [ { "to": "framework/react/examples/filters", "label": "Column Filters" }, { "to": "framework/react/examples/filters-faceted", "label": "Column Filters (Faceted)" }, { "to": "framework/react/examples/filters-fuzzy", "label": "Fuzzy Search Filters" }, { "to": "framework/react/examples/column-ordering", "label": "Column Ordering" }, { "to": "framework/react/examples/column-dnd", "label": "Column Ordering (DnD)" }, { "to": "framework/react/examples/column-pinning", "label": "Column Pinning" }, { "to": "framework/react/examples/column-pinning-split", "label": "Column Pinning (Split)" }, { "to": "framework/react/examples/column-pinning-sticky", "label": "Sticky Column Pinning" }, { "to": "framework/react/examples/column-sizing", "label": "Column Sizing" }, { "to": "framework/react/examples/column-resizing", "label": "Column Resizing" }, { "to": "framework/react/examples/column-resizing-performant", "label": "Performant Column Resizing" }, { "to": "framework/react/examples/column-visibility", "label": "Column Visibility" }, { "to": "framework/react/examples/expanding", "label": "Expanding" }, { "to": "framework/react/examples/grouping", "label": "Grouping" }, { "to": "framework/react/examples/pagination", "label": "Pagination" }, { "to": "framework/react/examples/row-dnd", "label": "Row DnD" }, { "to": "framework/react/examples/row-pinning", "label": "Row Pinning" }, { "to": "framework/react/examples/row-selection", "label": "Row Selection" }, { "to": "framework/react/examples/sorting", "label": "Sorting" } ] }, { "label": "solid", "children": [ { "to": "framework/solid/examples/column-ordering", "label": "Column Ordering" }, { "to": "framework/solid/examples/column-visibility", "label": "Column Visibility" }, { "to": "framework/solid/examples/filters", "label": "Filters" }, { "to": "framework/solid/examples/filters-faceted", "label": "Filters (Faceted)" }, { "to": "framework/solid/examples/row-selection", "label": "Row Selection" }, { "to": "framework/solid/examples/sorting", "label": "Sorting" } ] }, { "label": "svelte", "children": [ { "to": "framework/svelte/examples/column-ordering", "label": "Column Ordering" }, { "to": "framework/svelte/examples/column-pinning", "label": "Column Pinning" }, { "to": "framework/svelte/examples/column-visibility", "label": "Column Visibility" }, { "to": "framework/svelte/examples/filtering", "label": "Filtering" }, { "to": "framework/svelte/examples/row-selection", "label": "Row Selection" }, { "to": "framework/svelte/examples/sorting", "label": "Sorting" } ] }, { "label": "vue", "children": [ { "to": "framework/vue/examples/column-ordering", "label": "Column Ordering" }, { "to": "framework/vue/examples/column-pinning", "label": "Column Pinning" }, { "to": "framework/vue/examples/pagination", "label": "Pagination" }, { "to": "framework/vue/examples/pagination-controlled", "label": "Pagination Controlled" }, { "to": "framework/vue/examples/row-selection", "label": "Row Selection" }, { "to": "framework/vue/examples/sorting", "label": "Sorting" }, { "to": "framework/vue/examples/filters", "label": "Column Filters" } ] }, { "label": "preact", "children": [ { "to": "framework/preact/examples/sorting", "label": "Sorting" } ] }, { "label": "vanilla", "children": [ { "to": "framework/vanilla/examples/pagination", "label": "Pagination" }, { "to": "framework/vanilla/examples/sorting", "label": "Sorting" } ] } ] }, { "label": "Specialized Examples", "children": [], "frameworks": [ { "label": "angular", "children": [ { "to": "framework/angular/examples/composable-tables", "label": "Composable Tables" }, { "to": "framework/angular/examples/custom-plugin", "label": "Custom Plugin" }, { "to": "framework/angular/examples/sub-components", "label": "Sub Components" }, { "to": "framework/angular/examples/remote-data", "label": "Fetch API data (SPA / SSR)" }, { "to": "framework/angular/examples/signal-input", "label": "Signal Input" }, { "to": "framework/angular/examples/editable", "label": "Editable data" }, { "to": "framework/angular/examples/row-dnd", "label": "Row Drag & Drop" } ] }, { "label": "lit", "children": [ { "to": "framework/lit/examples/virtualized-rows", "label": "With TanStack Virtual - Rows" } ] }, { "label": "react", "children": [ { "to": "framework/react/examples/composable-tables", "label": "Composable Tables" }, { "to": "framework/react/examples/custom-plugin", "label": "Custom Plugin" }, { "to": "framework/react/examples/sub-components", "label": "Sub Components" }, { "to": "framework/react/examples/virtualized-columns", "label": "With TanStack Virtual - Columns" }, { "to": "framework/react/examples/virtualized-columns-experimental", "label": "With TanStack Virtual - Columns (Exp)" }, { "to": "framework/react/examples/virtualized-rows", "label": "With TanStack Virtual - Rows" }, { "to": "framework/react/examples/virtualized-rows-experimental", "label": "With TanStack Virtual - Rows (Exp)" }, { "to": "framework/react/examples/virtualized-infinite-scrolling", "label": "With TanStack Virtual - Infinite Scrolling" }, { "to": "framework/react/examples/with-tanstack-form", "label": "With TanStack Form" }, { "to": "framework/react/examples/with-tanstack-query", "label": "With TanStack Query" }, { "to": "framework/react/examples/with-tanstack-router", "label": "With TanStack Router" } ] }, { "label": "solid", "children": [ { "to": "framework/solid/examples/bootstrap", "label": "Solid Bootstrap" }, { "to": "framework/solid/examples/composable-tables", "label": "Composable Tables" }, { "to": "framework/solid/examples/with-tanstack-query", "label": "With TanStack Query" }] }, { "label": "vue", "children": [ { "to": "framework/vue/examples/sub-components", "label": "Sub Components" }, { "to": "framework/vue/examples/virtualized-rows", "label": "With TanStack Virtual (Rows)" } ] } ] }, { "label": "Kitchen Sink", "children": [], "frameworks": [ { "label": "react", "children": [ { "to": "framework/react/examples/kitchen-sink-shadcn", "label": "Kitchen Sink (Shadcn)" } ] } ] } ] } ================================================ FILE: docs/enterprise/ag-grid.md ================================================ --- title: AG Grid - An alternative enterprise data-grid solution ---

While we clearly love TanStack Table, we acknowledge that it is not a "batteries" included product packed with customer support and enterprise polish. We realize that some of our users may need this though! To help out here, we want to introduce you to AG Grid, an enterprise-grade data grid solution that can supercharge your applications with its extensive feature set and robust performance. While TanStack Table is also a powerful option for implementing data grids, we believe in providing our users with a diverse range of choices that best fit their specific requirements. AG Grid is one such choice, and we're excited to highlight its capabilities for you. ## Why Choose [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable)? Here are some good reasons to consider AG Grid for your next project: ### Comprehensive Feature Set AG Grid offers an extensive set of features, making it a versatile and powerful data grid solution. With AG Grid, you get access to a wide range of functionalities that cater to the needs of complex enterprise applications. From advanced sorting, filtering, and grouping capabilities to column pinning, multi-level headers, and tree data structure support, AG Grid provides you with the tools to create dynamic and interactive data grids that meet your application's unique demands. ### High Performance When it comes to handling large datasets and achieving exceptional performance, AG Grid delivers outstanding results. It employs highly optimized rendering techniques, efficient data updates, and virtualization to ensure smooth scrolling and fast response times, even when dealing with thousands or millions of rows of data. AG Grid's performance optimizations make it an excellent choice for applications that require high-speed data manipulation and visualization. ### Customization and Extensibility AG Grid is designed to be highly customizable and extensible, allowing you to tailor the grid to your specific needs. It provides a rich set of APIs and events that enable you to integrate custom functionality seamlessly. You can define custom cell renderers, editors, filters, and aggregators to enhance the grid's behavior and appearance. AG Grid also supports a variety of themes, allowing you to match the grid's visual style to your application's design. ### Support for Enterprise Needs As an enterprise-focused solution, AG Grid caters to the requirements of complex business applications. It offers enterprise-specific features such as row grouping, column pinning, server-side row model, master/detail grids, and rich editing capabilities. AG Grid also integrates well with other enterprise frameworks and libraries, making it a reliable choice for large-scale projects. ### Active Development and Community Support AG Grid benefits from active development and a thriving community of developers. The team behind AG Grid consistently introduces new features and enhancements, ensuring that the product evolves to meet the changing needs of the industry. The community support is robust, with forums, documentation, and examples readily available to assist you in utilizing the full potential of AG Grid. ## Conclusion While TanStack Table remains a powerful and flexible option for implementing data grids, we understand that different projects have different requirements. AG Grid offers a compelling enterprise-grade solution that may be particularly suited to your needs. Its comprehensive feature set, high performance, customization options, and focus on enterprise requirements make AG Grid an excellent choice for projects that demand a robust and scalable data grid solution. We encourage you to explore AG Grid further by visiting their website and trying out their demo. Remember that both TanStack Table and AG Grid have their unique strengths and considerations. We believe in providing options to our users, empowering you to make informed decisions and choose the best fit for your specific use case. Visit the [AG Grid website](https://www.ag-grid.com). ================================================ FILE: docs/faq.md ================================================ --- title: FAQ --- ## How do I stop infinite rendering loops? If you are using React, there is a very common pitfall that can cause infinite rendering. If you fail to give your `columns`, `data`, or `state` a stable reference, React will enter an infinite loop of re-rendering upon any change to the table state. Why does this happen? Is this a bug in TanStack Table? **No**, it is not. *This is fundamentally how React works*, and properly managing your columns, data, and state will prevent this from happening. TanStack Table is designed to trigger a re-render whenever either the `data` or `columns` that are passed into the table change, or whenever any of the table's state changes. > Failing to give `columns` or `data` stable references can cause an infinite loop of re-renders. ### Pitfall 1: Creating new columns or data on every render ```js export default function MyComponent() { //😵 BAD: This will cause an infinite loop of re-renders because `columns` is redefined as a new array on every render! const columns = [ // ... ]; //😵 BAD: This will cause an infinite loop of re-renders because `data` is redefined as a new array on every render! const data = [ // ... ]; //❌ Columns and data are defined in the same scope as `useTable` without a stable reference, will cause infinite loop! const table = useTable({ columns, data, }); return ...
; } ``` ### Solution 1: Stable references with useMemo or useState In React, you can give a "stable" reference to variables by defining them outside/above the component, or by using `useMemo` or `useState`, or by using a 3rd party state management library (like Redux or React Query 😉) ```js //✅ OK: Define columns outside of the component const columns = [ // ... ]; //✅ OK: Define data outside of the component const data = [ // ... ]; // Usually it's more practical to define columns and data inside the component, so use `useMemo` or `useState` to give them stable references export default function MyComponent() { //✅ GOOD: This will not cause an infinite loop of re-renders because `columns` is a stable reference const columns = useMemo(() => [ // ... ], []); //✅ GOOD: This will not cause an infinite loop of re-renders because `data` is a stable reference const [data, setData] = useState(() => [ // ... ]); // Columns and data are defined in a stable reference, will not cause infinite loop! const table = useTable({ columns, data, }); return ...
; } ``` ### Pitfall 2: Mutating columns or data in place Even if you give your initial `columns` and `data` stable references, you can still run into infinite loops if you mutate them in place. This is a common pitfall that you may not notice that you are doing at first. Something as simple as an inline `data.filter()` can cause an infinite loop if you are not careful. ```js export default function MyComponent() { //✅ GOOD const columns = useMemo(() => [ // ... ], []); //✅ GOOD (React Query provides stable references to data automatically) const { data, isLoading } = useQuery({ //... }); const table = useTable({ columns, //❌ BAD: This will cause an infinite loop of re-renders because `data` is mutated in place (destroys stable reference) data: data?.filter(d => d.isActive) ?? [], }); return ...
; } ``` ### Solution 2: Memoize your data transformations To prevent infinite loops, you should always memoize your data transformations. This can be done with `useMemo` or similar. ```js export default function MyComponent() { //✅ GOOD const columns = useMemo(() => [ // ... ], []); //✅ GOOD const { data, isLoading } = useQuery({ //... }); //✅ GOOD: This will not cause an infinite loop of re-renders because `filteredData` is memoized const filteredData = useMemo(() => data?.filter(d => d.isActive) ?? [], [data]); const table = useTable({ columns, data: filteredData, // stable reference! }); return ...
; } ``` ### React Forget When React Forget is released, these problems might be a thing of the past. Or just use Solid.js... 🤓 ## How do I stop my table state from automatically resetting when my data changes? Most plugins use state that _should_ normally reset when the data sources changes, but sometimes you need to suppress that from happening if you are filtering your data externally, or immutably editing your data while looking at it, or simply doing anything external with your data that you don't want to trigger a piece of table state to reset automatically. For those situations, each plugin provides a way to disable the state from automatically resetting internally when data or other dependencies for a piece of state change. By setting any of them to `false`, you can stop the automatic resets from being triggered. Here is a React-based example of stopping basically every piece of state from changing as they normally do while we edit the `data` source for a table: ```js const [data, setData] = React.useState([]) const skipPageResetRef = React.useRef() const updateData = newData => { // When data gets updated with this function, set a flag // to disable all of the auto resetting skipPageResetRef.current = true setData(newData) } React.useEffect(() => { // After the table has updated, always remove the flag skipPageResetRef.current = false }) useTable({ ... autoResetPageIndex: !skipPageResetRef.current, autoResetExpanded: !skipPageResetRef.current, }) ``` Now, when we update our data, the above table states will not automatically reset! ================================================ FILE: docs/framework/angular/angular-table.md ================================================ --- title: Angular Table --- The `@tanstack/angular-table` adapter is a wrapper around the core table logic. Most of it's job is related to managing state using angular signals, providing types and the rendering implementation of cell/header/footer templates. ## Exports `@tanstack/angular-table` re-exports all of `@tanstack/table-core`'s APIs and the following: ### `injectTable` Creates and returns an Angular-reactive table instance. `injectTable` accepts either: - an options function `() => TableOptions` - a computed signal returning `TableOptions` The initializer is intentionally re-evaluated whenever any signal read inside it changes. This is how the adapter keeps the table in sync with Angular's reactivity model. Because of that behavior, keep expensive/static values (for example `columns`, feature setup, row models) as stable references outside the initializer, and only read reactive state (`data()`, pagination/filter/sorting signals, etc.) inside it. Since `ColumnDef` is stricter about generics, prefer building columns with `createColumnHelper()` so feature and row types are inferred consistently. The returned table is also signal-reactive: table state and table APIs are wired for Angular signals, so you can safely consume table methods inside `computed(...)` and `effect(...)`. ```ts import { computed, effect, signal } from '@angular/core' import { createColumnHelper, injectTable, type ColumnDef, rowPaginationFeature, stockFeatures } from '@tanstack/angular-table' // Register all table core features const _features = tableFeatures(stockFeatures); // ...or register only your needed features const _features = tableFeatures({ rowPaginationFeature, // ...all other features }) const columnHelper = createColumnHelper() export class AppComponent { readonly data = signal([]) // If you type columns manually, include both generics: // readonly columns: ColumnDef[] = [...] readonly columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First name', cell: info => info.getValue(), }), // ... ]) // This function is re-run when any signal read inside changes. readonly table = injectTable(() => ({ _features: _features, // Reactive state can be read directly data: this.data(), state: { // ... }, // Keep stable references outside the initializer columns: this.columns, })) constructor() { effect(() => { console.log('Visible rows:', this.table.getRowModel().rows.length) }) } } ``` See [injectTable API Reference](reference/functions/injectTable) ### `createTableHook` `createTableHook` is the Angular composition API for building reusable table infrastructure. Use it when multiple tables should share the same defaults (features, row models, default options, and component registries) while keeping strong types across the app. At runtime, `createTableHook` wraps `injectTable` and returns typed helpers such as: - `injectAppTable` for creating tables with shared defaults - `createAppColumnHelper` for strongly typed column definitions - pre-typed context helpers (`injectTableContext`, `injectTableCellContext`, `injectTableHeaderContext`, `injectFlexRenderCellContext`, `injectFlexRenderHeaderContext`) For full setup and patterns, see the [Table Composition Guide](./guide/table-composition.md). ### `FlexRender` An Angular structural rendering primitive for cell/header/footer content. It supports the same content kinds as Angular rendering: - primitive values (`string`, `number`, plain objects) - `TemplateRef` - component types - `flexRenderComponent(component, options?)` wrappers with typed `inputs`, `outputs`, `injector`, `bindings`, and `directives` Column render functions (`header`, `cell`, `footer`) run in Angular injection context, so you can use `inject()` and signals directly in render logic. For complete rendering details (`*flexRender`, shorthand directives, `flexRenderComponent`, `TemplateRef`, component inputs/outputs, and `injectFlexRenderContext`), see the [Rendering components Guide](./guide/rendering.md). ### Context helpers and directives `@tanstack/angular-table` also exports Angular DI helpers and directives for table/cell/header context: - `TanStackTable` + `injectTableContext()` - `TanStackTableCell` + `injectTableCellContext()` - `TanStackTableHeader` + `injectTableHeaderContext()` These APIs provide signal-based context values and are available from nearest directives or from `*flexRender`-rendered components when matching props are present. ### Full API Reference See [Angular API Reference](reference/index.md) ================================================ FILE: docs/framework/angular/guide/migrating.md ================================================ --- title: Migrating to TanStack Table v9 (Angular) --- ## What's New in TanStack Table v9 TanStack Table v9 is a major release that introduces significant architectural improvements while maintaining the core table logic you're familiar with. Here are the key changes: ### 1. Tree-shaking - **Features are tree-shakeable**: Features are now treated as plugins—import only what you use. If your table only needs sorting, you won't ship filtering, pagination, or other feature code. Bundlers can eliminate unused code, so for smaller tables you can expect a meaningfully smaller bundle compared to v8. This also lets TanStack Table add features over time without bloating everyone's bundles. - **Row models and their functions are refactored**: Row model factories (`createFilteredRowModel`, `createSortedRowModel`, etc.) now accept their processing functions (`filterFns`, `sortFns`, `aggregationFns`) as parameters. This enables tree-shaking of the functions themselves—if you use a custom filter, you don't pay for built-in filters you never use. ### 2. State Management - **Uses TanStack Store**: The internal state system has been rebuilt on [TanStack Store](https://tanstack.com/store), providing a reactive, framework-agnostic foundation. - **Opt-in subscriptions instead of memo hacks**: In Angular, you consume state via signals and `computed(...)`. You can keep reads scoped to the state you actually need and avoid unnecessary template work. ### 3. Composability - **`tableOptions`**: New utilities let you compose and share table configurations. Define `_features`, `_rowModels`, and default options once, then reuse them across tables or pass them through `createTableHook`. - **`createTableHook`** (optional, advanced): Create reusable, strongly typed Angular table factories with pre-bound features, row models, default options, and component registries. ### The Good News: Most Upgrades Are Opt-in While v9 is a significant upgrade, **you don't have to adopt everything at once**: - **Don't want to think about tree-shaking yet?** You can start with `stockFeatures` to include most commonly used features. - **Your table markup is largely unchanged.** How you render ``, ``, ``, ` @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } } ``` ## Cell rendering with custom props When you need full control over the `props` passed to the render function, use `*flexRender` directly. `FlexRenderDirective` accepts two inputs: - `flexRender` — the render definition (a column def function, a string, a `TemplateRef`, a component type, or a `flexRenderComponent(...)` wrapper) - `flexRenderProps` — the props object passed to the render function and used as the implicit template context Standard usage: ```html {{ rendered }} ``` You can pass a custom props object to override the default context shape: ```html {{ rendered }} ``` Inside rendered components, the full props object is available via [`injectFlexRenderContext()`](#injectflexrendercontext). ## Component rendering You can render Angular components from column definitions in two ways: ### Using `flexRenderComponent` [`flexRenderComponent(component, options?)`](../reference/functions/flexRenderComponent) wraps a component type with explicit options for `inputs`, `outputs`, `injector`, `bindings`, and `directives`. Use this when you need to: - pass custom inputs not derived from the render context - subscribe to component outputs - provide a custom `Injector` - use creation-time `bindings` (Angular v20+) - apply host directives and binding values at runtime ```ts import { flexRenderComponent, type ColumnDef } from '@tanstack/angular-table' const columns: ColumnDef[] = [ { id: 'custom-cell', cell: ctx => flexRenderComponent(CustomCellComponent, { inputs: { content: ctx.row.original.firstName, }, outputs: { clicked: value => { console.log(value) }, }, }), }, ] ``` #### How inputs and outputs work **Inputs** are applied through [`ComponentRef.setInput(key, value)`](https://angular.dev/api/core/ComponentRef#setInput). This works with both `input()` signals and `@Input()` decorators. Inputs are diffed on every change detection cycle using `KeyValueDiffers` — only changed values trigger `setInput`. For object-like inputs, updates are reference-based: if the object reference is stable, Angular's default input equality semantics prevent unnecessary updates. **Outputs** work through `OutputEmitterRef` subscriptions. The factory reads the component instance property by name, checks that it is an `OutputEmitterRef`, and subscribes to it. When the output emits, the corresponding callback from `outputs` is invoked. Subscriptions are cleaned up automatically when the component is destroyed. #### `bindings` API (Angular v20+) `flexRenderComponent` also accepts `bindings` and `directives`, forwarded directly to [`ViewContainerRef.createComponent`](https://angular.dev/api/core/ViewContainerRef#createComponent) at creation time. This supports Angular programmatic rendering APIs for passing host directives and binding values at runtime. Unlike `inputs`/`outputs` (which are applied imperatively after creation), `bindings` are applied **at creation time** — they participate in the component's initial change detection cycle. ```ts import { inputBinding, outputBinding, twoWayBinding, signal, } from '@angular/core' import { flexRenderComponent } from '@tanstack/angular-table' readonly name = signal('Ada') cell: () => flexRenderComponent(EditableNameCellComponent, { bindings: [ inputBinding('value', this.name), outputBinding('valueChange', value => { console.log('changed', value) }), twoWayBinding('value', this.name), ], }) ``` > Avoid mixing `bindings` with `inputs`/`outputs` on the same property. `bindings` are applied at creation, while `inputs`/`outputs` are applied post-creation — mixing them can lead to double initialization or conflicting values. See the Angular docs for details: - [Programmatic rendering — Binding inputs/outputs/directives](https://angular.dev/guide/components/programmatic-rendering#binding-inputs-outputs-and-setting-host-directives-at-creation) - [`inputBinding`](https://angular.dev/api/core/inputBinding), [`outputBinding`](https://angular.dev/api/core/outputBinding), [`twoWayBinding`](https://angular.dev/api/core/twoWayBinding) ### Returning a component class Return a component class from `header`, `cell`, or `footer`. The render context properties (`table`, `column`, `header`, `cell`, `row`, `getValue`, etc.) are automatically set as component inputs via `ComponentRef.setInput(...)`. Define input signals matching the context property names you need: ```ts import { Component, input } from '@angular/core' import type { ColumnDef, Table, CellContext } from '@tanstack/angular-table' const columns: ColumnDef[] = [ { id: 'select', header: () => TableHeadSelectionComponent, cell: () => TableRowSelectionComponent, }, ] @Component({ template: ` `, }) export class TableHeadSelectionComponent { readonly table = input.required>(); // column = input.required>() // header = input.required>() } ``` Only properties declared with `input()` / `input.required()` are set — other context properties are silently ignored. You can also access the full context via [`injectFlexRenderContext()`](#injectflexrendercontext). ## TemplateRef rendering You can return a `TemplateRef` from column definitions. The render context is passed as the template's `$implicit` context. Use `viewChild(...)` to capture template references: ```ts import { Component, TemplateRef, viewChild } from '@angular/core' import type { CellContext, ColumnDef, HeaderContext, } from '@tanstack/angular-table' @Component({ template: ` {{ context.column.id }} {{ context.getValue() }} `, }) export class AppComponent { readonly customHeader = viewChild.required }>>( 'customHeader', ) readonly customCell = viewChild.required }>>( 'customCell', ) readonly columns: ColumnDef[] = [ { id: 'templated', header: () => this.customHeader(), cell: () => this.customCell(), }, ] } ``` `TemplateRef` rendering uses `createEmbeddedView` with an injector that includes the [DI context tokens](#dependency-injection). For reusable render blocks shared across multiple screens, prefer standalone components over `TemplateRef`. ## Dependency injection `FlexRender` automatically provides DI tokens when rendering components and templates. These tokens are created in the `#getInjector` method of the renderer, which builds a child `Injector` with the render context properties. ### `injectFlexRenderContext` [`injectFlexRenderContext()`](../reference/functions/injectFlexRenderContext) returns the full props object passed to `*flexRender`. The return type depends on the column definition slot: - In a `cell` definition: `CellContext` - In a `header`/`footer` definition: `HeaderContext` ```ts import { Component } from '@angular/core' import { injectFlexRenderContext, type CellContext, } from '@tanstack/angular-table' @Component({ template: ` {{ context.getValue() }} `, }) export class InteractiveCellComponent { readonly context = injectFlexRenderContext>() } ``` Internally, the renderer wraps the context in a `Proxy` so that property access always reflects the latest values, even after re-renders. ### Context directives Three optional directives let you expose table, header, and cell context to **any descendant** in the template — not just components rendered by `*flexRender`. This eliminates prop drilling: instead of passing data through multiple `input()` layers, any nested component or directive can inject the context directly. | Directive | Selector | Token | Inject helper | |---|---|---|---| | [`TanStackTable`](../reference/functions/injectTableContext) | `[tanStackTable]` | `TanStackTableToken` | `injectTableContext()` | | [`TanStackTableHeader`](../reference/functions/injectTableHeaderContext) | `[tanStackTableHeader]` | `TanStackTableHeaderToken` | `injectTableHeaderContext()` | | [`TanStackTableCell`](../reference/functions/injectTableCellContext) | `[tanStackTableCell]` | `TanStackTableCellToken` | `injectTableCellContext()` | Import them alongside `FlexRender`: ```ts import { FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell, } from '@tanstack/angular-table' @Component({ imports: [FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell], templateUrl: './app.html', }) export class AppComponent {} ``` Apply them in the template to establish injection scopes: ```html
`, etc. remains the same. The main change is **how you define a table** with the Angular adapter — specifically the new `_features` and `_rowModels` options. --- ## Quick Legacy Migration Angular does **not** ship a legacy API. If you're migrating an Angular project from TanStack Table v8 to v9, you will migrate directly to the v9 Angular adapter APIs (`injectTable`, `_features`, and `_rowModels`). --- The rest of this guide focuses on migrating to the full v9 API and taking advantage of its features. ## Core Breaking Changes ### Entrypoint Change The Angular adapter entrypoint to create a table instance is `injectTable`: ```ts // v8 import { createAngularTable } from '@tanstack/angular-table' const v8Table = createAngularTable(() => ({ // options })) // v9 import { injectTable } from '@tanstack/angular-table' const v9Table = injectTable(() => ({ // options })) ``` > Note: `injectTable` evaluates your initializer whenever any Angular signal read inside of it changes. > Keep expensive/static values (like `columns`, `_features`, and `_rowModels`) as stable references outside the initializer. ### New Required Options: `_features` and `_rowModels` In v9, you must explicitly declare which features and row models your table uses: ```ts // v8 import { createAngularTable, getCoreRowModel } from '@tanstack/angular-table' const v8Table = createAngularTable(() => ({ columns, data: data(), getCoreRowModel: getCoreRowModel(), })) // v9 import { injectTable, tableFeatures, } from '@tanstack/angular-table' const _features = tableFeatures({}) // Empty = core feaFtures only // Define stable references outside the initializer const v9Table = injectTable(() => ({ _features, _rowModels: {}, // Core row model is automatic columns: this.columns, data: this.data(), })) ``` --- ## The `_features` Option Features control what table functionality is available. In v8, all features were bundled. In v9, you import only what you need. ### Importing Individual Features ```ts import { tableFeatures, // Import only the features you need columnFilteringFeature, rowSortingFeature, rowPaginationFeature, columnVisibilityFeature, rowSelectionFeature, } from '@tanstack/angular-table' // Create a features object (define this outside your injectTable initializer for stable reference) const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, columnVisibilityFeature, rowSelectionFeature, }) ``` ### Using `stockFeatures` for v8-like Behavior If you want all features without thinking about it (like v8), import `stockFeatures`: ```ts import { injectTable, stockFeatures } from '@tanstack/angular-table' class TableCmp { readonly table = injectTable(() => ({ _features: stockFeatures, // All features included _rowModels: { /* ... */ }, columns: this.columns, data: this.data(), })) } ``` ### Available Features | Feature | Import Name | |---------|-------------| | Column Filtering | `columnFilteringFeature` | | Global Filtering | `globalFilteringFeature` | | Row Sorting | `rowSortingFeature` | | Row Pagination | `rowPaginationFeature` | | Row Selection | `rowSelectionFeature` | | Row Expanding | `rowExpandingFeature` | | Row Pinning | `rowPinningFeature` | | Column Pinning | `columnPinningFeature` | | Column Visibility | `columnVisibilityFeature` | | Column Ordering | `columnOrderingFeature` | | Column Sizing | `columnSizingFeature` | | Column Resizing | `columnResizingFeature` | | Column Grouping | `columnGroupingFeature` | | Column Faceting | `columnFacetingFeature` | --- ## The `_rowModels` Option Row models are the functions that process your data (filtering, sorting, pagination, etc.). In v9, they're configured via `_rowModels` instead of `get*RowModel` options. ### Migration Mapping | v8 Option | v9 `_rowModels` Key | v9 Factory Function | |-----------|---------------------|---------------------| | `getCoreRowModel()` | (automatic) | Not needed — always included | | `getFilteredRowModel()` | `filteredRowModel` | `createFilteredRowModel(filterFns)` | | `getSortedRowModel()` | `sortedRowModel` | `createSortedRowModel(sortFns)` | | `getPaginationRowModel()` | `paginatedRowModel` | `createPaginatedRowModel()` | | `getExpandedRowModel()` | `expandedRowModel` | `createExpandedRowModel()` | | `getGroupedRowModel()` | `groupedRowModel` | `createGroupedRowModel(aggregationFns)` | | `getFacetedRowModel()` | `facetedRowModel` | `createFacetedRowModel()` | | `getFacetedMinMaxValues()` | `facetedMinMaxValues` | `createFacetedMinMaxValues()` | | `getFacetedUniqueValues()` | `facetedUniqueValues` | `createFacetedUniqueValues()` | ### Key Change: Row Model Functions Now Accept Parameters Several row model factories now accept their processing functions as parameters. This enables better tree-shaking and explicit configuration: ```ts import { injectTable, createFilteredRowModel, createSortedRowModel, createGroupedRowModel, createPaginatedRowModel, filterFns, // Built-in filter functions sortFns, // Built-in sort functions aggregationFns, // Built-in aggregation functions } from '@tanstack/angular-table' class TableCmp { readonly table = injectTable(() => ({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), sortedRowModel: createSortedRowModel(sortFns), groupedRowModel: createGroupedRowModel(aggregationFns), paginatedRowModel: createPaginatedRowModel(), }, columns: this.columns, data: this.data(), })) } ``` ### Full Migration Example ```ts // v8 import { injectTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, filterFns, sortingFns, } from '@tanstack/angular-table' const v8Table = createAngularTable(() => ({ columns, data: data(), getCoreRowModel: getCoreRowModel(), // used to be called "get*RowModel()" getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), filterFns, // used to be passed in as a root option sortingFns, })) // v9 import { injectTable, tableFeatures, columnFilteringFeature, rowSortingFeature, rowPaginationFeature, createFilteredRowModel, createSortedRowModel, createPaginatedRowModel, filterFns, sortFns, } from '@tanstack/angular-table' const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, }) const v9Table = injectTable(() => ({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data: data(), })) ``` --- ## State Management Changes ### Accessing State In v8, you accessed state via `table.getState()`. In v9, state is accessed via the store: ```ts // v8 const state = table.getState() const v8 = table.getState() const { sorting, pagination } = v8 // v9 - via the store const fullState = table.store.state const v9 = table.store.state const { sorting: v9Sorting, pagination: v9Pagination } = v9 ``` ### Optimizing Reads with Angular Signals In Angular, you have a few good options for consuming table state. #### Option 1: Prefer `table.store.subscribe(...)` for a sliced signal TanStack Store lets you subscribe to (and derive) a slice of state. With the Angular adapter, you can use that to create a signal-like value that only updates when the selected slice changes. This is the closest equivalent to the fine-grained subscription examples you might see in other frameworks. ```ts import { computed, effect } from '@angular/core' class TableCmp { readonly table = injectTable(() => ({ _features, _rowModels: { /* ... */ }, columns: this.columns, data: this.data(), })) // Create a computed to a slice of state. // The store will only emit when this selected value changes. private readonly pagination = this.table.computed( state => state.pagination, ) constructor() { effect(() => { const { pageIndex, pageSize } = this.pagination() console.log('Page', pageIndex, 'Size', pageSize) }) } } ``` #### Option 2: Use `computed(...)` and read from `table.store.state` You can also use Angular `computed(...)` and directly read from `table.store.state`. This is simple and works well, but for object/array slices you should provide an equality function to avoid unnecessary downstream work when the slice is recreated with the same values. ```ts import { computed, effect } from '@angular/core' class TableCmp { readonly table = injectTable(() => ({ _features, _rowModels: { /* ... */ }, columns: this.columns, data: this.data(), })) // Provide an equality function for object slices readonly pagination = computed( () => this.table.store.state.pagination, { equal: (a, b) => a.pageIndex === b.pageIndex && a.pageSize === b.pageSize, }, ) constructor() { effect(() => { // This effect only re-runs when pagination changes const { pageIndex, pageSize } = this.pagination() console.log('Page', pageIndex, 'Size', pageSize) }) } } ``` ### Controlled State Controlled state patterns are pretty the same as v8: ```ts import { signal } from '@angular/core' import type { SortingState, PaginationState } from '@tanstack/angular-table' class TableCmp { readonly sorting = signal([]) readonly pagination = signal({ pageIndex: 0, pageSize: 10 }) readonly table = injectTable(() => ({ _features, _rowModels: { /* ... */ }, columns: this.columns, data: this.data(), state: { sorting: this.sorting(), pagination: this.pagination(), }, onSortingChange: (updater) => { updater instanceof Function ? this.sorting.update(updater) : this.sorting.set(updater) }, onPaginationChange: (updater) => { updater instanceof Function ? this.pagination.update(updater) : this.pagination.set(updater) }, })) } ``` --- ## Column Helper Changes The `createColumnHelper` function now requires a `TFeatures` type parameter in addition to `TData`: ```ts // v8 import { createColumnHelper } from '@tanstack/angular-table' const columnHelperV8 = createColumnHelper() // v9 import { createColumnHelper, tableFeatures, rowSortingFeature } from '@tanstack/angular-table' const _features = tableFeatures({ rowSortingFeature }) const columnHelperV9 = createColumnHelper() ``` ### New `columns()` Helper Method v9 adds a `columns()` helper for better type inference when wrapping column arrays. ```ts const columnHelper = createColumnHelper() // Wrap your columns array for better type inference const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { id: 'lastName', header: () => 'Last Name', cell: (info) => info.getValue(), }), columnHelper.display({ id: 'actions', header: 'Actions', cell: () => 'Edit', }), ]) ``` ### Using with `createTableHook` When using `createTableHook`, you get a pre-bound `createAppColumnHelper` that only requires `TData`: ```ts import { createTableHook, tableFeatures, rowSortingFeature } from '@tanstack/angular-table' const { injectAppTable, createAppColumnHelper } = createTableHook({ _features: tableFeatures({ rowSortingFeature }), _rowModels: { /* ... */ }, }) // TFeatures is already bound — only need TData! const columnHelper = createAppColumnHelper() ``` --- ## Rendering Changes ### `FlexRender` The rendering primitives in the Angular adapter are `FlexRender` and the `*flexRender` directives. In v9, you can continue to render header/cell/footer content using the Angular adapter rendering utilities, but there are a few important improvements and helper APIs to be aware of. #### Structural directive rendering Angular rendering is directive-based: - `FlexRender` / `*flexRender` renders arbitrary render content (primitives, `TemplateRef`, component types, or `flexRenderComponent(...)` wrappers) - The directive is responsible for mounting embedded views or components via `ViewContainerRef` #### Shorthand directives If you're rendering standard table content, prefer the shorthand helpers: - `*flexRenderCell="cell; let value"` - `*flexRenderHeader="header; let value"` - `*flexRenderFooter="footer; let value"` These automatically select the correct column definition (`columnDef.cell` / `header` / `footer`) and the right props (`cell.getContext()` / `header.getContext()`), so you don't need to manually provide `props:`. #### DI-aware render functions + context injection Column definition render functions (`header`, `cell`, `footer`) run inside an Angular injection context, so they can safely call `inject()` and use signals. When a component is rendered through the FlexRender directives, you can also access the full render props object via DI using `injectFlexRenderContext()`. #### Component rendering helper: `flexRenderComponent` If you need to render an Angular component with explicit configuration (custom `inputs`, `outputs`, `injector`, and Angular v20+ creation-time `bindings`/`directives`), return a `flexRenderComponent(Component, options)` wrapper from your column definition. For complete rendering details (including component rendering, `TemplateRef`, `flexRenderComponent`, and context helpers), see the [Rendering components Guide](./rendering.md). --- ## The `tableOptions()` Utility The `tableOptions()` helper provides type-safe composition of table options. It's useful for creating reusable partial configurations that can be spread into your table setup. ### Basic Usage ```ts import { injectTable, tableOptions, tableFeatures, rowSortingFeature } from '@tanstack/angular-table' import { isDevMode } from '@angular/core'; // Create a reusable options object with features pre-configured const baseOptions = tableOptions({ _features: tableFeatures({ rowSortingFeature }), debugTable: isDevMode() }) class TableCmp { readonly table = injectTable(() => ({ ...baseOptions, columns: this.columns, data: this.data(), _rowModels: {}, })) } ``` ### Composing Partial Options `tableOptions()` allows you to omit certain required fields (like `data`, `columns`, or `_features`) when creating partial configurations: ```ts import { tableOptions, tableFeatures, rowSortingFeature, columnFilteringFeature, createSortedRowModel, createFilteredRowModel, filterFns, sortFns, } from '@tanstack/angular-table' // Partial options without data or columns const featureOptions = tableOptions({ _features: tableFeatures({ rowSortingFeature, columnFilteringFeature, }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), }, }) ``` ```ts import { injectTable, tableOptions, createPaginatedRowModel } from '@tanstack/angular-table' // Another partial without _features (inherits from spread) const paginationDefaults = tableOptions({ _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, initialState: { pagination: { pageIndex: 0, pageSize: 25 }, }, }) class TableCmp { readonly table = injectTable(() => ({ ...featureOptions, ...paginationDefaults, columns: this.columns, data: this.data(), })) } ``` ### Using with `createTableHook` `tableOptions()` pairs well with `createTableHook` for building composable table factories: ```ts import { createTableHook, tableOptions, tableFeatures, rowSortingFeature, rowPaginationFeature, createSortedRowModel, createPaginatedRowModel, sortFns, } from '@tanstack/angular-table' const sharedOptions = tableOptions({ _features: tableFeatures({ rowSortingFeature, rowPaginationFeature }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, }) const { injectAppTable } = createTableHook(sharedOptions) ``` --- ## `createTableHook`: Composable Table Patterns **This is an advanced, optional feature.** You don't need to use `createTableHook`—`injectTable` is sufficient for most use cases. For applications with multiple tables sharing the same configuration, `createTableHook` lets you define features, row models, and reusable components once. For full setup and patterns, see the [Table composition Guide](./table-composition.md). --- ## Other Breaking Changes ### Column Pinning Option Split The `enablePinning` option has been split into separate options: ```ts // v8 enablePinning: true // v9 enableColumnPinning: true enableRowPinning: true ``` ### Removed Internal APIs All internal APIs prefixed with `_` have been removed. If you were using any of these, use their public equivalents. ### Column Sizing vs. Column Resizing Split In v8, column sizing and resizing were combined in a single feature. In v9, they've been split into separate features for better tree-shaking. | v8 | v9 | |----|-----| | `ColumnSizing` (combined feature) | `columnSizingFeature` + `columnResizingFeature` | | `columnSizingInfo` state | `columnResizing` state | | `setColumnSizingInfo()` | `setColumnResizing()` | | `onColumnSizingInfoChange` option | `onColumnResizingChange` option | If you only need column sizing (fixed widths) without interactive resizing, you can import just `columnSizingFeature`. If you need drag-to-resize functionality, import both. ### Sorting API Renames Sorting-related APIs have been renamed for consistency: | v8 | v9 | |----|-----| | `sortingFn` (column def option) | `sortFn` | | `column.getSortingFn()` | `column.getSortFn()` | | `column.getAutoSortingFn()` | `column.getAutoSortFn()` | | `SortingFn` type | `SortFn` type | | `SortingFns` interface | `SortFns` interface | | `sortingFns` (built-in functions) | `sortFns` | Update your column definitions. ### Row API Changes Some row APIs have changed from private to public: | v8 | v9 | |----|-----| | `row._getAllCellsByColumnId()` (private) | `row.getAllCellsByColumnId()` (public) | --- ## TypeScript Changes Summary ### Type Generics Most types now require a `TFeatures` parameter: ```txt // v8 type Column type ColumnDef type Table type Row type Cell // v9 type Column type ColumnDef type Table type Row type Cell ``` ### Using `typeof _features` The easiest way to get the `TFeatures` type is with `typeof`: ```ts const _features = tableFeatures({ rowSortingFeature, columnFilteringFeature, }) type MyFeatures = typeof _features const columns: ColumnDef[] = [...] ``` ### Using `StockFeatures` If using `stockFeatures`, use the `StockFeatures` type: ```ts import type { StockFeatures, ColumnDef } from '@tanstack/angular-table' const columns: ColumnDef[] = [...] ``` ### `ColumnMeta` Generic Change If you're using module augmentation to extend `ColumnMeta`, note that it now requires a `TFeatures` parameter. ### `RowData` Type Restriction The `RowData` type is now more restrictive. --- ## Migration Checklist - [ ] Update your table setup to v9 and define `_features` using `tableFeatures()` (or use `stockFeatures`) - [ ] Migrate `get*RowModel()` options to `_rowModels` - [ ] Update row model factories to include `Fns` parameters where needed - [ ] Update TypeScript types to include `TFeatures` generic - [ ] Update state access: `table.getState()` → `table.store.state` - [ ] Update `createColumnHelper()` → `createColumnHelper()` - [ ] Replace `enablePinning` with `enableColumnPinning`/`enableRowPinning` if used - [ ] Rename `sortingFn` → `sortFn` in column definitions - [ ] Split column sizing/resizing: use both `columnSizingFeature` and `columnResizingFeature` if needed - [ ] Rename `columnSizingInfo` state → `columnResizing` (and related options) - [ ] Update `ColumnMeta` module augmentation to include `TFeatures` generic (if used) - [ ] (Optional) Use `tableOptions()` for composable configurations - [ ] (Optional) Use `createTableHook` for reusable table patterns --- ## Examples Check out these examples to see v9 patterns in action: - [Basic](../examples/basic) - [Basic (App Table)](../examples/basic-app-table) - [Filters](../examples/filters) - [Column Ordering](../examples/column-ordering) - [Column Pinning](../examples/column-pinning) - [Column Visibility](../examples/column-visibility) - [Expanding](../examples/expanding) - [Grouping](../examples/grouping) - [Row Selection](../examples/row-selection) - [Composable Tables](../examples/composable-tables) ================================================ FILE: docs/framework/angular/guide/rendering.md ================================================ --- title: Rendering components --- The `@tanstack/angular-table` adapter provides structural directives and dependency injection primitives for rendering table content in Angular templates. ## FlexRender [`FlexRender`](../reference/variables/FlexRender) is the rendering primitive. It is exported as a tuple of two directives: - [`FlexRenderDirective`](../reference/classes/FlexRenderDirective) — the base structural directive (`*flexRender`) - [`FlexRenderCell`](../reference/classes/FlexRenderCell.md) — shorthand directives (`*flexRenderCell`, `*flexRenderHeader`, `*flexRenderFooter`) Import `FlexRender` to get both: ```ts import { Component } from '@angular/core' import { FlexRender } from '@tanstack/angular-table' @Component({ imports: [FlexRender], templateUrl: './app.html', }) export class AppComponent {} ``` ### How it works `FlexRender` is an Angular **structural directive**. Internally, it resolves the column definition's `header`, `cell`, or `footer` function and renders the result using [`ViewContainerRef`](https://angular.dev/api/core/ViewContainerRef): - **Primitives** (`string`, `number`): rendered via `createEmbeddedView` into the host `ng-template`. The value is exposed as the template's implicit context (`let value`). - **`TemplateRef`**: rendered via `createEmbeddedView`. The render context (`CellContext`, `HeaderContext`) is passed as `$implicit`. - **`flexRenderComponent(...)`**: rendered via `createComponent` with explicit `inputs`, `outputs`, `bindings`, `directives`, and `injector`. - **Component type** (`Type`): rendered via [`createComponent`](https://angular.dev/api/core/ViewContainerRef#createComponent). All properties from the render context are set as component inputs through [`ComponentRef.setInput`](https://angular.dev/api/core/ComponentRef#setInput). Column definition functions (`header`, `cell`, `footer`) are called inside [`runInInjectionContext`](https://angular.dev/api/core/runInInjectionContext), which means you can call `inject()`, use signals, and access DI tokens directly in your render logic. ## Cell rendering Prefer the shorthand directives for standard rendering: | Directive | Input | Column definition | |---|---|---| | `*flexRenderCell` | `Cell` | `columnDef.cell` | | `*flexRenderHeader` | `Header` | `columnDef.header` | | `*flexRenderFooter` | `Header` | `columnDef.footer` | Each shorthand resolves the correct column definition function and render context automatically through a `computed` signal, so no manual `props` mapping is needed. ### Example ```html
@if (!header.isPlaceholder) { {{ value }} }
{{ value }}
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
``` Any component nested inside a `[tanStackTableCell]` host can inject the cell context: ```ts import { Component } from '@angular/core' import { injectTableCellContext } from '@tanstack/angular-table' @Component({ template: ` `, }) export class CellActionsComponent { readonly cell = injectTableCellContext() onAction() { console.log('Cell:', this.cell()) } } ``` ```html ``` Each directive uses Angular's `providers` array to register a factory that reads its own input signal. This means the token is scoped to the directive's host element and its descendants. Multiple `[tanStackTableCell]` directives on different elements provide independent contexts. ### Automatic token injection in FlexRender When `FlexRender` renders a component or template, it also provides DI tokens automatically based on the render context shape. In the renderer's `#getInjector` method, if the context object contains `table`, `cell`, or `header` properties, the corresponding `TanStackTableToken`, `TanStackTableCellToken`, or `TanStackTableHeaderToken` tokens are provided in the child injector. This means that even **without** the context directives, components rendered via `*flexRender` can use `injectTableContext()`, `injectTableCellContext()`, and `injectTableHeaderContext()`. The context directives are only needed for components that live **outside** the `*flexRender` rendering tree (e.g. sibling components in the same ``). ================================================ FILE: docs/framework/angular/guide/table-composition.md ================================================ --- title: Table Composition (createTableHook) --- `createTableHook` is a convenience API for creating reusable, type-safe table configurations with pre-bound components. It is inspired by [TanStack Form's `createFormHook`](https://tanstack.com/form/latest/docs/framework/react/guides/form-composition) — a pattern where you define shared infrastructure once and consume it across your application with minimal boilerplate. > **When to use it:** Use `createTableHook` when you have multiple tables that share the same configuration (features, row models, and reusable components). For a single table, `injectTable` is sufficient. ## Examples - [Composable Tables](../examples/composable-tables) — Two tables (Users and Products) sharing the same `createTableHook` configuration, with table/cell/header components, sorting, filtering, and pagination. - [Basic App Table](../examples/basic-app-table) — Minimal example using `createTableHook` with no pre-bound components. ### createTableHook `createTableHook` centralizes your table configuration into a single factory call. It returns a set of typed functions — `injectAppTable`, `createAppColumnHelper`, and pre-typed injection helpers — that you use instead of the base APIs. ## Setup Call `createTableHook` with your shared configuration and destructure the returned utilities: ```ts // table.ts — shared table infrastructure import { createTableHook, tableFeatures, columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, } from '@tanstack/angular-table' import { PaginationControls, RowCount, TableToolbar } from './components/table-components' import { TextCell, NumberCell, StatusCell, ProgressCell } from './components/cell-components' import { SortIndicator, ColumnFilter } from './components/header-components' export const { createAppColumnHelper, injectAppTable, injectTableContext, injectTableCellContext, injectTableHeaderContext, } = createTableHook({ // Features and row models are shared across all tables _features: tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, // Default table options applied to every table getRowId: (row) => row.id, // Pre-bound component registries tableComponents: { PaginationControls, RowCount, TableToolbar, }, cellComponents: { TextCell, NumberCell, StatusCell, ProgressCell, }, headerComponents: { SortIndicator, ColumnFilter, }, }) ``` This single file becomes the source of truth for your application's table infrastructure. ## What `createTableHook` returns | Export | Description | |---|---| | `injectAppTable` | A wrapper around `injectTable` that merges default options and attaches component registries. Returns an `AppAngularTable` with table/cell/header components available directly on the instance. | | `createAppColumnHelper` | A typed column helper where `cell`, `header`, and `footer` definitions receive enhanced context types with the registered components. | | `injectTableContext` | Pre-typed `injectTableContext()` bound to your feature set. | | `injectTableCellContext` | Pre-typed `injectTableCellContext()` bound to your feature set. | | `injectTableHeaderContext` | Pre-typed `injectTableHeaderContext()` bound to your feature set. | | `injectFlexRenderCellContext` | Pre-typed `injectFlexRenderContext()` for cell context. | | `injectFlexRenderHeaderContext` | Pre-typed `injectFlexRenderContext()` for header context. | ## Component registries `createTableHook` accepts three component registries that map string keys to Angular components or render functions: ### `tableComponents` Components that need access to the **table instance**. These are attached directly to the `AppAngularTable` object returned by `injectAppTable`, so you can reference them in templates as `table.PaginationControls`, `table.RowCount`, etc. Use `injectTableContext()` inside these components to access the table: ```ts @Component({ selector: 'app-pagination-controls', template: ` `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class PaginationControls { readonly table = injectTableContext() } ``` Render table components via Angular `NgComponentOutlet`: ```html ``` ### `cellComponents` Components that render **cell content**. These are attached to the `Cell` prototype, so they are available in column definitions through the enhanced `AppCellContext`: ```ts const columnHelper = createAppColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: ({ cell }) => cell.TextCell, }), columnHelper.accessor('age', { header: 'Age', cell: ({ cell }) => cell.NumberCell, }), columnHelper.accessor('status', { header: 'Status', cell: ({ cell }) => cell.StatusCell, }), ]) ``` Use `injectTableCellContext()` or `injectFlexRenderContext()` inside cell components: ```ts @Component({ selector: 'span', template: `{{ cell().getValue() }}`, }) export class TextCell { readonly cell = injectTableCellContext() } ``` ### `headerComponents` Components or render functions that render **header/footer content**. These are attached to the `Header` prototype and available through the enhanced `AppHeaderContext`: ```ts // Render functions work too — they run in injection context export function SortIndicator(): string | null { const header = injectTableHeaderContext() const sorted = header().column.getIsSorted() if (!sorted) return null return sorted === 'asc' ? '🔼' : '🔽' } ``` Access header components in the template via `table.appHeader(header)`: ```html @for (_header of headerGroup.headers; track _header.id) { @let header = table.appHeader(_header); {{ value }}
} ``` ## Using `injectAppTable` `injectAppTable` is a wrapper around `injectTable`. It merges the default options from `createTableHook` with the per-table options, and returns an `AppAngularTable` — the standard table instance augmented with: - **Table components** directly on the table object (`table.PaginationControls`, `table.TableToolbar`, etc.) - **`table.appCell(cell)`** — utility type functions for templates that wraps a `Cell` with the registered `cellComponents` - **`table.appHeader(header)`** — utility type functions for templates that wraps a `Header` with the registered `headerComponents` - **`table.appFooter(footer)`** — utility type functions for templates that wraps a `Header` (footer) with the registered `headerComponents` You do not need to pass `_features` or `_rowModels` — they are inherited from the hook configuration: ```ts @Component({ selector: 'users-table', templateUrl: './users-table.html', imports: [FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell, NgComponentOutlet], changeDetection: ChangeDetectionStrategy.OnPush, }) export class UsersTable { readonly data = signal(makeData(100)) readonly columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: ({ cell }) => cell.TextCell, }), // ... ]) // No need to specify _features, _rowModels, ... — they come from createTableHook table = injectAppTable(() => ({ columns: this.columns, data: this.data(), })) } ``` ## Using `createAppColumnHelper` `createAppColumnHelper()` returns a column helper identical to `createColumnHelper` at runtime, but with enhanced types: the `cell`, `header`, and `footer` definition callbacks receive `AppCellContext` / `AppHeaderContext` instead of the base context types. This means TypeScript knows about your registered components and provides autocompletion: ```ts const columnHelper = createAppColumnHelper() columnHelper.accessor('firstName', { cell: ({ cell }) => { // ✅ TypeScript knows about TextCell, NumberCell, StatusCell, etc. return cell.TextCell }, header: ({ header }) => { // ✅ TypeScript knows about SortIndicator, ColumnFilter, etc. return flexRenderComponent(header.SortIndicator) }, }) ``` You can also use `flexRenderComponent(...)` to wrap the component with custom inputs/outputs: ```ts columnHelper.accessor('firstName', { cell: ({ cell }) => flexRenderComponent(cell.TextCell), footer: ({ header }) => flexRenderComponent(header.FooterColumnId), }) ``` ## Multiple table configurations You can call `createTableHook` multiple times to create different table configurations for different parts of your application. Each call returns an independent set of utilities with its own feature set and component registries: ```ts // admin-table.ts — tables with editing capabilities export const { injectAppTable: injectAdminTable, createAppColumnHelper: createAdminColumnHelper, } = createTableHook({ _features: tableFeatures({ rowSortingFeature, columnFilteringFeature }), _rowModels: { /* ... */ }, cellComponents: { EditableCell, DeleteButton }, }) // readonly-table.ts — simpler read-only tables export const { injectAppTable: injectReadonlyTable, createAppColumnHelper: createReadonlyColumnHelper, } = createTableHook({ _features: tableFeatures({ rowSortingFeature }), _rowModels: { /* ... */ }, cellComponents: { TextCell, NumberCell }, }) ``` ## Examples - [Composable Tables](../examples/composable-tables) — Full example with two tables sharing the same `createTableHook` configuration. - [Basic App Table](../examples/basic-app-table) — Minimal example with no pre-bound components. ================================================ FILE: docs/framework/angular/guide/table-state.md ================================================ --- title: Table State (Angular) Guide --- ## Table State (Angular) Guide TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table. ### Accessing Table State You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API. ```ts table = injectTable(() => ({ columns: this.columns, data: this.data(), //... })) someHandler() { console.log(this.table.store.state) //access the entire internal state console.log(this.table.store.state.rowSelection) //access just the row selection state } ``` ### Custom Initial State If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance. ```jsx table = injectTable(() => ({ columns: this.columns, data: this.data(), initialState: { columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order columnVisibility: { id: false //hide the id column by default }, expanded: true, //expand all rows by default sorting: [ { id: 'age', desc: true //sort by age in descending order by default } ] }, //... })) ``` > **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`. ### Controlled State If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options. #### Individual Controlled State You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis. In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance. Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values. ```ts import {signal} from '@angular/core'; import {SortingState, ColumnFiltersState, PaginationState} from '@tanstack/angular-table' import {toObservable} from "@angular/core/rxjs-interop"; import {combineLatest, switchMap} from 'rxjs'; class TableComponent { readonly columnFilters = signal([]) //no default filters readonly sorting = signal([ { id: 'age', desc: true, //sort by age in descending order by default } ]) readonly pagination = signal({ pageIndex: 0, pageSize: 15 }) //Use our controlled state values to fetch data readonly data$ = combineLatest({ filters: toObservable(this.columnFilters), sorting: toObservable(this.sorting), pagination: toObservable(this.pagination) }).pipe( switchMap(({filters, sorting, pagination}) => fetchData(filters, sorting, pagination)) ) readonly data = toSignal(this.data$); readonly table = injectTable(() => ({ columns: this.columns, data: this.data(), //... state: { columnFilters: this.columnFilters(), //pass controlled state back to the table (overrides internal state) sorting: this.sorting(), pagination: this.pagination(), }, onColumnFiltersChange: updater => { //hoist columnFilters state into our own state management updater instanceof Function ? this.columnFilters.update(updater) : this.columnFilters.set(updater) }, onSortingChange: updater => { updater instanceof Function ? this.sorting.update(updater) : this.sorting.set(updater) }, onPaginationChange: updater => { updater instanceof Function ? this.pagination.update(updater) : this.pagination.set(updater) }, })) } //... ``` #### Fully Controlled State Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a component tree, like `columnSizingInfo` state`, might cause bad performance issues. A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use a constructor in a special way as shown below. ```ts class TableComponent { // create an empty table state, we'll override it later readonly state = signal({} as TableState); // create a table instance with default state values readonly table = injectTable(() => ({ columns: this.columns, data: this.data(), // our fully controlled state overrides the internal state state: this.state(), onStateChange: updater => { // any state changes will be pushed up to our own state management this.state.set( updater instanceof Function ? updater(this.state()) : updater ) } })) constructor() { // set the initial table state this.state.set({ // populate the initial state with all of the default state values // from the table instance ...this.table.initialState, pagination: { pageIndex: 0, pageSize: 15, // optionally customize the initial pagination state. }, }) } } ``` ### On State Change Callbacks So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of. #### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**. Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value. ```ts class TableComponent { sorting = signal([]) table = injectTable(() => ({ columns: this.columns, data: this.data(), //... state: { sorting: this.sorting(), // required because we are using `onSortingChange` }, onSortingChange: updater => { // makes the `state.sorting` controlled updater instanceof Function ? this.sorting.update(updater) : this.sorting.set(updater) } })) } ``` #### 2. **Updaters can either be raw values or callback functions**. The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value. What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value. This is why you will see the `updater instanceof Function ? this.state.update(updater) : this.state.set(updater)` pattern in the examples above. This pattern checks if the updater is a function, and if it is, it calls the function with the previous state value to get the new state value, or the signal will require `signal.update` to be called with the updater instead of `signal.set`. ### State Types All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling. ```ts import {injectTable, type SortingState} from '@tanstack/angular-table' class TableComponent { readonly sorting = signal([ { id: 'age', // you should get autocomplete for the `id` and `desc` properties desc: true, } ]) } ``` ================================================ FILE: docs/framework/angular/reference/classes/FlexRenderCell.md ================================================ --- id: FlexRenderCell title: FlexRenderCell --- # Class: FlexRenderCell\ Defined in: [helpers/flexRenderCell.ts:62](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L62) Simplified directive wrapper of `*flexRender`. Use this utility component to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed based on the used selector. ## Examples ```html {{cell}} {{header}} {{footer}} ``` This replaces calling `*flexRender` directly like this: ```html {{cell}} {{header}} {{footer}} ``` Can be imported through FlexRenderCell or [FlexRender](../variables/FlexRender.md) import, which the latter is preferred. ```ts import {FlexRender} from '@tanstack/angular-table @Component({ // ... imports: [ FlexRender ] }) ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ## Constructors ### Constructor ```ts new FlexRenderCell(): FlexRenderCell; ``` Defined in: [helpers/flexRenderCell.ts:118](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L118) #### Returns `FlexRenderCell`\<`TFeatures`, `TData`, `TValue`\> ## Properties ### cell ```ts readonly cell: InputSignal | undefined>; ``` Defined in: [helpers/flexRenderCell.ts:67](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L67) *** ### footer ```ts readonly footer: InputSignal | undefined>; ``` Defined in: [helpers/flexRenderCell.ts:75](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L75) *** ### header ```ts readonly header: InputSignal | undefined>; ``` Defined in: [helpers/flexRenderCell.ts:71](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L71) ================================================ FILE: docs/framework/angular/reference/classes/FlexRenderComponentInstance.md ================================================ --- id: FlexRenderComponentInstance title: FlexRenderComponentInstance --- # Class: FlexRenderComponentInstance\ Defined in: [flex-render/flexRenderComponent.ts:259](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L259) Wrapper class for a component that will be used as content for [FlexRenderDirective](FlexRenderDirective.md) Prefer [flexRenderComponent](../functions/flexRenderComponent.md) helper for better type-safety ## Type Parameters ### TComponent `TComponent` = `any` ## Implements - [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md)\<`TComponent`\> ## Constructors ### Constructor ```ts new FlexRenderComponentInstance( component, inputs?, injector?, outputs?, directives?, bindings?): FlexRenderComponentInstance; ``` Defined in: [flex-render/flexRenderComponent.ts:266](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L266) #### Parameters ##### component `Type`\<`TComponent`\> ##### inputs? `Inputs`\<`TComponent`\> ##### injector? `Injector` ##### outputs? `Outputs`\<`TComponent`\> ##### directives? (`Type`\<`unknown`\> \| `DirectiveWithBindings`\<`unknown`\>)[] ##### bindings? `Binding`[] #### Returns `FlexRenderComponentInstance`\<`TComponent`\> ## Properties ### allowedInputNames ```ts readonly allowedInputNames: string[] = []; ``` Defined in: [flex-render/flexRenderComponent.ts:263](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L263) List of allowed input names. #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`allowedInputNames`](../interfaces/FlexRenderComponent.md#allowedinputnames) *** ### allowedOutputNames ```ts readonly allowedOutputNames: string[] = []; ``` Defined in: [flex-render/flexRenderComponent.ts:264](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L264) List of allowed output names. #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`allowedOutputNames`](../interfaces/FlexRenderComponent.md#allowedoutputnames) *** ### bindings? ```ts readonly optional bindings: Binding[]; ``` Defined in: [flex-render/flexRenderComponent.ts:272](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L272) Bindings to apply to the root component #### See FlexRenderOptions#bindings #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`bindings`](../interfaces/FlexRenderComponent.md#bindings) *** ### component ```ts readonly component: Type; ``` Defined in: [flex-render/flexRenderComponent.ts:267](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L267) The component type #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`component`](../interfaces/FlexRenderComponent.md#component) *** ### directives? ```ts readonly optional directives: (Type | DirectiveWithBindings)[]; ``` Defined in: [flex-render/flexRenderComponent.ts:271](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L271) Directives that should be applied to the component. #### See #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`directives`](../interfaces/FlexRenderComponent.md#directives) *** ### injector? ```ts readonly optional injector: Injector; ``` Defined in: [flex-render/flexRenderComponent.ts:269](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L269) Optional Injector that will be used when rendering the component. #### See FlexRenderOptions#injector #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`injector`](../interfaces/FlexRenderComponent.md#injector) *** ### inputs? ```ts readonly optional inputs: Inputs; ``` Defined in: [flex-render/flexRenderComponent.ts:268](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L268) Component instance inputs. Set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)) #### See FlexRenderOptions#inputs #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`inputs`](../interfaces/FlexRenderComponent.md#inputs) *** ### mirror ```ts readonly mirror: ComponentMirror; ``` Defined in: [flex-render/flexRenderComponent.ts:262](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L262) Reflected metadata about the component. #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`mirror`](../interfaces/FlexRenderComponent.md#mirror) *** ### outputs? ```ts readonly optional outputs: Outputs; ``` Defined in: [flex-render/flexRenderComponent.ts:270](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L270) Component instance outputs. Subscribed via OutputEmitterRef#subscribe #### See FlexRenderOptions#outputs #### Implementation of [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`outputs`](../interfaces/FlexRenderComponent.md#outputs) ================================================ FILE: docs/framework/angular/reference/classes/FlexRenderDirective.md ================================================ --- id: FlexRenderDirective title: FlexRenderDirective --- # Class: FlexRenderDirective\ Defined in: [flexRender.ts:84](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L84) Use this utility directive to render headers, cells, or footers with custom markup. Note: If you are rendering cell, header, or footer without custom context or other props, you can use the [FlexRenderCell](FlexRenderCell.md) directive as shorthand instead . ## Example ```ts import {FlexRender} from '@tanstack/angular-table'; @Component({ imports: [FlexRender], template: ` {{cell}} {{header}} {{footer}} `, }) class App { } ``` Can be imported through FlexRenderDirective or [FlexRender](../variables/FlexRender.md) import, which the latter is preferred. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TRowData `TRowData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### TProps `TProps` *extends* \| `NonNullable`\<`unknown`\> \| `CellContext`\<`TFeatures`, `TRowData`, `TValue`\> \| `HeaderContext`\<`TFeatures`, `TRowData`, `TValue`\> ## Constructors ### Constructor ```ts new FlexRenderDirective(): FlexRenderDirective; ``` Defined in: [flexRender.ts:109](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L109) #### Returns `FlexRenderDirective`\<`TFeatures`, `TRowData`, `TValue`, `TProps`\> ## Properties ### content ```ts readonly content: InputSignal>; ``` Defined in: [flexRender.ts:93](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L93) *** ### injector ```ts readonly injector: InputSignal; ``` Defined in: [flexRender.ts:102](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L102) *** ### props ```ts readonly props: InputSignal; ``` Defined in: [flexRender.ts:98](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L98) ================================================ FILE: docs/framework/angular/reference/classes/TanStackTable.md ================================================ --- id: TanStackTable title: TanStackTable --- # Class: TanStackTable\ Defined in: [helpers/table.ts:59](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L59) Provides a TanStack Table instance (`AngularTable`) in Angular DI. The table can be injected by: - any descendant of an element using `[tanStackTable]="..."` - any component instantiated by `*flexRender` when the render props contains `table` ## Example ```html
``` ```ts @Component({ selector: 'app-pagination', template: ` `, }) export class PaginationComponent { readonly table = injectTableContext() prev() { this.table().previousPage() } next() { this.table().nextPage() } } ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` *extends* `object` = `TableState`\<`TFeatures`\> ## Constructors ### Constructor ```ts new TanStackTable(): TanStackTable; ``` #### Returns `TanStackTable`\<`TFeatures`, `TData`, `TSelected`\> ## Properties ### table ```ts readonly table: InputSignal>; ``` Defined in: [helpers/table.ts:69](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L69) The current TanStack Table instance. Provided as a required signal input so DI consumers always read the latest value. ================================================ FILE: docs/framework/angular/reference/classes/TanStackTableCell.md ================================================ --- id: TanStackTableCell title: TanStackTableCell --- # Class: TanStackTableCell\ Defined in: [helpers/cell.ts:76](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L76) Provides a TanStack Table `Cell` instance in Angular DI. The cell can be injected by: - any descendant of an element using `[tanStackTableCell]="..."` - any component instantiated by `*flexRender` when the render props contains `cell` ## Examples Inject from the nearest `[tanStackTableCell]`: ```html ``` ```ts @Component({ selector: 'app-cell-actions', template: `{{ cell().id }}`, }) export class CellActionsComponent { readonly cell = injectTableCellContext() } ``` Inject inside a component rendered via `flexRender`: ```ts @Component({ selector: 'app-price-cell', template: `{{ cell().getValue() }}`, }) export class PriceCellComponent { readonly cell = injectTableCellContext() } ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ## Implements - [`TanStackTableCellContext`](../interfaces/TanStackTableCellContext.md)\<`TFeatures`, `TData`, `TValue`\> ## Constructors ### Constructor ```ts new TanStackTableCell(): TanStackTableCell; ``` #### Returns `TanStackTableCell`\<`TFeatures`, `TData`, `TValue`\> ## Properties ### cell ```ts readonly cell: InputSignal>; ``` Defined in: [helpers/cell.ts:86](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L86) The current TanStack Table cell. Provided as a required signal input so DI consumers always read the latest value. #### Implementation of [`TanStackTableCellContext`](../interfaces/TanStackTableCellContext.md).[`cell`](../interfaces/TanStackTableCellContext.md#cell) ================================================ FILE: docs/framework/angular/reference/classes/TanStackTableHeader.md ================================================ --- id: TanStackTableHeader title: TanStackTableHeader --- # Class: TanStackTableHeader\ Defined in: [helpers/header.ts:71](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L71) Provides a TanStack Table `Header` instance in Angular DI. The header can be injected by: - any descendant of an element using `[tanStackTableHeader]="..."` - any component instantiated by `*flexRender` when the render props contains `header` ## Example ```html ``` ```ts @Component({ selector: 'app-sort-indicator', template: ` `, }) export class SortIndicatorComponent { readonly header = injectTableHeaderContext() toggle() { this.header().column.toggleSorting() } } ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ## Implements - [`TanStackTableHeaderContext`](../interfaces/TanStackTableHeaderContext.md)\<`TFeatures`, `TData`, `TValue`\> ## Constructors ### Constructor ```ts new TanStackTableHeader(): TanStackTableHeader; ``` #### Returns `TanStackTableHeader`\<`TFeatures`, `TData`, `TValue`\> ## Properties ### header ```ts readonly header: InputSignal>; ``` Defined in: [helpers/header.ts:81](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L81) The current TanStack Table header. Provided as a required signal input so DI consumers always read the latest value. #### Implementation of [`TanStackTableHeaderContext`](../interfaces/TanStackTableHeaderContext.md).[`header`](../interfaces/TanStackTableHeaderContext.md#header) ================================================ FILE: docs/framework/angular/reference/functions/createTableHook.md ================================================ --- id: createTableHook title: createTableHook --- # Function: createTableHook() ```ts function createTableHook(__namedParameters): CreateTableHookResult; ``` Defined in: [helpers/createTableHook.ts:352](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L352) ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ## Parameters ### \_\_namedParameters [`CreateTableContextOptions`](../type-aliases/CreateTableContextOptions.md)\<`TFeatures`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\> ## Returns [`CreateTableHookResult`](../type-aliases/CreateTableHookResult.md)\<`TFeatures`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\> ================================================ FILE: docs/framework/angular/reference/functions/flexRenderComponent.md ================================================ --- id: flexRenderComponent title: flexRenderComponent --- # Function: flexRenderComponent() ```ts function flexRenderComponent(component, options?): FlexRenderComponent; ``` Defined in: [flex-render/flexRenderComponent.ts:150](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L150) Helper function to create a [FlexRenderComponent](../interfaces/FlexRenderComponent.md) instance, with better type-safety. ## Type Parameters ### TComponent `TComponent` = `any` ## Parameters ### component `Type`\<`TComponent`\> ### options? `FlexRenderOptions`\<`Inputs`\<`TComponent`\>, `Outputs`\<`TComponent`\>\> ## Returns [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md)\<`TComponent`\> ## Example ```ts import {flexRenderComponent} from '@tanstack/angular-table' import {inputBinding, outputBinding} from '@angular/core'; const columns = [ { cell: ({ row }) => { return flexRenderComponent(MyComponent, { inputs: { value: mySignalValue() }, outputs: { valueChange: (val) => {} } // or using angular native createComponent#binding api bindings: [ inputBinding('value', mySignalValue), outputBinding('valueChange', value => { console.log("my value changed to", value) }) ] }) }, }, ] ``` ================================================ FILE: docs/framework/angular/reference/functions/injectFlexRenderContext.md ================================================ --- id: injectFlexRenderContext title: injectFlexRenderContext --- # Function: injectFlexRenderContext() ```ts function injectFlexRenderContext(): T; ``` Defined in: [flex-render/context.ts:12](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/context.ts#L12) Inject the flex render context props. Can be used in components rendered via FlexRender directives. ## Type Parameters ### T `T` *extends* `object` ## Returns `T` ================================================ FILE: docs/framework/angular/reference/functions/injectTable.md ================================================ --- id: injectTable title: injectTable --- # Function: injectTable() ```ts function injectTable(options, selector): AngularTable; ``` Defined in: [injectTable.ts:95](https://github.com/TanStack/table/blob/main/packages/angular-table/src/injectTable.ts#L95) Creates and returns an Angular-reactive table instance. The initializer is intentionally re-evaluated whenever any signal read inside it changes. This is how the adapter keeps the table in sync with Angular's reactivity model. Because of that behavior, keep expensive/static values (for example `columns`, feature setup, row models) as stable references outside the initializer, and only read reactive state (`data()`, pagination/filter/sorting signals, etc.) inside it. The returned table is also signal-reactive: table state and table APIs are wired for Angular signals, so you can safely consume table methods inside `computed(...)` and `effect(...)`. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` = `TableState`\<`TFeatures`\> ## Parameters ### options () => `TableOptions`\<`TFeatures`, `TData`\> ### selector (`state`) => `TSelected` ## Returns [`AngularTable`](../type-aliases/AngularTable.md)\<`TFeatures`, `TData`, `TSelected`\> An Angular-reactive TanStack Table instance. ## Example 1. Register the table features you need ```ts // Register only the features you need import {tableFeatures, rowPaginationFeature} from '@tanstack/angular-table'; const _features = tableFeatures({ rowPaginationFeature, // ...all other features you need }) // Use all table core features import {stockFeatures} from '@tanstack/angular-table'; const _features = tableFeatures(stockFeatures); ``` 2. Prepare the table columns ```ts import {ColumnDef} from '@tanstack/angular-table'; type MyData = {} const columns: ColumnDef[] = [ // ...column definitions ] // or using createColumnHelper import {createColumnHelper} from '@tanstack/angular-table'; const columnHelper = createColumnHelper(); const columns = columnHelper.columns([ columnHelper.accessor(...), // ...other columns ]) ``` 3. Create the table instance with `injectTable` ```ts const table = injectTable(() => { // ...table options, _features, columns: columns, data: myDataSignal(), }) ``` ================================================ FILE: docs/framework/angular/reference/functions/injectTableCellContext.md ================================================ --- id: injectTableCellContext title: injectTableCellContext --- # Function: injectTableCellContext() ```ts function injectTableCellContext(): Signal>; ``` Defined in: [helpers/cell.ts:98](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L98) Injects the current TanStack Table cell signal. Available when: - there is a nearest `[tanStackTableCell]` directive in the DI tree, or - the caller is rendered via `*flexRender` with render props containing `cell` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `unknown` ## Returns `Signal`\<`Cell`\<`TFeatures`, `TData`, `TValue`\>\> ================================================ FILE: docs/framework/angular/reference/functions/injectTableContext.md ================================================ --- id: injectTableContext title: injectTableContext --- # Function: injectTableContext() ```ts function injectTableContext(): Signal>; ``` Defined in: [helpers/table.ts:81](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L81) Injects the current TanStack Table instance signal. Available when: - there is a nearest `[tanStackTable]` directive in the DI tree, or - the caller is rendered via `*flexRender` with render props containing `table` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` *extends* `object` = `TableState`\<`TFeatures`\> ## Returns `Signal`\<[`AngularTable`](../type-aliases/AngularTable.md)\<`TFeatures`, `TData`, `TSelected`\>\> ================================================ FILE: docs/framework/angular/reference/functions/injectTableHeaderContext.md ================================================ --- id: injectTableHeaderContext title: injectTableHeaderContext --- # Function: injectTableHeaderContext() ```ts function injectTableHeaderContext(): Signal>; ``` Defined in: [helpers/header.ts:93](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L93) Injects the current TanStack Table header signal. Available when: - there is a nearest `[tanStackTableHeader]` directive in the DI tree, or - the caller is rendered via `*flexRender` with render props containing `header` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `unknown` ## Returns `Signal`\<`Header`\<`TFeatures`, `TData`, `TValue`\>\> ================================================ FILE: docs/framework/angular/reference/index.md ================================================ --- id: "@tanstack/angular-table" title: "@tanstack/angular-table" --- # @tanstack/angular-table ## Classes - [FlexRenderCell](classes/FlexRenderCell.md) - [FlexRenderComponentInstance](classes/FlexRenderComponentInstance.md) - [FlexRenderDirective](classes/FlexRenderDirective.md) - [TanStackTable](classes/TanStackTable.md) - [TanStackTableCell](classes/TanStackTableCell.md) - [TanStackTableHeader](classes/TanStackTableHeader.md) ## Interfaces - [AngularReactivityFlags](interfaces/AngularReactivityFlags.md) - [FlexRenderComponent](interfaces/FlexRenderComponent.md) - [TanStackTableCellContext](interfaces/TanStackTableCellContext.md) - [TanStackTableHeaderContext](interfaces/TanStackTableHeaderContext.md) ## Type Aliases - [AngularTable](type-aliases/AngularTable.md) - [AppAngularTable](type-aliases/AppAngularTable.md) - [AppCellContext](type-aliases/AppCellContext.md) - [AppColumnHelper](type-aliases/AppColumnHelper.md) - [AppHeaderContext](type-aliases/AppHeaderContext.md) - [CreateTableContextOptions](type-aliases/CreateTableContextOptions.md) - [CreateTableHookResult](type-aliases/CreateTableHookResult.md) - [FlexRenderComponentProps](type-aliases/FlexRenderComponentProps.md) - [FlexRenderContent](type-aliases/FlexRenderContent.md) - [FlexRenderInputContent](type-aliases/FlexRenderInputContent.md) ## Variables - [FlexRender](variables/FlexRender.md) - [TanStackTableCellToken](variables/TanStackTableCellToken.md) - [TanStackTableHeaderToken](variables/TanStackTableHeaderToken.md) - [TanStackTableToken](variables/TanStackTableToken.md) ## Functions - [createTableHook](functions/createTableHook.md) - [flexRenderComponent](functions/flexRenderComponent.md) - [injectFlexRenderContext](functions/injectFlexRenderContext.md) - [injectTable](functions/injectTable.md) - [injectTableCellContext](functions/injectTableCellContext.md) - [injectTableContext](functions/injectTableContext.md) - [injectTableHeaderContext](functions/injectTableHeaderContext.md) ================================================ FILE: docs/framework/angular/reference/interfaces/AngularReactivityFlags.md ================================================ --- id: AngularReactivityFlags title: AngularReactivityFlags --- # Interface: AngularReactivityFlags Defined in: [angularReactivityFeature.ts:55](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L55) Fine-grained configuration for Angular reactivity. Each key controls whether prototype methods/getters on the corresponding TanStack Table objects are wrapped with signal-aware access. - `true` enables wrapping using the default skip rules. - `false` disables wrapping entirely for that object type. - a function allows customizing the skip rules (see SkipPropertyFn). ## Example ```ts const table = injectTable(() => { // ...table options, reactivity: { // fine-grained control over which table objects have reactive properties, // and which properties are wrapped header: true, column: true, row: true, cell: true, } }) ``` ## Properties ### cell ```ts cell: boolean | SkipPropertyFn; ``` Defined in: [angularReactivityFeature.ts:63](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L63) Controls reactive wrapping for `Cell` instances. *** ### column ```ts column: boolean | SkipPropertyFn; ``` Defined in: [angularReactivityFeature.ts:59](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L59) Controls reactive wrapping for `Column` instances. *** ### header ```ts header: boolean | SkipPropertyFn; ``` Defined in: [angularReactivityFeature.ts:57](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L57) Controls reactive wrapping for `Header` instances. *** ### row ```ts row: boolean | SkipPropertyFn; ``` Defined in: [angularReactivityFeature.ts:61](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L61) Controls reactive wrapping for `Row` instances. ================================================ FILE: docs/framework/angular/reference/interfaces/FlexRenderComponent.md ================================================ --- id: FlexRenderComponent title: FlexRenderComponent --- # Interface: FlexRenderComponent\ Defined in: [flex-render/flexRenderComponent.ts:205](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L205) Wrapper interface for a component that will be used as content for [FlexRenderDirective](../classes/FlexRenderDirective.md). Can be created using [flexRenderComponent](../functions/flexRenderComponent.md) helper. ## Example ```ts import {flexRenderComponent} from '@tanstack/angular-table' // Usage in cell/header/footer definition const columns = [ { cell: ({ row }) => { return flexRenderComponent(MyComponent, { inputs: { value: mySignalValue() }, outputs: { valueChange: (val) => {} } // or using angular createComponent#bindings api bindings: [ inputBinding('value', mySignalValue), outputBinding('valueChange', value => { console.log("my value changed to", value) }) ] }) }, }, ] import {input, output} from '@angular/core'; @Component({ selector: 'my-component', }) class MyComponent { readonly value = input(0); readonly valueChange = output(); } ``` ## Type Parameters ### TComponent `TComponent` = `any` ## Properties ### allowedInputNames ```ts readonly allowedInputNames: string[]; ``` Defined in: [flex-render/flexRenderComponent.ts:217](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L217) List of allowed input names. *** ### allowedOutputNames ```ts readonly allowedOutputNames: string[]; ``` Defined in: [flex-render/flexRenderComponent.ts:221](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L221) List of allowed output names. *** ### bindings? ```ts optional bindings: Binding[]; ``` Defined in: [flex-render/flexRenderComponent.ts:245](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L245) Bindings to apply to the root component #### See FlexRenderOptions#bindings *** ### component ```ts readonly component: Type; ``` Defined in: [flex-render/flexRenderComponent.ts:209](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L209) The component type *** ### directives? ```ts optional directives: (Type | DirectiveWithBindings)[]; ``` Defined in: [flex-render/flexRenderComponent.ts:251](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L251) Directives that should be applied to the component. #### See *** ### injector? ```ts readonly optional injector: Injector; ``` Defined in: [flex-render/flexRenderComponent.ts:239](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L239) Optional Injector that will be used when rendering the component. #### See FlexRenderOptions#injector *** ### inputs? ```ts readonly optional inputs: Inputs; ``` Defined in: [flex-render/flexRenderComponent.ts:233](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L233) Component instance inputs. Set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)) #### See FlexRenderOptions#inputs *** ### mirror ```ts readonly mirror: ComponentMirror; ``` Defined in: [flex-render/flexRenderComponent.ts:213](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L213) Reflected metadata about the component. *** ### outputs? ```ts readonly optional outputs: Outputs; ``` Defined in: [flex-render/flexRenderComponent.ts:227](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L227) Component instance outputs. Subscribed via OutputEmitterRef#subscribe #### See FlexRenderOptions#outputs ================================================ FILE: docs/framework/angular/reference/interfaces/TanStackTableCellContext.md ================================================ --- id: TanStackTableCellContext title: TanStackTableCellContext --- # Interface: TanStackTableCellContext\ Defined in: [helpers/cell.ts:11](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L11) DI context shape for a TanStack Table cell. This exists to make the current `Cell` injectable by any nested component/directive without having to pass it through inputs/props manually. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ## Properties ### cell ```ts cell: Signal>; ``` Defined in: [helpers/cell.ts:17](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L17) Signal that returns the current cell instance. ================================================ FILE: docs/framework/angular/reference/interfaces/TanStackTableHeaderContext.md ================================================ --- id: TanStackTableHeaderContext title: TanStackTableHeaderContext --- # Interface: TanStackTableHeaderContext\ Defined in: [helpers/header.ts:11](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L11) DI context shape for a TanStack Table header. This exists to make the current `Header` injectable by any nested component/directive without passing it through inputs/props. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ## Properties ### header ```ts header: Signal>; ``` Defined in: [helpers/header.ts:17](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L17) Signal that returns the current header instance. ================================================ FILE: docs/framework/angular/reference/type-aliases/AngularTable.md ================================================ --- id: AngularTable title: AngularTable --- # Type Alias: AngularTable\ ```ts type AngularTable = Table & object; ``` Defined in: [injectTable.ts:21](https://github.com/TanStack/table/blob/main/packages/angular-table/src/injectTable.ts#L21) ## Type Declaration ### state ```ts readonly state: Signal>; ``` The selected state from the table store, based on the selector provided. ### Subscribe() ```ts Subscribe: (props) => Signal>; ``` Subscribe to changes in the table store with a custom selector. #### Type Parameters ##### TSubSelected `TSubSelected` = \{ \} #### Parameters ##### props ###### equal? `ValueEqualityFn`\<`TSubSelected`\> ###### selector (`state`) => `TSubSelected` #### Returns `Signal`\<`Readonly`\<`TSubSelected`\>\> ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` = `TableState`\<`TFeatures`\> ================================================ FILE: docs/framework/angular/reference/type-aliases/AppAngularTable.md ================================================ --- id: AppAngularTable title: AppAngularTable --- # Type Alias: AppAngularTable\ ```ts type AppAngularTable = AngularTable & NoInfer & object; ``` Defined in: [helpers/createTableHook.ts:243](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L243) Extended table API returned by useAppTable with all App wrapper components ## Type Declaration ### appCell() ```ts appCell: (cell) => Cell & NoInfer; ``` #### Type Parameters ##### TValue `TValue` #### Parameters ##### cell `Cell`\<`TFeatures`, `TData`, `TValue`\> #### Returns `Cell`\<`TFeatures`, `TData`, `TValue`\> & `NoInfer`\<`TCellComponents`\> ### appFooter() ```ts appFooter: (footer) => Header & NoInfer; ``` #### Type Parameters ##### TValue `TValue` #### Parameters ##### footer `Header`\<`TFeatures`, `TData`, `TValue`\> #### Returns `Header`\<`TFeatures`, `TData`, `TValue`\> & `NoInfer`\<`THeaderComponents`\> ### appHeader() ```ts appHeader: (header) => Header & NoInfer; ``` #### Type Parameters ##### TValue `TValue` #### Parameters ##### header `Header`\<`TFeatures`, `TData`, `TValue`\> #### Returns `Header`\<`TFeatures`, `TData`, `TValue`\> & `NoInfer`\<`THeaderComponents`\> ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ================================================ FILE: docs/framework/angular/reference/type-aliases/AppCellContext.md ================================================ --- id: AppCellContext title: AppCellContext --- # Type Alias: AppCellContext\ ```ts type AppCellContext = object; ``` Defined in: [helpers/createTableHook.ts:47](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L47) Enhanced CellContext with pre-bound cell components. The `cell` property includes the registered cellComponents. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ## Properties ### cell ```ts cell: Cell & TCellComponents & object; ``` Defined in: [helpers/createTableHook.ts:53](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L53) #### Type Declaration ##### FlexRender() ```ts FlexRender: () => unknown; ``` ###### Returns `unknown` *** ### column ```ts column: Column; ``` Defined in: [helpers/createTableHook.ts:55](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L55) *** ### getValue ```ts getValue: CellContext["getValue"]; ``` Defined in: [helpers/createTableHook.ts:56](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L56) *** ### renderValue ```ts renderValue: CellContext["renderValue"]; ``` Defined in: [helpers/createTableHook.ts:57](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L57) *** ### row ```ts row: Row; ``` Defined in: [helpers/createTableHook.ts:58](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L58) *** ### table ```ts table: Table; ``` Defined in: [helpers/createTableHook.ts:59](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L59) ================================================ FILE: docs/framework/angular/reference/type-aliases/AppColumnHelper.md ================================================ --- id: AppColumnHelper title: AppColumnHelper --- # Type Alias: AppColumnHelper\ ```ts type AppColumnHelper = object; ``` Defined in: [helpers/createTableHook.ts:168](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L168) Enhanced column helper with pre-bound components in cell/header/footer contexts. This enables TypeScript to know about the registered components when defining columns. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ## Properties ### accessor() ```ts accessor: (accessor, column) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef; ``` Defined in: [helpers/createTableHook.ts:178](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L178) Creates a data column definition with an accessor key or function. The cell, header, and footer contexts include pre-bound components. #### Type Parameters ##### TAccessor `TAccessor` *extends* `AccessorFn`\<`TData`\> \| `DeepKeys`\<`TData`\> ##### TValue `TValue` *extends* `TAccessor` *extends* `AccessorFn`\<`TData`, infer TReturn\> ? `TReturn` : `TAccessor` *extends* `DeepKeys`\<`TData`\> ? `DeepValue`\<`TData`, `TAccessor`\> : `never` #### Parameters ##### accessor `TAccessor` ##### column `TAccessor` *extends* `AccessorFn`\<`TData`\> ? `AppColumnDefBase`\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `THeaderComponents`\> & `object` : `AppColumnDefBase`\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `THeaderComponents`\> #### Returns `TAccessor` *extends* `AccessorFn`\<`TData`\> ? `AccessorFnColumnDef`\<`TFeatures`, `TData`, `TValue`\> : `AccessorKeyColumnDef`\<`TFeatures`, `TData`, `TValue`\> *** ### columns() ```ts columns: (columns) => ColumnDef[] & [...TColumns]; ``` Defined in: [helpers/createTableHook.ts:209](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L209) Wraps an array of column definitions to preserve each column's individual TValue type. #### Type Parameters ##### TColumns `TColumns` *extends* `ReadonlyArray`\<`ColumnDef`\<`TFeatures`, `TData`, `any`\>\> #### Parameters ##### columns \[`...TColumns`\] #### Returns `ColumnDef`\<`TFeatures`, `TData`, `any`\>[] & \[`...TColumns`\] *** ### display() ```ts display: (column) => DisplayColumnDef; ``` Defined in: [helpers/createTableHook.ts:217](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L217) Creates a display column definition for non-data columns. The cell, header, and footer contexts include pre-bound components. #### Parameters ##### column `AppDisplayColumnDef`\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\> #### Returns `DisplayColumnDef`\<`TFeatures`, `TData`, `unknown`\> *** ### group() ```ts group: (column) => GroupColumnDef; ``` Defined in: [helpers/createTableHook.ts:230](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L230) Creates a group column definition with nested child columns. The cell, header, and footer contexts include pre-bound components. #### Parameters ##### column `AppGroupColumnDef`\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\> #### Returns `GroupColumnDef`\<`TFeatures`, `TData`, `unknown`\> ================================================ FILE: docs/framework/angular/reference/type-aliases/AppHeaderContext.md ================================================ --- id: AppHeaderContext title: AppHeaderContext --- # Type Alias: AppHeaderContext\ ```ts type AppHeaderContext = object; ``` Defined in: [helpers/createTableHook.ts:66](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L66) Enhanced HeaderContext with pre-bound header components. The `header` property includes the registered headerComponents. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ## Properties ### column ```ts column: Column; ``` Defined in: [helpers/createTableHook.ts:72](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L72) *** ### header ```ts header: Header & THeaderComponents & object; ``` Defined in: [helpers/createTableHook.ts:73](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L73) #### Type Declaration ##### FlexRender() ```ts FlexRender: () => unknown; ``` ###### Returns `unknown` *** ### table ```ts table: Table; ``` Defined in: [helpers/createTableHook.ts:75](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L75) ================================================ FILE: docs/framework/angular/reference/type-aliases/CreateTableContextOptions.md ================================================ --- id: CreateTableContextOptions title: CreateTableContextOptions --- # Type Alias: CreateTableContextOptions\ ```ts type CreateTableContextOptions = Omit, "columns" | "data" | "store" | "state" | "initialState"> & object; ``` Defined in: [helpers/createTableHook.ts:273](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L273) Options for creating a table hook with pre-bound components and default table options. Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. ## Type Declaration ### cellComponents? ```ts optional cellComponents: TCellComponents; ``` Cell-level components that need access to the cell instance. These are available on the cell object passed to AppCell's children. Use `useCellContext()` inside these components. #### Example ```ts { TextCell, NumberCell, DateCell, CurrencyCell } ``` ### headerComponents? ```ts optional headerComponents: THeaderComponents; ``` Header-level components that need access to the header instance. These are available on the header object passed to AppHeader/AppFooter's children. Use `useHeaderContext()` inside these components. #### Example ```ts { SortIndicator, ColumnFilter, ResizeHandle } ``` ### tableComponents? ```ts optional tableComponents: TTableComponents; ``` Table-level components that need access to the table instance. These are available directly on the table object returned by useAppTable. Use `useTableContext()` inside these components. #### Example ```ts { PaginationControls, GlobalFilter, RowCount } ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ================================================ FILE: docs/framework/angular/reference/type-aliases/CreateTableHookResult.md ================================================ --- id: CreateTableHookResult title: CreateTableHookResult --- # Type Alias: CreateTableHookResult\ ```ts type CreateTableHookResult = object; ``` Defined in: [helpers/createTableHook.ts:305](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L305) ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\> ## Properties ### createAppColumnHelper() ```ts createAppColumnHelper: () => AppColumnHelper; ``` Defined in: [helpers/createTableHook.ts:311](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L311) #### Type Parameters ##### TData `TData` *extends* `RowData` #### Returns [`AppColumnHelper`](AppColumnHelper.md)\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\> *** ### injectAppTable() ```ts injectAppTable: (tableOptions, selector?) => AppAngularTable; ``` Defined in: [helpers/createTableHook.ts:336](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L336) #### Type Parameters ##### TData `TData` *extends* `RowData` ##### TSelected `TSelected` = `TableState`\<`TFeatures`\> #### Parameters ##### tableOptions () => `Omit`\<`TableOptions`\<`TFeatures`, `TData`\>, `"_features"` \| `"_rowModels"`\> ##### selector? (`state`) => `TSelected` #### Returns [`AppAngularTable`](AppAngularTable.md)\<`TFeatures`, `TData`, `TSelected`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\> *** ### injectFlexRenderCellContext() ```ts injectFlexRenderCellContext: () => CellContext; ``` Defined in: [helpers/createTableHook.ts:332](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L332) #### Type Parameters ##### TData `TData` *extends* `RowData` ##### TValue `TValue` *extends* `CellData` #### Returns `CellContext`\<`TFeatures`, `TData`, `TValue`\> *** ### injectFlexRenderHeaderContext() ```ts injectFlexRenderHeaderContext: () => HeaderContext; ``` Defined in: [helpers/createTableHook.ts:328](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L328) #### Type Parameters ##### TData `TData` *extends* `RowData` ##### TValue `TValue` *extends* `CellData` #### Returns `HeaderContext`\<`TFeatures`, `TData`, `TValue`\> *** ### injectTableCellContext() ```ts injectTableCellContext: () => Signal>; ``` Defined in: [helpers/createTableHook.ts:324](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L324) #### Type Parameters ##### TValue `TValue` *extends* `CellData` = `CellData` ##### TRowData `TRowData` *extends* `RowData` = `RowData` #### Returns `Signal`\<`Cell`\<`TFeatures`, `TRowData`, `TValue`\>\> *** ### injectTableContext() ```ts injectTableContext: () => Signal>; ``` Defined in: [helpers/createTableHook.ts:317](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L317) #### Type Parameters ##### TData `TData` *extends* `RowData` = `RowData` #### Returns `Signal`\<[`AngularTable`](AngularTable.md)\<`TFeatures`, `TData`\>\> *** ### injectTableHeaderContext() ```ts injectTableHeaderContext: () => Signal>; ``` Defined in: [helpers/createTableHook.ts:320](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L320) #### Type Parameters ##### TValue `TValue` *extends* `CellData` = `CellData` ##### TRowData `TRowData` *extends* `RowData` = `RowData` #### Returns `Signal`\<`Header`\<`TFeatures`, `TRowData`, `TValue`\>\> ================================================ FILE: docs/framework/angular/reference/type-aliases/FlexRenderComponentProps.md ================================================ --- id: FlexRenderComponentProps title: FlexRenderComponentProps --- # Type Alias: FlexRenderComponentProps ```ts type FlexRenderComponentProps = InjectionToken<{ }>; ``` Defined in: [flex-render/context.ts:3](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/context.ts#L3) ================================================ FILE: docs/framework/angular/reference/type-aliases/FlexRenderContent.md ================================================ --- id: FlexRenderContent title: FlexRenderContent --- # Type Alias: FlexRenderContent\ ```ts type FlexRenderContent = | string | number | Type | FlexRenderComponent | TemplateRef<{ $implicit: TProps; }> | null | Record | undefined; ``` Defined in: [flex-render/renderer.ts:40](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/renderer.ts#L40) Content supported by the `flexRender` directive when declaring a table column header/cell. ## Type Parameters ### TProps `TProps` *extends* `NonNullable`\<`unknown`\> ================================================ FILE: docs/framework/angular/reference/type-aliases/FlexRenderInputContent.md ================================================ --- id: FlexRenderInputContent title: FlexRenderInputContent --- # Type Alias: FlexRenderInputContent\ ```ts type FlexRenderInputContent = | number | string | (props) => FlexRenderContent | null | undefined; ``` Defined in: [flex-render/renderer.ts:53](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/renderer.ts#L53) Input content supported by the `flexRender` directives. ## Type Parameters ### TProps `TProps` *extends* `NonNullable`\<`unknown`\> ================================================ FILE: docs/framework/angular/reference/variables/FlexRender.md ================================================ --- id: FlexRender title: FlexRender --- # Variable: FlexRender ```ts const FlexRender: readonly [typeof FlexRenderDirective, typeof FlexRenderCell]; ``` Defined in: [index.ts:25](https://github.com/TanStack/table/blob/main/packages/angular-table/src/index.ts#L25) Constant helper to import FlexRender directives. You should prefer to use this constant over importing the directives separately, as it ensures you always have the correct set of directives over library updates. ## See [FlexRenderDirective](../classes/FlexRenderDirective.md) and [FlexRenderCell](../classes/FlexRenderCell.md) for more details on the directives included in this export. ================================================ FILE: docs/framework/angular/reference/variables/TanStackTableCellToken.md ================================================ --- id: TanStackTableCellToken title: TanStackTableCellToken --- # Variable: TanStackTableCellToken ```ts const TanStackTableCellToken: InjectionToken>; ``` Defined in: [helpers/cell.ts:25](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L25) Injection token that provides access to the current cell. This token is provided by the [TanStackTableCell](../classes/TanStackTableCell.md) directive. ================================================ FILE: docs/framework/angular/reference/variables/TanStackTableHeaderToken.md ================================================ --- id: TanStackTableHeaderToken title: TanStackTableHeaderToken --- # Variable: TanStackTableHeaderToken ```ts const TanStackTableHeaderToken: InjectionToken>; ``` Defined in: [helpers/header.ts:25](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L25) Injection token that provides access to the current header. This token is provided by the [TanStackTableHeader](../classes/TanStackTableHeader.md) directive. ================================================ FILE: docs/framework/angular/reference/variables/TanStackTableToken.md ================================================ --- id: TanStackTableToken title: TanStackTableToken --- # Variable: TanStackTableToken ```ts const TanStackTableToken: InjectionToken>; ``` Defined in: [helpers/table.ts:11](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L11) Injection token that provides access to the current [AngularTable](../type-aliases/AngularTable.md) instance. This token is provided by the [TanStackTable](../classes/TanStackTable.md) directive. ================================================ FILE: docs/framework/lit/guide/table-state.md ================================================ --- title: Table State (Lit) Guide --- ## Table State (Lit) Guide TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table. ### Accessing Table State You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API. ```ts private tableController = new TableController(this); render() { const table = this.tableController.table({ columns, data, ... }) console.log(table.store.state) //access the entire internal state console.log(table.store.state.rowSelection) //access just the row selection state // ... } ``` ### Custom Initial State If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance. ```ts render() { const table = this.tableController.table({ columns, data, initialState: { columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order columnVisibility: { id: false //hide the id column by default }, expanded: true, //expand all rows by default sorting: [ { id: 'age', desc: true //sort by age in descending order by default } ] }, }) return html`...`; } ``` > **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`. ### Controlled State If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options. #### Individual Controlled State You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis. In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance. Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values. ```jsx import {html} from "lit"; @customElement('my-component') class MyComponent extends LitElement { @state() private _sorting: SortingState = [] render() { const table = this.tableController.table({ columns, data, state: { sorting: this._sorting, }, onSortingChange: updaterOrValue => { if (typeof updaterOrValue === 'function') { this._sorting = updaterOrValue(this._sorting) } else { this._sorting = updaterOrValue } }, getSortedRowModel: createSortedRowModel(sortFns), getCoreRowModel: createCoreRowModel(), }) return html`...` } } //... ``` #### Fully Controlled State Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a component tree, like `columnSizingInfo` state`, might cause bad performance issues. A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below. ```ts private tableController = new TableController(this); @state() private _tableState; render() { const table = this.tableController.table({ columns, data, getCoreRowModel: createCoreRowModel(), getSortedRowModel: createSortedRowModel(sortFns) }) const state = { ...table.initialState, ...this.tableState }; table.setOptions(prev => ({ ...prev, state, onStateChange: updater => { this.tableState = updater instanceof Function ? updater(state) : updater //any state changes will be pushed up to our own state management }, })) return html`...`; } ``` ### On State Change Callbacks So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of. #### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**. Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value. ```jsx @state() private _sorting = []; //... render() { const table = this.tableController.table({ columns, data, state: { sorting: this._sorting, }, onSortingChange: updaterOrValue => { if (typeof updaterOrValue === 'function') { this._sorting = updaterOrValue(this._sorting) } else { this._sorting = updaterOrValue } }, getSortedRowModel: createSortedRowModel(sortFns), getCoreRowModel: createCoreRowModel(), }) return html`...`; } ``` #### 2. **Updaters can either be raw values or callback functions**. The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value. What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value. This is why you will see the `updater instanceof Function ? updater(state.value) : updater` pattern in the examples above. This pattern checks if the updater is a function, and if it is, it calls the function with the previous state value to get the new state value. ### State Types All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling. ```tsx import { TableController, type SortingState } from '@tanstack/lit-table' //... @state() private _sorting: SortingState = [ { id: 'age', //you should get autocomplete for the `id` and `desc` properties desc: true, } ] ``` ================================================ FILE: docs/framework/lit/lit-table.md ================================================ --- title: Lit Table --- The `@tanstack/lit-table` adapter is a wrapper around the core table logic. Most of it's job is related to managing state the "lit" way, providing types and the rendering implementation of cell/header/footer templates. ## Exports `@tanstack/lit-table` re-exports all of `@tanstack/table-core`'s APIs and the following: ### `TableController` Is a reactive controller that provides a `table` API that takes an `options` object and returns a table instance. ```ts import { TableController } from '@tanstack/lit-table' @customElement('my-table-element') class MyTableElement extends LitElement { private tableController = new TableController(this) protected render() { const table = this.tableController.table(options) // ...render your table } } ``` ### `flexRender` A utility function for rendering cell/header/footer templates with dynamic values. Example: ```jsx import { flexRender } from '@tanstack/lit-table' //... return html` ${table .getRowModel() .rows.slice(0, 10) .map( row => html` ${row .getVisibleCells() .map( cell => html` ${flexRender( cell.column.columnDef.cell, cell.getContext() )} ` )} ` )} ` ``` ================================================ FILE: docs/framework/preact/guide/create-table-hook.md ================================================ --- title: createTableHook Guide --- `createTableHook` is an advanced API for building reusable, composable table configurations in Preact. It mirrors the [React `createTableHook` API](../react/guide/create-table-hook) — you define features, row models, and pre-bound components once, then reuse them across multiple tables with minimal boilerplate. > **When to use it:** Use `createTableHook` when you have multiple tables that share the same configuration. For a single table, `useTable` is sufficient. ## Setup Create a shared table configuration file and call `createTableHook` with your features, row models, and component registries: ```tsx // hooks/table.ts import { createTableHook, tableFeatures, columnFilteringFeature, rowPaginationFeature, rowSortingFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, sortFns, } from '@tanstack/preact-table' import { PaginationControls, RowCount, TableToolbar } from '../components/table-components' import { TextCell, NumberCell, StatusCell } from '../components/cell-components' import { SortIndicator, ColumnFilter } from '../components/header-components' export const { createAppColumnHelper, useAppTable, useTableContext, useCellContext, useHeaderContext, } = createTableHook({ _features: tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, getRowId: (row) => row.id, tableComponents: { PaginationControls, RowCount, TableToolbar, }, cellComponents: { TextCell, NumberCell, StatusCell, }, headerComponents: { SortIndicator, ColumnFilter, }, }) ``` ## What `createTableHook` Returns | Export | Description | |--------|-------------| | `useAppTable` | Hook for creating tables. Merges default options from the hook with per-table options. | | `createAppColumnHelper` | Column helper with `TFeatures` pre-bound. Only requires `TData`. | | `useTableContext` | Access the table instance inside `tableComponents`. | | `useCellContext` | Access the cell instance inside `cellComponents`. | | `useHeaderContext` | Access the header instance inside `headerComponents`. | ## Component Registries The API matches React's `createTableHook`: - **`tableComponents`** — Components attached to the table (`table.PaginationControls`, etc.). Use `useTableContext()` inside them. - **`cellComponents`** — Components attached to the cell (`cell.TextCell`, etc.). Use `useCellContext()` inside them. - **`headerComponents`** — Components attached to the header (`header.SortIndicator`, etc.). Use `useHeaderContext()` inside them. ## Using `useAppTable` ```tsx const personColumnHelper = createAppColumnHelper() function UsersTable() { const [data, setData] = useState(() => makeData(100)) const columns = useMemo( () => personColumnHelper.columns([ personColumnHelper.accessor('firstName', { header: 'First Name', cell: ({ cell }) => , }), personColumnHelper.accessor('age', { header: 'Age', cell: ({ cell }) => , }), ]), [], ) const table = useAppTable({ columns, data, }) return ( ({ pagination: state.pagination })}> {() => (
setData(makeData(100))} /> {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((h) => ( {(header) => ( )} ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((c) => ( {(cell) => } ))} ))}
)}
) } ``` ## AppTable, AppHeader, AppCell, AppFooter Same as React: `table.AppTable`, `table.AppHeader`, `table.AppCell`, and `table.AppFooter` provide context to your registered components. Use the `selector` prop on `AppTable` for optimized re-renders. ## See Also - [React createTableHook Guide](../react/guide/create-table-hook) — The React guide has more detailed examples and the same API. - [Composable Tables (React)](../react/examples/composable-tables) — Reference implementation (Preact API mirrors React). ================================================ FILE: docs/framework/react/guide/create-table-hook.md ================================================ --- title: createTableHook Guide --- `createTableHook` is an advanced API for building reusable, composable table configurations. It lets you define features, row models, and pre-bound components once, then reuse them across multiple tables with minimal boilerplate. It is inspired by [TanStack Form's `createFormHook`](https://tanstack.com/form/latest/docs/framework/react/guides/form-composition). > **When to use it:** Use `createTableHook` when you have multiple tables that share the same configuration (features, row models, and reusable components). For a single table, `useTable` is sufficient. ## Examples - [Composable Tables](../examples/composable-tables) — Two tables (Users and Products) sharing the same `createTableHook` configuration, with table/cell/header components, sorting, filtering, and pagination. - [Basic useAppTable](../examples/basic-use-app-table) — Minimal example using `createTableHook` with no pre-bound components. ## Setup Create a shared table configuration file and call `createTableHook` with your features, row models, and component registries: ```tsx // hooks/table.ts import { createTableHook, tableFeatures, columnFilteringFeature, rowPaginationFeature, rowSortingFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, sortFns, } from '@tanstack/react-table' import { PaginationControls, RowCount, TableToolbar } from '../components/table-components' import { TextCell, NumberCell, StatusCell, ProgressCell } from '../components/cell-components' import { SortIndicator, ColumnFilter } from '../components/header-components' export const { createAppColumnHelper, useAppTable, useTableContext, useCellContext, useHeaderContext, } = createTableHook({ _features: tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, getRowId: (row) => row.id, tableComponents: { PaginationControls, RowCount, TableToolbar, }, cellComponents: { TextCell, NumberCell, StatusCell, ProgressCell, }, headerComponents: { SortIndicator, ColumnFilter, }, }) ``` ## What `createTableHook` Returns | Export | Description | |--------|-------------| | `useAppTable` | Hook for creating tables. Merges default options from the hook with per-table options. No need to pass `_features` or `_rowModels`—they come from the hook. | | `createAppColumnHelper` | Column helper with `TFeatures` pre-bound. Only requires `TData`. Use `createAppColumnHelper()` instead of `createColumnHelper()`. | | `useTableContext` | Access the table instance inside `tableComponents`. | | `useCellContext` | Access the cell instance inside `cellComponents`. | | `useHeaderContext` | Access the header instance inside `headerComponents`. | ## Component Registries ### `tableComponents` Components that need access to the **table instance**. They are attached to the table object, so you use them as `table.PaginationControls`, `table.RowCount`, etc. Use `useTableContext()` inside these components: ```tsx export function PaginationControls() { const table = useTableContext() return (
) } ``` ### `cellComponents` Components that render **cell content**. They are attached to the `cell` object in column definitions, so you use them as `cell.TextCell`, `cell.NumberCell`, etc. Use `useCellContext()` inside these components: ```tsx export function TextCell() { const cell = useCellContext() return {cell.getValue()} } export function NumberCell() { const cell = useCellContext() return {cell.getValue().toLocaleString()} } ``` ### `headerComponents` Components that render **header/footer content**. They are attached to the `header` object, so you use them as `header.SortIndicator`, `header.ColumnFilter`, etc. Use `useHeaderContext()` inside these components: ```tsx export function SortIndicator() { const header = useHeaderContext() const sorted = header.column.getIsSorted() if (!sorted) return null return {sorted === 'asc' ? '🔼' : '🔽'} } ``` ## Using `useAppTable` Create tables with `useAppTable`—`_features` and `_rowModels` are inherited from the hook: ```tsx const personColumnHelper = createAppColumnHelper() function UsersTable() { const [data, setData] = useState(() => makeData(1000)) const columns = useMemo( () => personColumnHelper.columns([ personColumnHelper.accessor('firstName', { header: 'First Name', cell: ({ cell }) => , }), personColumnHelper.accessor('age', { header: 'Age', cell: ({ cell }) => , }), personColumnHelper.accessor('status', { header: 'Status', cell: ({ cell }) => , }), ]), [], ) const table = useAppTable({ columns, data, debugTable: true, }) return ( ({ pagination: state.pagination, sorting: state.sorting })}> {({ sorting }) => (
setData(makeData(1000))} /> {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((h) => ( {(header) => ( )} ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((c) => ( {(cell) => } ))} ))}
)}
) } ``` ## AppTable, AppHeader, AppCell, AppFooter The table returned by `useAppTable` includes wrapper components that provide context to your registered components: - **`table.AppTable`** — Wraps the table UI and provides a `selector` prop for optimized re-renders. Renders its children with the selected state. - **`table.AppHeader`** — Wraps a header and provides the enhanced `header` context (with `header.SortIndicator`, `header.ColumnFilter`, etc.) to its render prop. - **`table.AppCell`** — Wraps a cell and provides the enhanced `cell` context (with `cell.TextCell`, `cell.FlexRender`, etc.) to its render prop. - **`table.AppFooter`** — Same as AppHeader but for footer cells. ## Optimized Rendering with `selector` Pass a `selector` to `table.AppTable` to subscribe only to the state slices you need. This reduces re-renders when other state (e.g., column filters) changes but your component doesn't use it: ```tsx ({ pagination: state.pagination, sorting: state.sorting, columnFilters: state.columnFilters, })} > {({ sorting, columnFilters }) => ( // This only re-renders when pagination, sorting, or columnFilters change
...
)}
``` For v8-style behavior (re-render on any state change), pass `(state) => state`. ## Multiple Table Configurations You can call `createTableHook` multiple times for different parts of your app: ```tsx // admin-tables.ts export const { useAppTable: useAdminTable, createAppColumnHelper: createAdminColumnHelper } = createTableHook({ _features: tableFeatures({ rowSortingFeature, columnFilteringFeature, rowSelectionFeature }), _rowModels: { /* ... */ }, cellComponents: { EditableCell, DeleteButton }, }) // readonly-tables.ts export const { useAppTable: useReadonlyTable, createAppColumnHelper: createReadonlyColumnHelper } = createTableHook({ _features: tableFeatures({ rowSortingFeature }), _rowModels: { /* ... */ }, cellComponents: { TextCell, NumberCell }, }) ``` ## See Also - [Migrating to v9](./migrating) — Includes a createTableHook section - [Composable Tables example](../examples/composable-tables) — Full implementation with two tables ================================================ FILE: docs/framework/react/guide/migrating.md ================================================ --- title: Migrating to TanStack Table v9 (React) --- ## What's New in TanStack Table v9 TanStack Table v9 is a major release that introduces significant architectural improvements while maintaining the core table logic you're familiar with. Here are the key changes: ### 1. Tree-shaking - **Features are tree-shakeable**: Features are now treated as plugins—import only what you use. If your table only needs sorting, you won't ship filtering, pagination, or other feature code. Bundlers can eliminate unused code, so for smaller tables you can expect to bundle ~6–7kb compared to 15–20kb for the same table in v8. This also lets TanStack Table add features over time without bloating everyone's bundles. - **Row models and their functions are refactored**: Row model factories (`createFilteredRowModel`, `createSortedRowModel`, etc.) now accept their processing functions (`filterFns`, `sortFns`, `aggregationFns`) as parameters. This enables tree-shaking of the functions themselves—if you use a custom filter, you don't pay for built-in filters you never use. ### 2. State Management - **Uses TanStack Store**: The internal state system has been rebuilt on [TanStack Store](https://tanstack.com/store), providing a reactive, framework-agnostic foundation. This works similarly to TanStack Form's state model. - **Opt-in subscriptions instead of memo hacks**: Use `table.Subscribe` or pass a selector to `useTable` to subscribe to specific slices of state. Only re-render when the state you care about changes—no more `React.memo` or manual memoization. Pass `state => state` if you want v8-style behavior where any state change triggers a re-render. ### 3. Composability - **`tableOptions`**: New utilities let you compose and share table configurations. Define `_features`, `_rowModels`, and default options once, then reuse them across tables or pass them through `createTableHook`. - **`createTableHook`** (optional, advanced): Create custom table hooks with pre-bound features, row models, and components—similar to TanStack Form's `createFormHook`. Define your table setup once and reuse it across many tables. You don't need this for most use cases; `useTable` is sufficient. ### The Good News: Most Upgrades Are Opt-in While v9 is a significant upgrade, **you don't have to adopt everything at once**: - **Don't want to optimize renders?** Pass `state => state` as the selector to `useTable` and rendering works like v8. - **Don't want to think about tree-shaking?** Import `stockFeatures` to include all features, just like v8. - **Table markup is largely unchanged.** How you render ``, ``, ``, `} // With selector - children receives cell and selected state s.columnFilters}> {(c, filters) => } ``` ### AppFooter ```ts AppFooter: AppHeaderComponent>; ``` Wraps a footer and provides header context with pre-bound headerComponents. Optionally accepts a selector for Subscribe functionality. #### Example ```tsx {(f) => } ``` ### AppHeader ```ts AppHeader: AppHeaderComponent>; ``` Wraps a header and provides header context with pre-bound headerComponents. Optionally accepts a selector for Subscribe functionality. #### Example ```tsx // Without selector {(h) => } // With selector s.sorting}> {(h, sorting) => } ``` ### AppTable ```ts AppTable: AppTableComponent; ``` Root wrapper component that provides table context with optional Subscribe. #### Example ```tsx // Without selector - children is ReactNode
`, etc. remains the same. The main change is **how you define a table** with the `useTable` hook — specifically the new `_features` and `_rowModels` options. --- ## Quick Legacy Migration Need to migrate incrementally? Use `useLegacyTable` — it accepts the v8-style API while using v9 under the hood. **This is deprecated** and intended only as a temporary migration aid. It includes all features by default, resulting in a larger bundle size. Legacy APIs live in a separate export. Import core utilities from `@tanstack/react-table` and legacy-specific APIs from `@tanstack/react-table/legacy`: ```tsx import { flexRender } from '@tanstack/react-table' import { useLegacyTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, legacyCreateColumnHelper, } from '@tanstack/react-table/legacy' ``` See the [useLegacyTable Guide](./use-legacy-table.md) for full documentation, examples, and type helpers. --- The rest of this guide focuses on migrating to the full v9 API and taking advantage of its features. ## Core Breaking Changes ### Hook Rename The hook name has been simplified to be consistent across all TanStack libraries: ```tsx // v8 import { useReactTable } from '@tanstack/react-table' const table = useReactTable(options) // v9 import { useTable } from '@tanstack/react-table' const table = useTable(options) ``` ### New Required Options: `_features` and `_rowModels` In v9, you must explicitly declare which features and row models your table uses: ```tsx // v8 import { useReactTable, getCoreRowModel } from '@tanstack/react-table' const table = useReactTable({ columns, data, getCoreRowModel: getCoreRowModel(), }) // v9 import { useTable, tableFeatures } from '@tanstack/react-table' const _features = tableFeatures({}) // Empty = core features only const table = useTable({ _features, _rowModels: {}, // Core row model is automatic columns, data, }) ``` --- ## The `_features` Option Features control what table functionality is available. In v8, all features were bundled. In v9, you import only what you need. ### Importing Individual Features ```tsx import { tableFeatures, // Import only the features you need columnFilteringFeature, rowSortingFeature, rowPaginationFeature, columnVisibilityFeature, rowSelectionFeature, } from '@tanstack/react-table' // Create a features object (define this outside your component for stable reference) const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, columnVisibilityFeature, rowSelectionFeature, }) ``` ### Using `stockFeatures` for v8-like Behavior If you want all features without thinking about it (like v8), import `stockFeatures`: ```tsx import { useTable, stockFeatures } from '@tanstack/react-table' const table = useTable({ _features: stockFeatures, // All features included _rowModels: { /* ... */ }, columns, data, }) ``` ### Available Features | Feature | Import Name | |---------|-------------| | Column Filtering | `columnFilteringFeature` | | Global Filtering | `globalFilteringFeature` | | Row Sorting | `rowSortingFeature` | | Row Pagination | `rowPaginationFeature` | | Row Selection | `rowSelectionFeature` | | Row Expanding | `rowExpandingFeature` | | Row Pinning | `rowPinningFeature` | | Column Pinning | `columnPinningFeature` | | Column Visibility | `columnVisibilityFeature` | | Column Ordering | `columnOrderingFeature` | | Column Sizing | `columnSizingFeature` | | Column Resizing | `columnResizingFeature` | | Column Grouping | `columnGroupingFeature` | | Column Faceting | `columnFacetingFeature` | --- ## The `_rowModels` Option Row models are the functions that process your data (filtering, sorting, pagination, etc.). In v9, they're configured via `_rowModels` instead of `get*RowModel` options. ### Migration Mapping | v8 Option | v9 `_rowModels` Key | v9 Factory Function | |-----------|---------------------|---------------------| | `getCoreRowModel()` | (automatic) | Not needed — always included | | `getFilteredRowModel()` | `filteredRowModel` | `createFilteredRowModel(filterFns)` | | `getSortedRowModel()` | `sortedRowModel` | `createSortedRowModel(sortFns)` | | `getPaginationRowModel()` | `paginatedRowModel` | `createPaginatedRowModel()` | | `getExpandedRowModel()` | `expandedRowModel` | `createExpandedRowModel()` | | `getGroupedRowModel()` | `groupedRowModel` | `createGroupedRowModel(aggregationFns)` | | `getFacetedRowModel()` | `facetedRowModel` | `createFacetedRowModel()` | | `getFacetedMinMaxValues()` | `facetedMinMaxValues` | `createFacetedMinMaxValues()` | | `getFacetedUniqueValues()` | `facetedUniqueValues` | `createFacetedUniqueValues()` | ### Key Change: Row Model Functions Now Accept Parameters Several row model factories now accept their processing functions as parameters. This enables better tree-shaking and explicit configuration: ```tsx import { createFilteredRowModel, createSortedRowModel, createGroupedRowModel, filterFns, // Built-in filter functions sortFns, // Built-in sort functions aggregationFns, // Built-in aggregation functions } from '@tanstack/react-table' const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), sortedRowModel: createSortedRowModel(sortFns), groupedRowModel: createGroupedRowModel(aggregationFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, }) ``` ### Full Migration Example ```tsx // v8 import { useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, filterFns, sortingFns, } from '@tanstack/react-table' const table = useReactTable({ columns, data, getCoreRowModel: getCoreRowModel(), // used to be called "get*RowModel()" getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), filterFns, // used to be passed in as a root option sortingFns, }) // v9 import { useTable, tableFeatures, columnFilteringFeature, rowSortingFeature, rowPaginationFeature, createFilteredRowModel, createSortedRowModel, createPaginatedRowModel, filterFns, sortFns, } from '@tanstack/react-table' const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, }) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), // now called "create*RowModel()" with a Fns parameter sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, }) ``` --- ## State Management Changes ### Accessing State In v8, you accessed state via `table.getState()`. In v9, state is accessed differently: ```tsx // v8 const state = table.getState() const { sorting, pagination } = table.getState() // v9 - via the store (full state) const fullState = table.store.state const { sorting, pagination } = table.store.state // v9 - via table.state (selected state from your selector) const table = useTable(options, (state) => ({ sorting: state.sorting, pagination: state.pagination, })) // Now table.state only contains sorting and pagination const { sorting, pagination } = table.state ``` ### Optimized Rendering with `table.Subscribe` The biggest state management improvement is `table.Subscribe`, which enables fine-grained reactivity: ```tsx function MyTable() { const table = useTable({ _features, _rowModels: { /* ... */ }, columns, data, }) return ( ({ sorting: state.sorting, pagination: state.pagination, })} > {({ sorting, pagination }) => ( // This only re-renders when sorting or pagination changes
{/* ... */}
Page {pagination.pageIndex + 1}
)}
) } ``` ### Opt-Out: v8-Style Full State Subscription If you want v8-style behavior where the component re-renders on any state change, pass `state => state` as the selector: ```tsx // Re-renders on ANY state change (like v8) const table = useTable( { _features, _rowModels: { /* ... */ }, columns, data, }, (state) => state, // Subscribe to entire state ) // table.state now contains the full state const { sorting, pagination, columnFilters } = table.state ``` ### Controlled State Controlled state patterns work similarly to v8: ```tsx const [sorting, setSorting] = useState([]) const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10, }) const table = useTable({ _features, _rowModels: { /* ... */ }, columns, data, state: { sorting, pagination, }, onSortingChange: setSorting, onPaginationChange: setPagination, }) ``` --- ## Column Helper Changes The `createColumnHelper` function now requires a `TFeatures` type parameter in addition to `TData`: ```tsx // v8 import { createColumnHelper } from '@tanstack/react-table' const columnHelper = createColumnHelper() // v9 import { createColumnHelper, tableFeatures, rowSortingFeature } from '@tanstack/react-table' const _features = tableFeatures({ rowSortingFeature }) const columnHelper = createColumnHelper() ``` ### New `columns()` Helper Method v9 adds a `columns()` helper for better type inference when wrapping column arrays. In v8, `TValue` wasn't always type-safe—especially with group columns, where nested column types could be lost or widened. The `columns()` helper uses variadic tuple types to preserve each column's individual `TValue` type, so `info.getValue()` and cell renderers stay correctly typed throughout nested structures: ```tsx const columnHelper = createColumnHelper() // Wrap your columns array for better type inference const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { id: 'lastName', header: () => Last Name, cell: (info) => {info.getValue()}, }), columnHelper.display({ id: 'actions', header: 'Actions', cell: (info) => , }), ]) ``` ### Using with `createTableHook` When using `createTableHook`, you get a pre-bound `createAppColumnHelper` that only requires `TData`: ```tsx const { useAppTable, createAppColumnHelper } = createTableHook({ _features: tableFeatures({ rowSortingFeature }), _rowModels: { /* ... */ }, }) // TFeatures is already bound — only need TData! const columnHelper = createAppColumnHelper() ``` --- ## Rendering Changes ### `flexRender` Function The `flexRender` function still exists and works the same way: ```tsx import { flexRender } from '@tanstack/react-table' // Still works in v9 {flexRender(cell.column.columnDef.cell, cell.getContext())} {flexRender(header.column.columnDef.header, header.getContext())} ``` ### New `` Component v9 adds a cleaner component-based approach attached to the table instance: ```tsx const table = useTable({ /* ... */ }) // Instead of: {flexRender(header.column.columnDef.header, header.getContext())} // You can use: ``` This should be way more convenient and type-safe than the old `flexRender` function! ### Standalone `` Component There's also a standalone component you can import: ```tsx import { FlexRender } from '@tanstack/react-table' ``` --- ## The `tableOptions()` Utility The `tableOptions()` helper provides type-safe composition of table options. It's useful for creating reusable partial configurations that can be spread into your table setup. ### Basic Usage ```tsx import { tableOptions, tableFeatures, rowSortingFeature } from '@tanstack/react-table' // Create a reusable options object with features pre-configured const baseOptions = tableOptions({ _features: tableFeatures({ rowSortingFeature }), debugTable: process.env.NODE_ENV === 'development', }) // Use in your table — columns, data, and other options can be added const table = useTable({ ...baseOptions, columns, data, _rowModels: {}, }) ``` ### Composing Partial Options `tableOptions()` allows you to omit certain required fields (like `data`, `columns`, or `_features`) when creating partial configurations: ```tsx // Partial options without data or columns const featureOptions = tableOptions({ _features: tableFeatures({ rowSortingFeature, columnFilteringFeature, }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), }, }) // Another partial without _features (inherits from spread) const paginationDefaults = tableOptions({ _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, initialState: { pagination: { pageIndex: 0, pageSize: 25 }, }, }) // Combine them const table = useTable({ ...featureOptions, ...paginationDefaults, columns, data, }) ``` ### Using with `createTableHook` `tableOptions()` pairs well with `createTableHook` for building composable table factories: ```tsx const sharedOptions = tableOptions({ _features: tableFeatures({ rowSortingFeature, rowPaginationFeature }), _rowModels: { sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, }) const { useAppTable } = createTableHook(sharedOptions) ``` --- ## `createTableHook`: Composable Table Patterns **This is an advanced, optional feature.** You don't need to use `createTableHook`—`useTable` is sufficient for most use cases. If you're familiar with [TanStack Form](https://tanstack.com/form)'s `createFormHook`, `createTableHook` works almost the same way: it creates a custom hook with pre-bound configuration that you can reuse across many tables. For applications with multiple tables sharing the same configuration, `createTableHook` lets you define features, row models, and reusable components once: ```tsx // hooks/table.ts import { createTableHook, tableFeatures, columnFilteringFeature, rowSortingFeature, rowPaginationFeature, createFilteredRowModel, createSortedRowModel, createPaginatedRowModel, filterFns, sortFns, } from '@tanstack/react-table' // Import your reusable components import { PaginationControls, SortIndicator, TextCell } from './components' export const { useAppTable, createAppColumnHelper, useTableContext, useCellContext, useHeaderContext, } = createTableHook({ // Features defined once _features: tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, }), // Row models defined once _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, // Default table options debugTable: process.env.NODE_ENV === 'development', // Register reusable components tableComponents: { PaginationControls }, cellComponents: { TextCell }, headerComponents: { SortIndicator }, }) ``` ### Using `useAppTable` ```tsx // features/users.tsx import { useAppTable, createAppColumnHelper } from './hooks/table' const columnHelper = createAppColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: ({ cell }) => , // Pre-bound component! }), ]) function UsersTable({ data }: { data: Person[] }) { const table = useAppTable({ columns, data, // _features and _rowModels already configured! }) return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((h) => ( {(header) => ( )} ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((c) => ( {(cell) => ( )} ))} ))}
) } ``` ### Context Hooks for Components Components registered via `createTableHook` can access their context: ```tsx // components/SortIndicator.tsx import { useHeaderContext } from './hooks/table' export function SortIndicator() { const header = useHeaderContext() const sorted = header.column.getIsSorted() if (!sorted) return null return sorted === 'asc' ? ' 🔼' : ' 🔽' } // components/TextCell.tsx import { useCellContext } from './hooks/table' export function TextCell() { const cell = useCellContext() return {cell.getValue() as string} } // components/PaginationControls.tsx import { useTableContext } from './hooks/table' export function PaginationControls() { const table = useTableContext() return ( s.pagination}> {(pagination) => (
Page {pagination.pageIndex + 1}
)}
) } ``` --- ## Other Breaking Changes ### Column Pinning Option Split The `enablePinning` option has been split into separate options: ```tsx // v8 enablePinning: true // v9 enableColumnPinning: true enableRowPinning: true ``` ### Removed Internal APIs All internal APIs prefixed with `_` have been removed. If you were using any of these, use their public equivalents: - Removed: `table._getPinnedRows()` - Removed: `table._getFacetedRowModel()` - Removed: `table._getFacetedMinMaxValues()` - Removed: `table._getFacetedUniqueValues()` ### Column Sizing vs. Column Resizing Split In v8, column sizing and resizing were combined in a single feature. In v9, they've been split into separate features for better tree-shaking. | v8 | v9 | |----|-----| | `ColumnSizing` (combined feature) | `columnSizingFeature` + `columnResizingFeature` | | `columnSizingInfo` state | `columnResizing` state | | `setColumnSizingInfo()` | `setColumnResizing()` | | `onColumnSizingInfoChange` option | `onColumnResizingChange` option | If you only need column sizing (fixed widths) without interactive resizing, you can import just `columnSizingFeature`. If you need drag-to-resize functionality, import both: ```tsx import { columnSizingFeature, columnResizingFeature } from '@tanstack/react-table' const _features = tableFeatures({ columnSizingFeature, columnResizingFeature, // Only if you need interactive resizing }) ``` ### Sorting API Renames Sorting-related APIs have been renamed for consistency: | v8 | v9 | |----|-----| | `sortingFn` (column def option) | `sortFn` | | `column.getSortingFn()` | `column.getSortFn()` | | `column.getAutoSortingFn()` | `column.getAutoSortFn()` | | `SortingFn` type | `SortFn` type | | `SortingFns` interface | `SortFns` interface | | `sortingFns` (built-in functions) | `sortFns` | Update your column definitions: ```tsx // v8 const columns = [ { accessorKey: 'name', sortingFn: 'alphanumeric', // or custom function }, ] // v9 const columns = [ { accessorKey: 'name', sortFn: 'alphanumeric', // or custom function }, ] ``` ### Row API Changes Some row APIs have changed from private to public: | v8 | v9 | |----|-----| | `row._getAllCellsByColumnId()` (private) | `row.getAllCellsByColumnId()` (public) | If you were accessing this internal API, you can now use it without the underscore prefix. --- ## TypeScript Changes Summary ### Type Generics Most types now require a `TFeatures` parameter: ```tsx // v8 type Column type ColumnDef type Table type Row type Cell // v9 type Column type ColumnDef type Table type Row type Cell ``` ### Using `typeof _features` The easiest way to get the `TFeatures` type is with `typeof`: ```tsx const _features = tableFeatures({ rowSortingFeature, columnFilteringFeature, }) // Use typeof to get the type type MyFeatures = typeof _features const columns: ColumnDef[] = [...] function Filter({ column }: { column: Column }) { // ... } ``` ### Using `StockFeatures` If using `stockFeatures` with `useTable`, use the `StockFeatures` type: ```tsx import type { StockFeatures, ColumnDef } from '@tanstack/react-table' const columns: ColumnDef[] = [...] ``` ### `ColumnMeta` Generic Change If you're using module augmentation to extend `ColumnMeta`, note that it now requires a `TFeatures` parameter: ```tsx // v8 declare module '@tanstack/react-table' { interface ColumnMeta { customProperty: string } } // v9 - TFeatures is now the first parameter declare module '@tanstack/react-table' { interface ColumnMeta { customProperty: string } } ``` ### `RowData` Type Restriction The `RowData` type is now more restrictive: ```tsx // v8 - very permissive type RowData = unknown | object | any[] // v9 - must be a record or array type RowData = Record | Array ``` This change improves type safety. If you were passing unusual data types, ensure your data conforms to `Record` or `Array`. --- ## Migration Checklist - [ ] Update import: `useReactTable` → `useTable` - [ ] Define `_features` using `tableFeatures()` (or use `stockFeatures`) - [ ] Migrate `get*RowModel()` options to `_rowModels` - [ ] Update row model factories to include `Fns` parameters where needed - [ ] Update TypeScript types to include `TFeatures` generic - [ ] Update state access: `table.getState()` → `table.store.state` or `table.state` - [ ] Update `createColumnHelper()` → `createColumnHelper()` - [ ] Replace `enablePinning` with `enableColumnPinning`/`enableRowPinning` if used - [ ] Rename `sortingFn` → `sortFn` in column definitions - [ ] Split column sizing/resizing: use both `columnSizingFeature` and `columnResizingFeature` if needed - [ ] Rename `columnSizingInfo` state → `columnResizing` (and related options) - [ ] Update `ColumnMeta` module augmentation to include `TFeatures` generic (if used) - [ ] (Optional) Add `table.Subscribe` for render optimizations - [ ] (Optional) Use `tableOptions()` for composable configurations - [ ] (Optional) Migrate to `createTableHook` for reusable table patterns --- ## Examples Check out these examples to see v9 patterns in action: - [Basic useTable](../examples/basic-use-table) - Simple table with the new `useTable` hook - [Basic useLegacyTable](../examples/basic-use-legacy-table) - Migration example using `useLegacyTable` - [Basic useAppTable](../examples/basic-use-app-table) - Using `createTableHook` - [Filters](../examples/filters) - Filtering with the new API - [Sorting](../examples/sorting) - Sorting with the new API - [Composable Tables](../examples/composable-tables) - Advanced `createTableHook` patterns ================================================ FILE: docs/framework/react/guide/table-state.md ================================================ --- title: Table State (React) Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [kitchen sink](../examples/kitchen-sink) - [fully controlled](../examples/fully-controlled) ## Table State (React) Guide TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table. ### Accessing Table State You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API. ```jsx const table = useTable({ columns, data, //... }) console.log(table.store.state) //access the entire internal state console.log(table.store.state.rowSelection) //access just the row selection state ``` ### Custom Initial State If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance. ```jsx const table = useTable({ columns, data, initialState: { columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order columnVisibility: { id: false //hide the id column by default }, expanded: true, //expand all rows by default sorting: [ { id: 'age', desc: true //sort by age in descending order by default } ] }, //... }) ``` > **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`. ### Controlled State If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options. #### Individual Controlled State You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis. In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance. Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values. ```jsx const [columnFilters, setColumnFilters] = React.useState([]) //no default filters const [sorting, setSorting] = React.useState([{ id: 'age', desc: true, //sort by age in descending order by default }]) const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 15 }) //Use our controlled state values to fetch data const tableQuery = useQuery({ queryKey: ['users', columnFilters, sorting, pagination], queryFn: () => fetchUsers(columnFilters, sorting, pagination), //... }) const table = useTable({ columns, data: tableQuery.data, //... state: { columnFilters, //pass controlled state back to the table (overrides internal state) sorting, pagination }, onColumnFiltersChange: setColumnFilters, //hoist columnFilters state into our own state management onSortingChange: setSorting, onPaginationChange: setPagination, }) //... ``` #### Fully Controlled State Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a react tree, like `columnSizingInfo` state`, might cause bad performance issues. A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below. ```jsx //create a table instance with default state values const table = useTable({ columns, data, //... Note: `state` values are NOT passed in yet }) const [state, setState] = React.useState({ ...table.initialState, //populate the initial state with all of the default state values from the table instance pagination: { pageIndex: 0, pageSize: 15 //optionally customize the initial pagination state. } }) //Use the table.setOptions API to merge our fully controlled state onto the table instance table.setOptions(prev => ({ ...prev, //preserve any other options that we have set up above state, //our fully controlled state overrides the internal state onStateChange: setState //any state changes will be pushed up to our own state management })) ``` ### On State Change Callbacks So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about using these options that you should be aware of. #### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**. Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value. ```jsx const [sorting, setSorting] = React.useState([]) //... const table = useTable({ columns, data, //... state: { sorting, //required because we are using `onSortingChange` }, onSortingChange: setSorting, //makes the `state.sorting` controlled }) ``` #### 2. **Updaters can either be raw values or callback functions**. The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value. What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value. ```jsx const [sorting, setSorting] = React.useState([]) const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10 }) const table = useTable({ columns, data, //... state: { pagination, sorting, } //syntax 1 onPaginationChange: (updater) => { setPagination(old => { const newPaginationValue = updater instanceof Function ? updater(old) : updater //do something with the new pagination value //... return newPaginationValue }) }, //syntax 2 onSortingChange: (updater) => { const newSortingValue = updater instanceof Function ? updater(sorting) : updater //do something with the new sorting value //... setSorting(updater) //normal state update } }) ``` ### State Types All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling. ```tsx import { useTable, type SortingState } from '@tanstack/react-table' //... const [sorting, setSorting] = React.useState([ { id: 'age', //you should get autocomplete for the `id` and `desc` properties desc: true, } ]) ``` ================================================ FILE: docs/framework/react/guide/use-legacy-table.md ================================================ --- title: Using useLegacyTable for Incremental Migration --- The `useLegacyTable` hook provides a compatibility layer that accepts the v8-style API while using v9 under the hood. This is useful for teams that need to migrate incrementally or have large codebases where a full migration isn't immediately practical. > **Warning:** `useLegacyTable` is **deprecated** and intended only as a temporary migration aid. It includes all features by default, resulting in a larger bundle size compared to the tree-shakeable v9 API. Plan to migrate to `useTable` for better performance and smaller bundles. ## When to Use `useLegacyTable` - You have an existing v8 codebase and need to upgrade dependencies - You want to migrate incrementally, one table at a time - You need v9 compatibility but don't have time for a full migration yet ## Basic Usage ```tsx import { useState } from 'react' import { flexRender } from '@tanstack/react-table' import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, legacyCreateColumnHelper, useLegacyTable, } from '@tanstack/react-table/legacy' import type { ColumnFiltersState, PaginationState, SortingState, } from '@tanstack/react-table' import type { LegacyColumn, LegacyColumnDef, LegacyRow, } from '@tanstack/react-table/legacy' interface Person { name: string email: string age: number } const columnHelper = legacyCreateColumnHelper() const columns: LegacyColumnDef[] = [ columnHelper.accessor('name', { header: 'Name' }), columnHelper.accessor('email', { header: 'Email' }), columnHelper.accessor('age', { header: 'Age' }), columnHelper.display({ id: 'actions', header: 'Actions' }), ] function MyTable({ data }: { data: Person[] }) { const [sorting, setSorting] = useState([]) const [columnFilters, setColumnFilters] = useState([]) const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10, }) // useLegacyTable accepts the v8-style API const table = useLegacyTable({ columns, data, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getPaginationRowModel: getPaginationRowModel(), state: { sorting, columnFilters, pagination }, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onPaginationChange: setPagination, }) return ( {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
{flexRender( header.column.columnDef.header, header.getContext() )} {header.column.getCanFilter() ? ( ) : null}
{cell.column.id === 'actions' ? ( ) : ( flexRender(cell.column.columnDef.cell, cell.getContext()) )}
) } function Filter({ column }: { column: LegacyColumn }) { return ( column.setFilterValue(e.target.value)} placeholder="Filter..." /> ) } function RowActions({ row }: { row: LegacyRow }) { return } ``` ## Type Helpers When using `useLegacyTable`, use these type helpers for proper TypeScript support: | Type | Description | |------|-------------| | `LegacyColumnDef` | Column definition type (equivalent to v8's `ColumnDef`) | | `LegacyColumn` | Column instance type | | `LegacyRow` | Row instance type | | `LegacyCell` | Cell instance type | | `LegacyTable` | Table instance type | | `legacyCreateColumnHelper()` | Column helper with StockFeatures pre-bound—only requires TData | ### Using `legacyCreateColumnHelper` Use `legacyCreateColumnHelper` instead of `createColumnHelper`—it has StockFeatures pre-bound, so you only need to specify `TData`: ```tsx import { legacyCreateColumnHelper } from '@tanstack/react-table/legacy' import type { LegacyColumnDef } from '@tanstack/react-table/legacy' const columnHelper = legacyCreateColumnHelper() const columns: LegacyColumnDef[] = [ columnHelper.accessor('name', { header: 'Name' }), // ... ] ``` ## API Differences from v8 While `useLegacyTable` aims for v8 compatibility, there are a few differences: ### Row Model Functions The `get*RowModel()` functions are imported from `@tanstack/react-table/legacy`: ```tsx import { getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, getExpandedRowModel, getGroupedRowModel, getFacetedRowModel, getFacetedMinMaxValues, getFacetedUniqueValues, } from '@tanstack/react-table/legacy' ``` ### Sorting Function Renames Note that in v9, sorting-related APIs have been renamed. If you're using custom sorting functions in column definitions: | v8 | v9 | |----|-----| | `sortingFn` | `sortFn` | The legacy table adapter handles this internally for built-in sorting, but if you're defining custom sorting functions, be aware of the rename. ## Caveats and Limitations ### Bundle Size `useLegacyTable` includes **all features** by default, similar to v8. This means: - No tree-shaking benefits - Bundle size is **much larger** than v8—each feature has grown since v8, and you pay for all of them - The tree-shakeable v9 API exists so TanStack Table can add features over time without bloating everyone's bundles; only users who opt into a feature pay for it - If bundle size is a concern, prioritize migrating to the full v9 API ### Deprecation `useLegacyTable` is deprecated and will be removed in a future major version. It exists solely to ease migration. Plan your migration timeline accordingly. ### No `table.Subscribe` The fine-grained reactivity feature (`table.Subscribe`) is not available with `useLegacyTable`. The table re-renders on every state change, like v8. ### No `createTableHook` Integration `useLegacyTable` cannot be used with `createTableHook`. If you want to create reusable table configurations, migrate to the full v9 API. ## Migration Path Once you're ready to migrate to the full v9 API: 1. Replace `useLegacyTable` with `useTable` 2. Define your `_features` using `tableFeatures()` 3. Convert `get*RowModel()` options to `_rowModels` 4. Update types from `Legacy*` to the standard v9 types See the [main migration guide](./migrating.md) for complete instructions. ## Example See the [Basic useLegacyTable example](../examples/basic-use-legacy-table) for a working implementation. ================================================ FILE: docs/framework/react/react-table.md ================================================ --- title: React Table --- The `@tanstack/react-table` adapter is a wrapper around the core table logic. Most of its job is related to managing state the "react" way, providing types and the rendering implementation of cell/header/footer templates. ## `useTable` Takes an `options` object and returns a table. ```tsx import { useTable } from '@tanstack/react-table' function App() { const table = useTable(options) // ...render your table } ``` ================================================ FILE: docs/framework/react/reference/index/functions/FlexRender-1.md ================================================ --- id: FlexRender title: FlexRender --- # Function: FlexRender() ```ts function FlexRender(props): | string | number | bigint | boolean | Iterable | Promise | Element | null | undefined; ``` Defined in: [FlexRender.tsx:97](https://github.com/TanStack/table/blob/main/packages/react-table/src/FlexRender.tsx#L97) Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### props [`FlexRenderProps`](../type-aliases/FlexRenderProps.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns \| `string` \| `number` \| `bigint` \| `boolean` \| `Iterable`\<`ReactNode`, `any`, `any`\> \| `Promise`\<`AwaitedReactNode`\> \| `Element` \| `null` \| `undefined` ## Example ```tsx ``` This replaces calling `flexRender` directly like this: ```tsx flexRender(cell.column.columnDef.cell, cell.getContext()) flexRender(header.column.columnDef.header, header.getContext()) flexRender(footer.column.columnDef.footer, footer.getContext()) ``` ================================================ FILE: docs/framework/react/reference/index/functions/Subscribe.md ================================================ --- id: Subscribe title: Subscribe --- # Function: Subscribe() ```ts function Subscribe(props): ReactNode | Promise; ``` Defined in: [Subscribe.ts:58](https://github.com/TanStack/table/blob/main/packages/react-table/src/Subscribe.ts#L58) A React component that allows you to subscribe to the table state. This is useful for opting into state re-renders for specific parts of the table state. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` = \{ \} ## Parameters ### props [`SubscribeProps`](../type-aliases/SubscribeProps.md)\<`TFeatures`, `TData`, `TSelected`\> ## Returns `ReactNode` \| `Promise`\<`ReactNode`\> ## Examples ```tsx // As a standalone component ({ rowSelection: state.rowSelection })}> {({ rowSelection }) => (
Selected rows: {Object.keys(rowSelection).length}
)}
``` ```tsx // As table.Subscribe (table instance method) ({ rowSelection: state.rowSelection })}> {({ rowSelection }) => (
Selected rows: {Object.keys(rowSelection).length}
)}
``` ================================================ FILE: docs/framework/react/reference/index/functions/createTableHook.md ================================================ --- id: createTableHook title: createTableHook --- # Function: createTableHook() ```ts function createTableHook(__namedParameters): object; ``` Defined in: [createTableHook.tsx:590](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L590) Creates a custom table hook with pre-bound components for composition. This is the table equivalent of TanStack Form's `createFormHook`. It allows you to: - Define features, row models, and default options once, shared across all tables - Register reusable table, cell, and header components - Access table/cell/header instances via context in those components - Get a `useAppTable` hook that returns an extended table with App wrapper components - Get a `createAppColumnHelper` function pre-bound to your features ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Parameters ### \_\_namedParameters [`CreateTableHookOptions`](../type-aliases/CreateTableHookOptions.md)\<`TFeatures`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\> ## Returns ### appFeatures ```ts appFeatures: TFeatures; ``` ### createAppColumnHelper() ```ts createAppColumnHelper: () => AppColumnHelper; ``` Create a column helper pre-bound to the features and components configured in this table hook. The cell, header, and footer contexts include pre-bound components (e.g., `cell.TextCell`). #### Type Parameters ##### TData `TData` *extends* `RowData` #### Returns [`AppColumnHelper`](../type-aliases/AppColumnHelper.md)\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\> #### Example ```tsx const columnHelper = createAppColumnHelper() const columns = [ columnHelper.accessor('firstName', { header: 'First Name', cell: ({ cell }) => , // cell has pre-bound components! }), columnHelper.accessor('age', { header: 'Age', cell: ({ cell }) => , }), ] ``` ### useAppTable() ```ts useAppTable: (tableOptions, selector?) => AppReactTable; ``` Enhanced useTable hook that returns a table with App wrapper components and pre-bound tableComponents attached directly to the table object. Default options from createTableHook are automatically merged with the options passed here. Options passed here take precedence. TFeatures is already known from the createTableHook call; TData is inferred from the data prop. #### Type Parameters ##### TData `TData` *extends* `RowData` ##### TSelected `TSelected` = \{ \} #### Parameters ##### tableOptions `Omit`\<`TableOptions`\<`TFeatures`, `TData`\>, `"_features"` \| `"_rowModels"`\> ##### selector? (`state`) => `TSelected` #### Returns [`AppReactTable`](../type-aliases/AppReactTable.md)\<`TFeatures`, `TData`, `TSelected`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\> ### useCellContext() ```ts useCellContext: () => Cell; ``` Access the cell instance from within an `AppCell` wrapper. Use this in custom `cellComponents` passed to `createTableHook`. TFeatures is already known from the createTableHook call. #### Type Parameters ##### TValue `TValue` *extends* `unknown` = `unknown` #### Returns `Cell`\<`TFeatures`, `any`, `TValue`\> #### Example ```tsx function TextCell() { const cell = useCellContext() return {cell.getValue()} } function NumberCell({ format }: { format?: Intl.NumberFormatOptions }) { const cell = useCellContext() return {cell.getValue().toLocaleString(undefined, format)} } ``` ### useHeaderContext() ```ts useHeaderContext: () => Header; ``` Access the header instance from within an `AppHeader` or `AppFooter` wrapper. Use this in custom `headerComponents` passed to `createTableHook`. TFeatures is already known from the createTableHook call. #### Type Parameters ##### TValue `TValue` *extends* `unknown` = `unknown` #### Returns `Header`\<`TFeatures`, `any`, `TValue`\> #### Example ```tsx function SortIndicator() { const header = useHeaderContext() const sorted = header.column.getIsSorted() return sorted === 'asc' ? '🔼' : sorted === 'desc' ? '🔽' : null } function ColumnFilter() { const header = useHeaderContext() if (!header.column.getCanFilter()) return null return ( header.column.setFilterValue(e.target.value)} placeholder="Filter..." /> ) } ``` ### useTableContext() ```ts useTableContext: () => ReactTable; ``` Access the table instance from within an `AppTable` wrapper. Use this in custom `tableComponents` passed to `createTableHook`. TFeatures is already known from the createTableHook call. #### Type Parameters ##### TData `TData` *extends* `RowData` = `RowData` #### Returns [`ReactTable`](../type-aliases/ReactTable.md)\<`TFeatures`, `TData`\> #### Example ```tsx function PaginationControls() { const table = useTableContext() return ( s.pagination}> {(pagination) => (
Page {pagination.pageIndex + 1}
)}
) } ``` ## Example ```tsx // hooks/table.ts export const { useAppTable, createAppColumnHelper, useTableContext, useCellContext, useHeaderContext, } = createTableHook({ _features: tableFeatures({ rowPaginationFeature, rowSortingFeature, columnFilteringFeature, }), _rowModels: { paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), }, tableComponents: { PaginationControls, RowCount }, cellComponents: { TextCell, NumberCell }, headerComponents: { SortIndicator, ColumnFilter }, }) // Create column helper with TFeatures already bound const columnHelper = createAppColumnHelper() // components/table-components.tsx function PaginationControls() { const table = useTableContext() // TFeatures already known! return s.pagination}>... } // features/users.tsx function UsersTable({ data }: { data: Person[] }) { const table = useAppTable({ columns, data, // TData inferred from Person[] }) return ( {table.getHeaderGroups().map(headerGroup => ( {headerGroup.headers.map(h => ( {(header) => ( )} ))} ))} {table.getRowModel().rows.map(row => ( {row.getAllCells().map(c => ( {(cell) => } ))} ))}
) } ``` ================================================ FILE: docs/framework/react/reference/index/functions/flexRender.md ================================================ --- id: flexRender title: flexRender --- # Function: flexRender() ```ts function flexRender(Comp, props): ReactNode | Element; ``` Defined in: [FlexRender.tsx:45](https://github.com/TanStack/table/blob/main/packages/react-table/src/FlexRender.tsx#L45) If rendering headers, cells, or footers with custom markup, use flexRender instead of `cell.getValue()` or `cell.renderValue()`. ## Type Parameters ### TProps `TProps` *extends* `object` ## Parameters ### Comp [`Renderable`](../type-aliases/Renderable.md)\<`TProps`\> ### props `TProps` ## Returns `ReactNode` \| `Element` ## Example ```ts flexRender(cell.column.columnDef.cell, cell.getContext()) ``` ================================================ FILE: docs/framework/react/reference/index/functions/useTable.md ================================================ --- id: useTable title: useTable --- # Function: useTable() ```ts function useTable(tableOptions, selector): ReactTable; ``` Defined in: [useTable.ts:78](https://github.com/TanStack/table/blob/main/packages/react-table/src/useTable.ts#L78) ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` = \{ \} ## Parameters ### tableOptions `TableOptions`\<`TFeatures`, `TData`\> ### selector (`state`) => `TSelected` ## Returns [`ReactTable`](../type-aliases/ReactTable.md)\<`TFeatures`, `TData`, `TSelected`\> ================================================ FILE: docs/framework/react/reference/index/index.md ================================================ --- id: index title: index --- # index ## Interfaces - [AppCellComponent](interfaces/AppCellComponent.md) - [AppCellPropsWithoutSelector](interfaces/AppCellPropsWithoutSelector.md) - [AppCellPropsWithSelector](interfaces/AppCellPropsWithSelector.md) - [AppHeaderComponent](interfaces/AppHeaderComponent.md) - [AppHeaderPropsWithoutSelector](interfaces/AppHeaderPropsWithoutSelector.md) - [AppHeaderPropsWithSelector](interfaces/AppHeaderPropsWithSelector.md) - [AppTableComponent](interfaces/AppTableComponent.md) - [AppTablePropsWithoutSelector](interfaces/AppTablePropsWithoutSelector.md) - [AppTablePropsWithSelector](interfaces/AppTablePropsWithSelector.md) ## Type Aliases - [AppCellContext](type-aliases/AppCellContext.md) - [AppColumnHelper](type-aliases/AppColumnHelper.md) - [AppHeaderContext](type-aliases/AppHeaderContext.md) - [AppReactTable](type-aliases/AppReactTable.md) - [CreateTableHookOptions](type-aliases/CreateTableHookOptions.md) - [FlexRenderProps](type-aliases/FlexRenderProps.md) - [ReactTable](type-aliases/ReactTable.md) - [Renderable](type-aliases/Renderable.md) - [SubscribeProps](type-aliases/SubscribeProps.md) ## Functions - [createTableHook](functions/createTableHook.md) - [flexRender](functions/flexRender.md) - [FlexRender](functions/FlexRender-1.md) - [Subscribe](functions/Subscribe.md) - [useTable](functions/useTable.md) ================================================ FILE: docs/framework/react/reference/index/interfaces/AppCellComponent.md ================================================ --- id: AppCellComponent title: AppCellComponent --- # Interface: AppCellComponent()\ Defined in: [createTableHook.tsx:368](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L368) Component type for AppCell - wraps a cell and provides cell context with optional Subscribe ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Call Signature ```ts AppCellComponent(props): ReactNode; ``` Defined in: [createTableHook.tsx:373](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L373) Component type for AppCell - wraps a cell and provides cell context with optional Subscribe ### Type Parameters #### TValue `TValue` *extends* `unknown` = `unknown` ### Parameters #### props [`AppCellPropsWithoutSelector`](AppCellPropsWithoutSelector.md)\<`TFeatures`, `TData`, `TValue`, `TCellComponents`\> ### Returns `ReactNode` ## Call Signature ```ts AppCellComponent(props): ReactNode; ``` Defined in: [createTableHook.tsx:381](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L381) Component type for AppCell - wraps a cell and provides cell context with optional Subscribe ### Type Parameters #### TValue `TValue` *extends* `unknown` = `unknown` #### TSelected `TSelected` = `unknown` ### Parameters #### props [`AppCellPropsWithSelector`](AppCellPropsWithSelector.md)\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `TSelected`\> ### Returns `ReactNode` ================================================ FILE: docs/framework/react/reference/index/interfaces/AppCellPropsWithSelector.md ================================================ --- id: AppCellPropsWithSelector title: AppCellPropsWithSelector --- # Interface: AppCellPropsWithSelector\ Defined in: [createTableHook.tsx:313](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L313) Props for AppCell component - with selector ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### TSelected `TSelected` ## Properties ### cell ```ts cell: Cell; ``` Defined in: [createTableHook.tsx:320](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L320) *** ### children() ```ts children: (cell, state) => ReactNode; ``` Defined in: [createTableHook.tsx:321](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L321) #### Parameters ##### cell `Cell_Cell`\<`TFeatures`, `TData`, `TValue`\> & `UnionToIntersection`\<`"columnGroupingFeature"` *extends* keyof `TFeatures` ? `Cell_ColumnGrouping` : `never`\> & `UnionToIntersection`\<\{ \[K in string \| number \| symbol\]: TFeatures\[K\] extends TableFeature\ ? "Cell" extends keyof FeatureConstructorOptions ? FeatureConstructorOptions\[keyof FeatureConstructorOptions & "Cell"\] : never : any \}\[keyof `TFeatures`\]\> & `Cell_Plugins`\<`TFeatures`, `TData`, `TValue`\> & `TCellComponents` & `object` ##### state `TSelected` #### Returns `ReactNode` *** ### selector() ```ts selector: (state) => TSelected; ``` Defined in: [createTableHook.tsx:326](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L326) #### Parameters ##### state `TableState`\<`TFeatures`\> #### Returns `TSelected` ================================================ FILE: docs/framework/react/reference/index/interfaces/AppCellPropsWithoutSelector.md ================================================ --- id: AppCellPropsWithoutSelector title: AppCellPropsWithoutSelector --- # Interface: AppCellPropsWithoutSelector\ Defined in: [createTableHook.tsx:296](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L296) Props for AppCell component - without selector ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Properties ### cell ```ts cell: Cell; ``` Defined in: [createTableHook.tsx:302](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L302) *** ### children() ```ts children: (cell) => ReactNode; ``` Defined in: [createTableHook.tsx:303](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L303) #### Parameters ##### cell `Cell_Cell`\<`TFeatures`, `TData`, `TValue`\> & `UnionToIntersection`\<`"columnGroupingFeature"` *extends* keyof `TFeatures` ? `Cell_ColumnGrouping` : `never`\> & `UnionToIntersection`\<\{ \[K in string \| number \| symbol\]: TFeatures\[K\] extends TableFeature\ ? "Cell" extends keyof FeatureConstructorOptions ? FeatureConstructorOptions\[keyof FeatureConstructorOptions & "Cell"\] : never : any \}\[keyof `TFeatures`\]\> & `Cell_Plugins`\<`TFeatures`, `TData`, `TValue`\> & `TCellComponents` & `object` #### Returns `ReactNode` *** ### selector? ```ts optional selector: undefined; ``` Defined in: [createTableHook.tsx:307](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L307) ================================================ FILE: docs/framework/react/reference/index/interfaces/AppHeaderComponent.md ================================================ --- id: AppHeaderComponent title: AppHeaderComponent --- # Interface: AppHeaderComponent()\ Defined in: [createTableHook.tsx:395](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L395) Component type for AppHeader/AppFooter - wraps a header and provides header context with optional Subscribe ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Call Signature ```ts AppHeaderComponent(props): ReactNode; ``` Defined in: [createTableHook.tsx:400](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L400) Component type for AppHeader/AppFooter - wraps a header and provides header context with optional Subscribe ### Type Parameters #### TValue `TValue` *extends* `unknown` = `unknown` ### Parameters #### props [`AppHeaderPropsWithoutSelector`](AppHeaderPropsWithoutSelector.md)\<`TFeatures`, `TData`, `TValue`, `THeaderComponents`\> ### Returns `ReactNode` ## Call Signature ```ts AppHeaderComponent(props): ReactNode; ``` Defined in: [createTableHook.tsx:408](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L408) Component type for AppHeader/AppFooter - wraps a header and provides header context with optional Subscribe ### Type Parameters #### TValue `TValue` *extends* `unknown` = `unknown` #### TSelected `TSelected` = `unknown` ### Parameters #### props [`AppHeaderPropsWithSelector`](AppHeaderPropsWithSelector.md)\<`TFeatures`, `TData`, `TValue`, `THeaderComponents`, `TSelected`\> ### Returns `ReactNode` ================================================ FILE: docs/framework/react/reference/index/interfaces/AppHeaderPropsWithSelector.md ================================================ --- id: AppHeaderPropsWithSelector title: AppHeaderPropsWithSelector --- # Interface: AppHeaderPropsWithSelector\ Defined in: [createTableHook.tsx:349](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L349) Props for AppHeader/AppFooter component - with selector ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### TSelected `TSelected` ## Properties ### children() ```ts children: (header, state) => ReactNode; ``` Defined in: [createTableHook.tsx:357](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L357) #### Parameters ##### header `Header_Core`\<`TFeatures`, `TData`, `TValue`\> & `UnionToIntersection`\< \| `"columnSizingFeature"` *extends* keyof `TFeatures` ? `Header_ColumnSizing` : `never` \| `"columnResizingFeature"` *extends* keyof `TFeatures` ? `Header_ColumnResizing` : `never`\> & `UnionToIntersection`\<\{ \[K in string \| number \| symbol\]: TFeatures\[K\] extends TableFeature\ ? "Header" extends keyof FeatureConstructorOptions ? FeatureConstructorOptions\[keyof FeatureConstructorOptions & "Header"\] : never : any \}\[keyof `TFeatures`\]\> & `Header_Plugins`\<`TFeatures`, `TData`, `TValue`\> & `THeaderComponents` & `object` ##### state `TSelected` #### Returns `ReactNode` *** ### header ```ts header: Header; ``` Defined in: [createTableHook.tsx:356](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L356) *** ### selector() ```ts selector: (state) => TSelected; ``` Defined in: [createTableHook.tsx:362](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L362) #### Parameters ##### state `TableState`\<`TFeatures`\> #### Returns `TSelected` ================================================ FILE: docs/framework/react/reference/index/interfaces/AppHeaderPropsWithoutSelector.md ================================================ --- id: AppHeaderPropsWithoutSelector title: AppHeaderPropsWithoutSelector --- # Interface: AppHeaderPropsWithoutSelector\ Defined in: [createTableHook.tsx:332](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L332) Props for AppHeader/AppFooter component - without selector ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Properties ### children() ```ts children: (header) => ReactNode; ``` Defined in: [createTableHook.tsx:339](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L339) #### Parameters ##### header `Header_Core`\<`TFeatures`, `TData`, `TValue`\> & `UnionToIntersection`\< \| `"columnSizingFeature"` *extends* keyof `TFeatures` ? `Header_ColumnSizing` : `never` \| `"columnResizingFeature"` *extends* keyof `TFeatures` ? `Header_ColumnResizing` : `never`\> & `UnionToIntersection`\<\{ \[K in string \| number \| symbol\]: TFeatures\[K\] extends TableFeature\ ? "Header" extends keyof FeatureConstructorOptions ? FeatureConstructorOptions\[keyof FeatureConstructorOptions & "Header"\] : never : any \}\[keyof `TFeatures`\]\> & `Header_Plugins`\<`TFeatures`, `TData`, `TValue`\> & `THeaderComponents` & `object` #### Returns `ReactNode` *** ### header ```ts header: Header; ``` Defined in: [createTableHook.tsx:338](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L338) *** ### selector? ```ts optional selector: undefined; ``` Defined in: [createTableHook.tsx:343](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L343) ================================================ FILE: docs/framework/react/reference/index/interfaces/AppTableComponent.md ================================================ --- id: AppTableComponent title: AppTableComponent --- # Interface: AppTableComponent()\ Defined in: [createTableHook.tsx:422](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L422) Component type for AppTable - root wrapper with optional Subscribe ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ## Call Signature ```ts AppTableComponent(props): ReactNode; ``` Defined in: [createTableHook.tsx:423](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L423) Component type for AppTable - root wrapper with optional Subscribe ### Parameters #### props [`AppTablePropsWithoutSelector`](AppTablePropsWithoutSelector.md) ### Returns `ReactNode` ## Call Signature ```ts AppTableComponent(props): ReactNode; ``` Defined in: [createTableHook.tsx:424](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L424) Component type for AppTable - root wrapper with optional Subscribe ### Type Parameters #### TSelected `TSelected` ### Parameters #### props [`AppTablePropsWithSelector`](AppTablePropsWithSelector.md)\<`TFeatures`, `TSelected`\> ### Returns `ReactNode` ================================================ FILE: docs/framework/react/reference/index/interfaces/AppTablePropsWithSelector.md ================================================ --- id: AppTablePropsWithSelector title: AppTablePropsWithSelector --- # Interface: AppTablePropsWithSelector\ Defined in: [createTableHook.tsx:285](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L285) Props for AppTable component - with selector ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TSelected `TSelected` ## Properties ### children() ```ts children: (state) => ReactNode; ``` Defined in: [createTableHook.tsx:289](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L289) #### Parameters ##### state `TSelected` #### Returns `ReactNode` *** ### selector() ```ts selector: (state) => TSelected; ``` Defined in: [createTableHook.tsx:290](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L290) #### Parameters ##### state `TableState`\<`TFeatures`\> #### Returns `TSelected` ================================================ FILE: docs/framework/react/reference/index/interfaces/AppTablePropsWithoutSelector.md ================================================ --- id: AppTablePropsWithoutSelector title: AppTablePropsWithoutSelector --- # Interface: AppTablePropsWithoutSelector Defined in: [createTableHook.tsx:277](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L277) Props for AppTable component - without selector ## Properties ### children ```ts children: ReactNode; ``` Defined in: [createTableHook.tsx:278](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L278) *** ### selector? ```ts optional selector: undefined; ``` Defined in: [createTableHook.tsx:279](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L279) ================================================ FILE: docs/framework/react/reference/index/type-aliases/AppCellContext.md ================================================ --- id: AppCellContext title: AppCellContext --- # Type Alias: AppCellContext\ ```ts type AppCellContext = object; ``` Defined in: [createTableHook.tsx:41](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L41) Enhanced CellContext with pre-bound cell components. The `cell` property includes the registered cellComponents. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Properties ### cell ```ts cell: Cell & TCellComponents & object; ``` Defined in: [createTableHook.tsx:47](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L47) #### Type Declaration ##### FlexRender() ```ts FlexRender: () => ReactNode; ``` ###### Returns `ReactNode` *** ### column ```ts column: Column; ``` Defined in: [createTableHook.tsx:49](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L49) *** ### getValue ```ts getValue: CellContext["getValue"]; ``` Defined in: [createTableHook.tsx:50](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L50) *** ### renderValue ```ts renderValue: CellContext["renderValue"]; ``` Defined in: [createTableHook.tsx:51](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L51) *** ### row ```ts row: Row; ``` Defined in: [createTableHook.tsx:52](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L52) *** ### table ```ts table: Table; ``` Defined in: [createTableHook.tsx:53](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L53) ================================================ FILE: docs/framework/react/reference/index/type-aliases/AppColumnHelper.md ================================================ --- id: AppColumnHelper title: AppColumnHelper --- # Type Alias: AppColumnHelper\ ```ts type AppColumnHelper = object; ``` Defined in: [createTableHook.tsx:162](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L162) Enhanced column helper with pre-bound components in cell/header/footer contexts. This enables TypeScript to know about the registered components when defining columns. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Properties ### accessor() ```ts accessor: (accessor, column) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef; ``` Defined in: [createTableHook.tsx:172](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L172) Creates a data column definition with an accessor key or function. The cell, header, and footer contexts include pre-bound components. #### Type Parameters ##### TAccessor `TAccessor` *extends* `AccessorFn`\<`TData`\> \| `DeepKeys`\<`TData`\> ##### TValue `TValue` *extends* `TAccessor` *extends* `AccessorFn`\<`TData`, infer TReturn\> ? `TReturn` : `TAccessor` *extends* `DeepKeys`\<`TData`\> ? `DeepValue`\<`TData`, `TAccessor`\> : `never` #### Parameters ##### accessor `TAccessor` ##### column `TAccessor` *extends* `AccessorFn`\<`TData`\> ? `AppColumnDefBase`\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `THeaderComponents`\> & `object` : `AppColumnDefBase`\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `THeaderComponents`\> #### Returns `TAccessor` *extends* `AccessorFn`\<`TData`\> ? `AccessorFnColumnDef`\<`TFeatures`, `TData`, `TValue`\> : `AccessorKeyColumnDef`\<`TFeatures`, `TData`, `TValue`\> *** ### columns() ```ts columns: (columns) => ColumnDef[] & [...TColumns]; ``` Defined in: [createTableHook.tsx:203](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L203) Wraps an array of column definitions to preserve each column's individual TValue type. #### Type Parameters ##### TColumns `TColumns` *extends* `ReadonlyArray`\<`ColumnDef`\<`TFeatures`, `TData`, `any`\>\> #### Parameters ##### columns \[`...TColumns`\] #### Returns `ColumnDef`\<`TFeatures`, `TData`, `any`\>[] & \[`...TColumns`\] *** ### display() ```ts display: (column) => DisplayColumnDef; ``` Defined in: [createTableHook.tsx:211](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L211) Creates a display column definition for non-data columns. The cell, header, and footer contexts include pre-bound components. #### Parameters ##### column `AppDisplayColumnDef`\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\> #### Returns `DisplayColumnDef`\<`TFeatures`, `TData`, `unknown`\> *** ### group() ```ts group: (column) => GroupColumnDef; ``` Defined in: [createTableHook.tsx:224](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L224) Creates a group column definition with nested child columns. The cell, header, and footer contexts include pre-bound components. #### Parameters ##### column `AppGroupColumnDef`\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\> #### Returns `GroupColumnDef`\<`TFeatures`, `TData`, `unknown`\> ================================================ FILE: docs/framework/react/reference/index/type-aliases/AppHeaderContext.md ================================================ --- id: AppHeaderContext title: AppHeaderContext --- # Type Alias: AppHeaderContext\ ```ts type AppHeaderContext = object; ``` Defined in: [createTableHook.tsx:60](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L60) Enhanced HeaderContext with pre-bound header components. The `header` property includes the registered headerComponents. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ## Properties ### column ```ts column: Column; ``` Defined in: [createTableHook.tsx:66](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L66) *** ### header ```ts header: Header & THeaderComponents & object; ``` Defined in: [createTableHook.tsx:67](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L67) #### Type Declaration ##### FlexRender() ```ts FlexRender: () => ReactNode; ``` ###### Returns `ReactNode` *** ### table ```ts table: Table; ``` Defined in: [createTableHook.tsx:69](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L69) ================================================ FILE: docs/framework/react/reference/index/type-aliases/AppReactTable.md ================================================ --- id: AppReactTable title: AppReactTable --- # Type Alias: AppReactTable\ ```ts type AppReactTable = ReactTable & NoInfer & object; ``` Defined in: [createTableHook.tsx:430](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L430) Extended table API returned by useAppTable with all App wrapper components ## Type Declaration ### AppCell ```ts AppCell: AppCellComponent>; ``` Wraps a cell and provides cell context with pre-bound cellComponents. Optionally accepts a selector for Subscribe functionality. #### Example ```tsx // Without selector {(c) =>
{filters.length}{sorting.length} sorted
...
// With selector - children receives selected state s.pagination}> {(pagination) =>
Page {pagination.pageIndex}
}
``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ================================================ FILE: docs/framework/react/reference/index/type-aliases/CreateTableHookOptions.md ================================================ --- id: CreateTableHookOptions title: CreateTableHookOptions --- # Type Alias: CreateTableHookOptions\ ```ts type CreateTableHookOptions = Omit, "columns" | "data" | "store" | "state" | "initialState"> & object; ``` Defined in: [createTableHook.tsx:242](https://github.com/TanStack/table/blob/main/packages/react-table/src/createTableHook.tsx#L242) Options for creating a table hook with pre-bound components and default table options. Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. ## Type Declaration ### cellComponents? ```ts optional cellComponents: TCellComponents; ``` Cell-level components that need access to the cell instance. These are available on the cell object passed to AppCell's children. Use `useCellContext()` inside these components. #### Example ```ts { TextCell, NumberCell, DateCell, CurrencyCell } ``` ### headerComponents? ```ts optional headerComponents: THeaderComponents; ``` Header-level components that need access to the header instance. These are available on the header object passed to AppHeader/AppFooter's children. Use `useHeaderContext()` inside these components. #### Example ```ts { SortIndicator, ColumnFilter, ResizeHandle } ``` ### tableComponents? ```ts optional tableComponents: TTableComponents; ``` Table-level components that need access to the table instance. These are available directly on the table object returned by useAppTable. Use `useTableContext()` inside these components. #### Example ```ts { PaginationControls, GlobalFilter, RowCount } ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TTableComponents `TTableComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### TCellComponents `TCellComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ### THeaderComponents `THeaderComponents` *extends* `Record`\<`string`, `ComponentType`\<`any`\>\> ================================================ FILE: docs/framework/react/reference/index/type-aliases/FlexRenderProps.md ================================================ --- id: FlexRenderProps title: FlexRenderProps --- # Type Alias: FlexRenderProps\ ```ts type FlexRenderProps = | { cell: Cell; footer?: never; header?: never; } | { cell?: never; footer?: never; header: Header; } | { cell?: never; footer: Header; header?: never; }; ``` Defined in: [FlexRender.tsx:63](https://github.com/TanStack/table/blob/main/packages/react-table/src/FlexRender.tsx#L63) Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. Only one prop (`cell`, `header`, or `footer`) may be passed. ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TValue `TValue` *extends* `CellData` = `CellData` ## Examples ```ts ``` ```ts ``` ```ts ``` ================================================ FILE: docs/framework/react/reference/index/type-aliases/ReactTable.md ================================================ --- id: ReactTable title: ReactTable --- # Type Alias: ReactTable\ ```ts type ReactTable = Table & object; ``` Defined in: [useTable.ts:23](https://github.com/TanStack/table/blob/main/packages/react-table/src/useTable.ts#L23) ## Type Declaration ### FlexRender() ```ts FlexRender: (props) => ReactNode; ``` A React component that renders headers, cells, or footers with custom markup. Use this utility component instead of manually calling flexRender. #### Type Parameters ##### TValue `TValue` *extends* `CellData` = `CellData` #### Parameters ##### props [`FlexRenderProps`](FlexRenderProps.md)\<`TFeatures`, `TData`, `TValue`\> #### Returns `ReactNode` #### Example ```tsx ``` This replaces calling `flexRender` directly like this: ```tsx flexRender(cell.column.columnDef.cell, cell.getContext()) flexRender(header.column.columnDef.header, header.getContext()) flexRender(footer.column.columnDef.footer, footer.getContext()) ``` ### state ```ts readonly state: Readonly; ``` The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `useTable`. #### Example ```ts const table = useTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state console.log(table.state.globalFilter) ``` ### Subscribe() ```ts Subscribe: (props) => ReturnType; ``` A React HOC (Higher Order Component) that allows you to subscribe to the table state. This is useful for opting into state re-renders for specific parts of the table state. #### Type Parameters ##### TSelected `TSelected` #### Parameters ##### props ###### children (`state`) => `ReactNode` \| `ReactNode` ###### selector (`state`) => `TSelected` #### Returns `ReturnType`\<`FunctionComponent`\> #### Example ```ts ({ rowSelection: state.rowSelection })}> {({ rowSelection }) => ( // important to include `{() => {()}}` syntax // render the row ))} ``` ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` = \{ \} ================================================ FILE: docs/framework/react/reference/index/type-aliases/Renderable.md ================================================ --- id: Renderable title: Renderable --- # Type Alias: Renderable\ ```ts type Renderable = ReactNode | ComponentType; ``` Defined in: [FlexRender.tsx:11](https://github.com/TanStack/table/blob/main/packages/react-table/src/FlexRender.tsx#L11) ## Type Parameters ### TProps `TProps` ================================================ FILE: docs/framework/react/reference/index/type-aliases/SubscribeProps.md ================================================ --- id: SubscribeProps title: SubscribeProps --- # Type Alias: SubscribeProps\ ```ts type SubscribeProps = object; ``` Defined in: [Subscribe.ts:12](https://github.com/TanStack/table/blob/main/packages/react-table/src/Subscribe.ts#L12) ## Type Parameters ### TFeatures `TFeatures` *extends* `TableFeatures` ### TData `TData` *extends* `RowData` ### TSelected `TSelected` = \{ \} ## Properties ### children ```ts children: (state) => ReactNode | ReactNode; ``` Defined in: [Subscribe.ts:30](https://github.com/TanStack/table/blob/main/packages/react-table/src/Subscribe.ts#L30) The children to render. Can be a function that receives the selected state, or a React node. *** ### selector() ```ts selector: (state) => TSelected; ``` Defined in: [Subscribe.ts:26](https://github.com/TanStack/table/blob/main/packages/react-table/src/Subscribe.ts#L26) A selector function that selects the part of the table state to subscribe to. This allows for fine-grained reactivity by only re-rendering when the selected state changes. #### Parameters ##### state `NoInfer`\<`TableState`\<`TFeatures`\>\> #### Returns `TSelected` *** ### table ```ts table: Table; ``` Defined in: [Subscribe.ts:21](https://github.com/TanStack/table/blob/main/packages/react-table/src/Subscribe.ts#L21) The table instance to subscribe to. Required when using as a standalone component. Not needed when using as `table.Subscribe`. ================================================ FILE: docs/framework/react/reference/index.md ================================================ --- id: "@tanstack/react-table" title: "@tanstack/react-table" --- # @tanstack/react-table ## Modules - [index](index/index.md) - [legacy](legacy/index.md) ================================================ FILE: docs/framework/react/reference/legacy/functions/getCoreRowModel.md ================================================ --- id: getCoreRowModel title: getCoreRowModel --- # ~~Function: getCoreRowModel()~~ ```ts function getCoreRowModel(): RowModelFactory; ``` Defined in: [useLegacyTable.ts:147](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L147) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `RowModelFactory`\<`TData`\> ## Deprecated The core row model is always created automatically in v9. This is a stub function for v8 API compatibility with `useLegacyTable`. It does nothing - the core row model is always available. ================================================ FILE: docs/framework/react/reference/legacy/functions/getExpandedRowModel.md ================================================ --- id: getExpandedRowModel title: getExpandedRowModel --- # ~~Function: getExpandedRowModel()~~ ```ts function getExpandedRowModel(): RowModelFactory; ``` Defined in: [useLegacyTable.ts:87](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L87) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `RowModelFactory`\<`TData`\> ## Deprecated Use `createExpandedRowModel()` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the expanded row model. ================================================ FILE: docs/framework/react/reference/legacy/functions/getFacetedMinMaxValues.md ================================================ --- id: getFacetedMinMaxValues title: getFacetedMinMaxValues --- # ~~Function: getFacetedMinMaxValues()~~ ```ts function getFacetedMinMaxValues(): FacetedMinMaxValuesFactory; ``` Defined in: [useLegacyTable.ts:123](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L123) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `FacetedMinMaxValuesFactory`\<`TData`\> ## Deprecated Use `createFacetedMinMaxValues()` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the faceted min/max values. ================================================ FILE: docs/framework/react/reference/legacy/functions/getFacetedRowModel.md ================================================ --- id: getFacetedRowModel title: getFacetedRowModel --- # ~~Function: getFacetedRowModel()~~ ```ts function getFacetedRowModel(): FacetedRowModelFactory; ``` Defined in: [useLegacyTable.ts:111](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L111) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `FacetedRowModelFactory`\<`TData`\> ## Deprecated Use `createFacetedRowModel()` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the faceted row model. ================================================ FILE: docs/framework/react/reference/legacy/functions/getFacetedUniqueValues.md ================================================ --- id: getFacetedUniqueValues title: getFacetedUniqueValues --- # ~~Function: getFacetedUniqueValues()~~ ```ts function getFacetedUniqueValues(): FacetedUniqueValuesFactory; ``` Defined in: [useLegacyTable.ts:135](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L135) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `FacetedUniqueValuesFactory`\<`TData`\> ## Deprecated Use `createFacetedUniqueValues()` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the faceted unique values. ================================================ FILE: docs/framework/react/reference/legacy/functions/getFilteredRowModel.md ================================================ --- id: getFilteredRowModel title: getFilteredRowModel --- # ~~Function: getFilteredRowModel()~~ ```ts function getFilteredRowModel(): RowModelFactory; ``` Defined in: [useLegacyTable.ts:51](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L51) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `RowModelFactory`\<`TData`\> ## Deprecated Use `createFilteredRowModel(filterFns)` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the filtered row model. ================================================ FILE: docs/framework/react/reference/legacy/functions/getGroupedRowModel.md ================================================ --- id: getGroupedRowModel title: getGroupedRowModel --- # ~~Function: getGroupedRowModel()~~ ```ts function getGroupedRowModel(): RowModelFactory; ``` Defined in: [useLegacyTable.ts:99](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L99) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `RowModelFactory`\<`TData`\> ## Deprecated Use `createGroupedRowModel(aggregationFns)` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the grouped row model. ================================================ FILE: docs/framework/react/reference/legacy/functions/getPaginationRowModel.md ================================================ --- id: getPaginationRowModel title: getPaginationRowModel --- # ~~Function: getPaginationRowModel()~~ ```ts function getPaginationRowModel(): RowModelFactory; ``` Defined in: [useLegacyTable.ts:75](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L75) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `RowModelFactory`\<`TData`\> ## Deprecated Use `createPaginatedRowModel()` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the paginated row model. ================================================ FILE: docs/framework/react/reference/legacy/functions/getSortedRowModel.md ================================================ --- id: getSortedRowModel title: getSortedRowModel --- # ~~Function: getSortedRowModel()~~ ```ts function getSortedRowModel(): RowModelFactory; ``` Defined in: [useLegacyTable.ts:63](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L63) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `RowModelFactory`\<`TData`\> ## Deprecated Use `createSortedRowModel(sortFns)` with the new `useTable` hook instead. This is a stub function for v8 API compatibility with `useLegacyTable`. It acts as a marker to enable the sorted row model. ================================================ FILE: docs/framework/react/reference/legacy/functions/legacyCreateColumnHelper.md ================================================ --- id: legacyCreateColumnHelper title: legacyCreateColumnHelper --- # ~~Function: legacyCreateColumnHelper()~~ ```ts function legacyCreateColumnHelper(): ColumnHelper; ``` Defined in: [useLegacyTable.ts:321](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L321) ## Type Parameters ### TData `TData` *extends* `RowData` ## Returns `ColumnHelper`\<`StockFeatures`, `TData`\> ## Deprecated Use `createColumnHelper()` with useTable instead. A column helper with StockFeatures pre-bound for use with useLegacyTable. Only requires TData—no need to specify TFeatures. ================================================ FILE: docs/framework/react/reference/legacy/functions/useLegacyTable.md ================================================ --- id: useLegacyTable title: useLegacyTable --- # ~~Function: useLegacyTable()~~ ```ts function useLegacyTable(options): LegacyReactTable; ``` Defined in: [useLegacyTable.ts:363](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L363) ## Type Parameters ### TData `TData` *extends* `RowData` ## Parameters ### options [`LegacyTableOptions`](../type-aliases/LegacyTableOptions.md)\<`TData`\> Legacy v8-style table options ## Returns [`LegacyReactTable`](../type-aliases/LegacyReactTable.md)\<`TData`\> A table instance with the full state subscribed and a `getState()` method ## Deprecated This hook is provided as a compatibility layer for migrating from TanStack Table v8. Use the new `useTable` hook instead with explicit `_features` and `_rowModels`: ```tsx // New v9 API const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, }) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, }) ``` Key differences from v8: - Features are tree-shakeable - only import what you use - Row models are explicitly passed via `_rowModels` - Use `table.Subscribe` for fine-grained re-renders - State is accessed via `table.state` after selecting with the 2nd argument ================================================ FILE: docs/framework/react/reference/legacy/index.md ================================================ --- id: legacy title: legacy --- # legacy ## Interfaces - [LegacyRowModelOptions](interfaces/LegacyRowModelOptions.md) ## Type Aliases - [~~LegacyCell~~](type-aliases/LegacyCell.md) - [~~LegacyColumn~~](type-aliases/LegacyColumn.md) - [~~LegacyColumnDef~~](type-aliases/LegacyColumnDef.md) - [~~LegacyHeader~~](type-aliases/LegacyHeader.md) - [~~LegacyHeaderGroup~~](type-aliases/LegacyHeaderGroup.md) - [~~LegacyReactTable~~](type-aliases/LegacyReactTable.md) - [~~LegacyRow~~](type-aliases/LegacyRow.md) - [~~LegacyTable~~](type-aliases/LegacyTable.md) - [~~LegacyTableOptions~~](type-aliases/LegacyTableOptions.md) ## Functions - [~~getCoreRowModel~~](functions/getCoreRowModel.md) - [~~getExpandedRowModel~~](functions/getExpandedRowModel.md) - [~~getFacetedMinMaxValues~~](functions/getFacetedMinMaxValues.md) - [~~getFacetedRowModel~~](functions/getFacetedRowModel.md) - [~~getFacetedUniqueValues~~](functions/getFacetedUniqueValues.md) - [~~getFilteredRowModel~~](functions/getFilteredRowModel.md) - [~~getGroupedRowModel~~](functions/getGroupedRowModel.md) - [~~getPaginationRowModel~~](functions/getPaginationRowModel.md) - [~~getSortedRowModel~~](functions/getSortedRowModel.md) - [~~legacyCreateColumnHelper~~](functions/legacyCreateColumnHelper.md) - [~~useLegacyTable~~](functions/useLegacyTable.md) ================================================ FILE: docs/framework/react/reference/legacy/interfaces/LegacyRowModelOptions.md ================================================ --- id: LegacyRowModelOptions title: LegacyRowModelOptions --- # Interface: LegacyRowModelOptions\ Defined in: [useLegacyTable.ts:191](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L191) Legacy v8-style row model options ## Type Parameters ### TData `TData` *extends* `RowData` ## Properties ### ~~getCoreRowModel?~~ ```ts optional getCoreRowModel: RowModelFactory; ``` Defined in: [useLegacyTable.ts:196](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L196) Returns the core row model for the table. #### Deprecated This option is no longer needed in v9. The core row model is always created automatically. *** ### ~~getExpandedRowModel?~~ ```ts optional getExpandedRowModel: RowModelFactory; ``` Defined in: [useLegacyTable.ts:216](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L216) Returns the expanded row model for the table. #### Deprecated Use `_rowModels.expandedRowModel` with `createExpandedRowModel()` instead. *** ### ~~getFacetedMinMaxValues?~~ ```ts optional getFacetedMinMaxValues: FacetedMinMaxValuesFactory; ``` Defined in: [useLegacyTable.ts:231](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L231) Returns the faceted min/max values for a column. #### Deprecated Use `_rowModels.facetedMinMaxValues` with `createFacetedMinMaxValues()` instead. *** ### ~~getFacetedRowModel?~~ ```ts optional getFacetedRowModel: FacetedRowModelFactory; ``` Defined in: [useLegacyTable.ts:226](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L226) Returns the faceted row model for a column. #### Deprecated Use `_rowModels.facetedRowModel` with `createFacetedRowModel()` instead. *** ### ~~getFacetedUniqueValues?~~ ```ts optional getFacetedUniqueValues: FacetedUniqueValuesFactory; ``` Defined in: [useLegacyTable.ts:236](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L236) Returns the faceted unique values for a column. #### Deprecated Use `_rowModels.facetedUniqueValues` with `createFacetedUniqueValues()` instead. *** ### ~~getFilteredRowModel?~~ ```ts optional getFilteredRowModel: RowModelFactory; ``` Defined in: [useLegacyTable.ts:201](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L201) Returns the filtered row model for the table. #### Deprecated Use `_rowModels.filteredRowModel` with `createFilteredRowModel(filterFns)` instead. *** ### ~~getGroupedRowModel?~~ ```ts optional getGroupedRowModel: RowModelFactory; ``` Defined in: [useLegacyTable.ts:221](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L221) Returns the grouped row model for the table. #### Deprecated Use `_rowModels.groupedRowModel` with `createGroupedRowModel(aggregationFns)` instead. *** ### ~~getPaginationRowModel?~~ ```ts optional getPaginationRowModel: RowModelFactory; ``` Defined in: [useLegacyTable.ts:211](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L211) Returns the paginated row model for the table. #### Deprecated Use `_rowModels.paginatedRowModel` with `createPaginatedRowModel()` instead. *** ### ~~getSortedRowModel?~~ ```ts optional getSortedRowModel: RowModelFactory; ``` Defined in: [useLegacyTable.ts:206](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L206) Returns the sorted row model for the table. #### Deprecated Use `_rowModels.sortedRowModel` with `createSortedRowModel(sortFns)` instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyCell.md ================================================ --- id: LegacyCell title: LegacyCell --- # ~~Type Alias: LegacyCell\~~ ```ts type LegacyCell = Cell; ``` Defined in: [useLegacyTable.ts:285](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L285) ## Type Parameters ### TData `TData` *extends* `RowData` ### TValue `TValue` = `unknown` ## Deprecated Use Cell with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyColumn.md ================================================ --- id: LegacyColumn title: LegacyColumn --- # ~~Type Alias: LegacyColumn\~~ ```ts type LegacyColumn = Column; ``` Defined in: [useLegacyTable.ts:275](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L275) ## Type Parameters ### TData `TData` *extends* `RowData` ### TValue `TValue` = `unknown` ## Deprecated Use Column with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyColumnDef.md ================================================ --- id: LegacyColumnDef title: LegacyColumnDef --- # ~~Type Alias: LegacyColumnDef\~~ ```ts type LegacyColumnDef = ColumnDef; ``` Defined in: [useLegacyTable.ts:305](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L305) ## Type Parameters ### TData `TData` *extends* `RowData` ### TValue `TValue` = `unknown` ## Deprecated Use ColumnDef with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyHeader.md ================================================ --- id: LegacyHeader title: LegacyHeader --- # ~~Type Alias: LegacyHeader\~~ ```ts type LegacyHeader = Header; ``` Defined in: [useLegacyTable.ts:292](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L292) ## Type Parameters ### TData `TData` *extends* `RowData` ### TValue `TValue` = `unknown` ## Deprecated Use Header with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyHeaderGroup.md ================================================ --- id: LegacyHeaderGroup title: LegacyHeaderGroup --- # ~~Type Alias: LegacyHeaderGroup\~~ ```ts type LegacyHeaderGroup = HeaderGroup; ``` Defined in: [useLegacyTable.ts:299](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L299) ## Type Parameters ### TData `TData` *extends* `RowData` ## Deprecated Use HeaderGroup with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyReactTable.md ================================================ --- id: LegacyReactTable title: LegacyReactTable --- # ~~Type Alias: LegacyReactTable\~~ ```ts type LegacyReactTable = ReactTable> & object; ``` Defined in: [useLegacyTable.ts:258](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L258) Legacy table instance type that includes the v8-style `getState()` method. ## Type Declaration ### ~~getState()~~ ```ts getState: () => TableState; ``` Returns the current table state. #### Returns `TableState`\<`StockFeatures`\> #### Deprecated In v9, access state directly via `table.state` or use `table.store.state` for the full state. ## Type Parameters ### TData `TData` *extends* `RowData` ## Deprecated Use `useTable` with explicit state selection instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyRow.md ================================================ --- id: LegacyRow title: LegacyRow --- # ~~Type Alias: LegacyRow\~~ ```ts type LegacyRow = Row; ``` Defined in: [useLegacyTable.ts:282](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L282) ## Type Parameters ### TData `TData` *extends* `RowData` ## Deprecated Use Row with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyTable.md ================================================ --- id: LegacyTable title: LegacyTable --- # ~~Type Alias: LegacyTable\~~ ```ts type LegacyTable = Table; ``` Defined in: [useLegacyTable.ts:309](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L309) ## Type Parameters ### TData `TData` *extends* `RowData` ## Deprecated Use Table with useTable instead. ================================================ FILE: docs/framework/react/reference/legacy/type-aliases/LegacyTableOptions.md ================================================ --- id: LegacyTableOptions title: LegacyTableOptions --- # ~~Type Alias: LegacyTableOptions\~~ ```ts type LegacyTableOptions = Omit, "_features" | "_rowModels"> & LegacyRowModelOptions; ``` Defined in: [useLegacyTable.ts:247](https://github.com/TanStack/table/blob/main/packages/react-table/src/useLegacyTable.ts#L247) Legacy v8-style table options that work with useLegacyTable. This type omits `_features` and `_rowModels` and instead accepts the v8-style `get*RowModel` function options. ## Type Parameters ### TData `TData` *extends* `RowData` ## Deprecated This is a compatibility layer for migrating from v8. Use `useTable` with explicit `_features` and `_rowModels` instead. ================================================ FILE: docs/framework/solid/guide/table-state.md ================================================ --- title: Table State (Solid) Guide --- ## Table State (Solid) Guide TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table. ### Accessing Table State You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API. ```jsx const table = createTable({ columns, get data() { return data() }, //... }) console.log(table.store.state) //access the entire internal state console.log(table.store.state.rowSelection) //access just the row selection state ``` ### Custom Initial State If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance. ```jsx const table = createTable({ columns, data, initialState: { columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order columnVisibility: { id: false //hide the id column by default }, expanded: true, //expand all rows by default sorting: [ { id: 'age', desc: true //sort by age in descending order by default } ] }, //... }) ``` > **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`. ### Controlled State If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options. #### Individual Controlled State You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis. In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance. Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values. ```jsx const [columnFilters, setColumnFilters] = createSignal([]) //no default filters const [sorting, setSorting] = createSignal([{ id: 'age', desc: true, //sort by age in descending order by default }]) const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 15 }) //Use our controlled state values to fetch data const tableQuery = createQuery({ queryKey: ['users', columnFilters, sorting, pagination], queryFn: () => fetchUsers(columnFilters, sorting, pagination), //... }) const table = createTable({ columns, get data() { return tableQuery.data() }, //... state: { get columnFilters() { return columnFilters() //pass controlled state back to the table (overrides internal state) }, get sorting() { return sorting() }, get pagination() { return pagination() }, }, onColumnFiltersChange: setColumnFilters, //hoist columnFilters state into our own state management onSortingChange: setSorting, onPaginationChange: setPagination, }) //... ``` #### Fully Controlled State Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a solid tree, like `columnSizingInfo` state`, might cause bad performance issues. A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below. ```jsx //create a table instance with default state values const table = createTable({ columns, get data() { return data() }, //... Note: `state` values are NOT passed in yet }) const [state, setState] = createSignal({ ...table.initialState, //populate the initial state with all of the default state values from the table instance pagination: { pageIndex: 0, pageSize: 15 //optionally customize the initial pagination state. } }) //Use the table.setOptions API to merge our fully controlled state onto the table instance table.setOptions(prev => ({ ...prev, //preserve any other options that we have set up above get state() { return state() //our fully controlled state overrides the internal state }, onStateChange: setState //any state changes will be pushed up to our own state management })) ``` ### On State Change Callbacks So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of. #### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**. Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value. ```jsx const [sorting, setSorting] = createSignal([]) //... const table = createTable({ columns, data, //... state: { get sorting() { return sorting() //required because we are using `onSortingChange` }, }, onSortingChange: setSorting, //makes the `state.sorting` controlled }) ``` #### 2. **Updaters can either be raw values or callback functions**. The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React (Solid Setters). The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value. What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value. ```jsx const [sorting, setSorting] = createSignal([]) const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 10 }) const table = createTable({ get columns() { return columns() }, get data() { return data() }, //... state: { get pagination() { return pagination() }, get sorting() { return sorting() }, } //syntax 1 onPaginationChange: (updater) => { setPagination(old => { const newPaginationValue = updater instanceof Function ? updater(old) : updater //do something with the new pagination value //... return newPaginationValue }) }, //syntax 2 onSortingChange: (updater) => { const newSortingValue = updater instanceof Function ? updater(sorting) : updater //do something with the new sorting value //... setSorting(updater) //normal state update } }) ``` ### State Types All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling. ```tsx import { createTable, type SortingState } from '@tanstack/solid-table' //... const [sorting, setSorting] = createSignal([ { id: 'age', //you should get autocomplete for the `id` and `desc` properties desc: true, } ]) ``` ================================================ FILE: docs/framework/solid/solid-table.md ================================================ --- title: Solid Table --- The `@tanstack/solid-table` adapter is a wrapper around the core table logic. Most of it's job is related to managing state the "solid" way, providing types and the rendering implementation of cell/header/footer templates. ## `createTable` Takes an `options` object and returns a table. ```tsx import { createTable } from '@tanstack/solid-table' function App() { const table = createTable(options) // ...render your table } ``` ================================================ FILE: docs/framework/svelte/guide/table-state.md ================================================ --- title: Table State (Svelte) Guide --- ## Table State (Svelte) Guide TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table. ### Accessing Table State You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API. ```ts const table = createTable({ columns, get data() { return data }, //... }) console.log(table.store.state) //access the entire internal state console.log(table.store.state.rowSelection) //access just the row selection state ``` ### Custom Initial State If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance. ```ts const table = createTable({ columns, data, initialState: { columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order columnVisibility: { id: false //hide the id column by default }, expanded: true, //expand all rows by default sorting: [ { id: 'age', desc: true //sort by age in descending order by default } ] }, //... }) ``` > **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will overwrite any corresponding value in `initialState`. ### Controlled State If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options. #### Individual Controlled State You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis. In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance. Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values. ```ts let sorting: SortingState = $state([ { id: 'age', desc: true, //sort by age in descending order by default }, ]) function setSorting(updater: Updater) { if (updater instanceof Function) { sorting = updater(sorting) } else sorting = updater } let columnFilters: ColumnFiltersState = $state([]) //no default filters function setColumnFilters(updater: Updater) { if (updater instanceof Function) { columnFilters = updater(columnFilters) } else columnFilters = updater } let pagination: PaginationState = $state( { pageIndex: 0, pageSize: 15 } //default pagination ) function setPagination(updater: Updater) { if (updater instanceof Function) { pagination = updater(pagination) } else pagination = updater } let data = $state(makeData(100_000)) const options = { columns, get data() { return data } //... state: { get sorting() { return sorting }, get columnFilters() { return columnFilters }, get pagination() { return pagination } }, onColumnFiltersChange: setColumnFilters, //hoist columnFilters state into our own state management onSortingChange: setSorting, onPaginationChange: setPagination, } const table = createTable(options) //... ``` #### Fully Controlled State Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a Svelte tree, like `columnSizingInfo` state, might cause bad performance issues. A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below. ```ts //create a table instance with default state values const table = createTable({ columns, get data() { return data }, //... Note: `state` values are NOT passed in yet }) const state = $state({ ...table.initialState, //populate the initial state with all of the default state values from the table instance pagination: { pageIndex: 0, pageSize: 15 //optionally customize the initial pagination state. } }) const setState = updater => { if (updater instanceof Function) { state = updater(state) } state = updater } //Use the table.setOptions API to merge our fully controlled state onto the table instance table.setOptions(prev => ({ ...prev, //preserve any other options that we have set up above get state() { return state //our fully controlled state overrides the internal state }, onStateChange: setState //any state changes will be pushed up to our own state management })) ``` ### On State Change Callbacks So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about using these options that you should be aware of. #### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**. Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value. ```ts let sorting = $state([]) const setSorting = updater => { if (updater instanceof Function) { sorting = updater(sorting) } else sorting = updater } // ... const table = createTable({ columns, data, //... state: { get sorting() { return sorting //required because we are using `onSortingChange` }, }, onSortingChange: setSorting, //makes the `state.sorting` controlled }) ``` #### 2. **Updaters can either be raw values or callback functions**. The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value. What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value. This is why you see the `if (updater instanceof Function)` check in the `setState` functions in the examples above. ### State Types All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling. ```ts import { createTable, type SortingState, type Updater } from '@tanstack/svelte-table' //... let sorting: SortingState[] = [ { id: 'age', //you should get autocomplete for the `id` and `desc` properties desc: true, } ] const setSorting = (updater: Updater) => { if (updater instanceof Function) { sorting = updater(sorting) } else sorting = updater } ``` ================================================ FILE: docs/framework/svelte/svelte-table.md ================================================ --- title: Svelte Table --- > **IMPORTANT:** This version of `@tanstack/svelte-table` only supports **Svelte 5 or newer**. For Svelte 3/4 support, use version 8 of `@tanstack/svelte-table`. > Alternatively, you can still use `@tanstack/table-core` v9 with Svelte 3/4 by copying the source code from the [v8 `@tanstack/svelte-table`](https://github.com/TanStack/table/tree/v8/packages/svelte-table/src) as a custom adapter. The `@tanstack/svelte-table` adapter is a wrapper around the core table logic. Most of its job is related to managing state the "Svelte" way, providing types and the rendering implementation of cell/header/footer templates. ## Exports `@tanstack/svelte-table` re-exports all of `@tanstack/table-core`'s APIs and the following: ### `createTable` Takes an `options` object and returns a table. ```svelte ``` ### FlexRender A Svelte component for rendering cell/header/footer templates with dynamic values. FlexRender supports any type of renderable content supported by Svelte: - Scalar data types such as numbers, strings, etc. - Svelte components (when wrapped with `renderComponent`) - Svelte snippets (when wrapped with `renderSnippet`) Example: ```svelte {#snippet mailtoLink(email: string)} {email} {/snippet} {#each table.getRowModel().rows as row} {#each row.getVisibleCells() as cell} {/each} {/each}
``` ================================================ FILE: docs/framework/vanilla/guide/table-state.md ================================================ --- title: Table State (Vanilla JS) Guide --- ## Table State (Vanilla JS) Guide ================================================ FILE: docs/framework/vanilla/table-core.md ================================================ ================================================ FILE: docs/framework/vue/guide/table-state.md ================================================ --- title: Table State (Vue) Guide --- ## Table State (Vue) Guide TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table. ### Accessing Table State You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API. ```ts const table = useTable({ columns, data: dataRef, // Reactive data support //... }) console.log(table.store.state) //access the entire internal state console.log(table.store.state.rowSelection) //access just the row selection state ``` ### Using Reactive Data > **New in v8.20.0** The `useVueTable` hook now supports reactive data. This means you can pass a Vue `ref` or `computed` containing your data to the `data`-option. The table will automatically react to changes in the data. ```ts const columns = [ { accessor: 'id', Header: 'ID' }, { accessor: 'name', Header: 'Name' } ] const dataRef = ref([ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ]) const table = useVueTable({ columns, data: dataRef, // Pass the reactive data ref }) // Later, updating dataRef will automatically update the table dataRef.value = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Doe' } ] ``` > ⚠️ `shallowRef` is used under the hood for performance reasons, meaning that the data is not deeply reactive, only the `.value` is. To update the data you have to mutate the data directly. ```ts const dataRef = ref([ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ]) // This will NOT update the table ❌ dataRef.value.push({ id: 4, name: 'John' }) // This will update the table ✅ dataRef.value = [ ...dataRef.value, { id: 4, name: 'John' } ] ``` ### Custom Initial State If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance. ```jsx const table = useTable({ columns, data, initialState: { columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order columnVisibility: { id: false //hide the id column by default }, expanded: true, //expand all rows by default sorting: [ { id: 'age', desc: true //sort by age in descending order by default } ] }, //... }) ``` > **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`. ### Controlled State If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options. #### Individual Controlled State You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis. In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance. Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values. ```ts const columnFilters = ref([]) //no default filters const sorting = ref([{ id: 'age', desc: true, //sort by age in descending order by default }]) const pagination = ref({ pageIndex: 0, pageSize: 15 } //Use our controlled state values to fetch data const tableQuery = useQuery({ queryKey: ['users', columnFilters, sorting, pagination], queryFn: () => fetchUsers(columnFilters, sorting, pagination), //... }) const table = useTable({ columns, data: tableQuery.data, //... state: { get columnFilters() { return columnFilters.value }, get sorting() { return sorting.value }, get pagination() { return pagination.value } }, onColumnFiltersChange: updater => { columnFilters.value = updater instanceof Function ? updater(columnFilters.value) : updater }, onSortingChange: updater => { sorting.value = updater instanceof Function ? updater(sorting.value) : updater }, onPaginationChange: updater => { pagination.value = updater instanceof Function ? updater(pagination.value) : updater }, }) //... ``` #### Fully Controlled State Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a react tree, like `columnSizingInfo` state`, might cause bad performance issues. A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below. ```jsx //create a table instance with default state values const table = useTable({ get columns() { return columns.value }, data, //... Note: `state` values are NOT passed in yet }) const state = ref({ ...table.initialState, pagination: { pageIndex: 0, pageSize: 15 } }) const setState = updater => { state.value = updater instanceof Function ? updater(state.value) : updater } //Use the table.setOptions API to merge our fully controlled state onto the table instance table.setOptions(prev => ({ ...prev, //preserve any other options that we have set up above get state() { return state.value }, onStateChange: setState //any state changes will be pushed up to our own state management })) ``` ### On State Change Callbacks So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of. #### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**. Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value. ```jsx const sorting = ref([]) const setSorting = updater => { sorting.value = updater instanceof Function ? updater(sorting.value) : updater } //... const table = useTable({ columns, data, //... state: { get sorting() { return sorting //required because we are using `onSortingChange` }, }, onSortingChange: setSorting, //makes the `state.sorting` controlled }) ``` #### 2. **Updaters can either be raw values or callback functions**. The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value. What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value. This is why we have the `updater instanceof Function` check in the `setState` functions above. This check allows us to handle both raw values and callback functions in the same function. ### State Types All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling. ```tsx import { useTable, type SortingState } from '@tanstack/vue-table' //... const sorting = ref([ { id: 'age', //you should get autocomplete for the `id` and `desc` properties desc: true, } ]) ``` ================================================ FILE: docs/framework/vue/vue-table.md ================================================ --- title: Vue Table --- The `@tanstack/vue-table` adapter is a wrapper around the core table logic. Most of it's job is related to managing state the "vue" way, providing types and the rendering implementation of cell/header/footer templates. ## Exports `@tanstack/vue-table` re-exports all of `@tanstack/table-core`'s APIs and the following: ### `useTable` Takes an `options` object and returns a table. ```ts import { useTable } from '@tanstack/vue-table' const table = useTable(options) // ...render your table ``` ### `FlexRender` A Vue component for rendering cell/header/footer templates with dynamic values. Example: ```vue import { FlexRender } from '@tanstack/vue-table' ``` ================================================ FILE: docs/guide/cells.md ================================================ --- title: Cells Guide --- ## API [Cell API](../api/core/cell) ## Cells Guide This quick guide will discuss the different ways you can retrieve and interact with `cell` objects in TanStack Table. ### Where to Get Cells From Cells come from [Rows](./rows). Enough said, right? There are multiple `row` instance APIs you can use to retrieve the appropriate cells from a row depending on which features you are using. Most commonly, you will use the `row.getAllCells` or `row.getVisibleCells` APIs (if you are using column visibility features), but there are a handful of other similar APIs that you can use. ### Cell Objects Every cell object can be associated with a `` or similar cell element in your UI. There are a few properties and methods on `cell` objects that you can use to interact with the table state and extract cell values from the table based on the state of the table. #### Cell IDs Every cell object has an `id` property that makes it unique within the table instance. Each `cell.id` is constructed simply as a union of its parent row and column IDs separated by an underscore. ```js { id: `${row.id}_${column.id}` } ``` During grouping or aggregation features, the `cell.id` will have additional string appended to it. #### Cell Parent Objects Every cell stores a reference to its parent [row](./rows) and [column](./columns) objects. #### Access Cell Values The recommended way to access data values from a cell is to use either the `cell.getValue` or `cell.renderValue` APIs. Using either of these APIs will cache the results of the accessor functions and keep rendering efficient. The only difference between the two is that `cell.renderValue` will return either the value or the `renderFallbackValue` if the value is undefined, whereas `cell.getValue` will return the value or `undefined` if the value is undefined. > Note: The `cell.getValue` and `cell.renderValue` APIs are shortcuts `row.getValue` and `row.renderValue` APIs, respectively. ```js // Access data from any of the columns const firstName = cell.getValue('firstName') // read the cell value from the firstName column const renderedLastName = cell.renderValue('lastName') // render the value from the lastName column ``` #### Access Other Row Data from Any Cell Since every cell object is associated with its parent row, you can access any data from the original row that you are using in your table using `cell.row.original`. ```js // Even if we are in the scope of a different cell, we can still access the original row data const firstName = cell.row.original.firstName // { firstName: 'John', lastName: 'Doe' } ``` ### More Cell APIs Depending on the features that you are using for your table, there are dozens more useful APIs for interacting with cells. See each features' respective API docs or guide for more information. ### Cell Rendering You can just use the `cell.renderValue` or `cell.getValue` APIs to render the cells of your table. However, these APIs will only spit out the raw cell values (from accessor functions). If you are using the `cell: () => JSX` column definition options, you will want to use the `flexRender` API utility from your adapter. Using the `flexRender` API will allow the cell to be rendered correctly with any extra markup or JSX and it will call the callback function with the correct parameters. ```jsx import { flexRender } from '@tanstack/react-table' const columns = [ { accessorKey: 'fullName', cell: ({ cell, row }) => { return
{row.original.firstName} {row.original.lastName}
} //... } ] //... {row.getVisibleCells().map(cell => { return {flexRender(cell.column.columnDef.cell, cell.getContext())} })} ================================================ FILE: docs/guide/column-defs.md ================================================ --- title: Columns Definitions Guide --- ## API [Column Def](../api/core/column-def) ## Column Definitions Guide > Note: This guide is about setting up column definitions for your table and NOT about the actual [`column`](./columns) objects that are generated within the table instance. Column defs are the single most important part of building a table. They are responsible for: - Building the underlying data model that will be used for everything including sorting, filtering, grouping, etc. - Formatting the data model into what will be displayed in the table - Creating [header groups](../api/core/header-group), [headers](../api/core/header) and [footers](../api/core/column-def#footer) - Creating columns for display-only purposes, eg. action buttons, checkboxes, expanders, sparklines, etc. ## Column Def Types The following "types" of column defs aren't actually TypeScript types, but more so a way to talk about and describe overall categories of column defs: - `Accessor Columns` - Accessor columns have an underlying data model which means they can be sorted, filtered, grouped, etc. - `Display Columns` - Display columns do **not** have a data model which means they cannot be sorted, filtered, etc, but they can be used to display arbitrary content in the table, eg. a row actions button, checkbox, expander, etc. - `Grouping Columns` - Group columns do **not** have a data model so they too cannot be sorted, filtered, etc, and are used to group other columns together. It's common to define a header or footer for a column group. ## Column Helpers While column defs are just plain objects at the end of the day, a `createColumnHelper` function is exposed from the table core which, when called with your features type and row type, returns a utility for creating different column definition types with the highest type-safety possible. In v9, `createColumnHelper` requires two type parameters: `TFeatures` (from your `_features` object) and `TData` (your row type). Use `typeof _features` to get the features type. Here's an example of creating and using a column helper: ```tsx // Define your row shape type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const _features = tableFeatures({}) // or tableFeatures({ rowSortingFeature, ... }) const columnHelper = createColumnHelper() // Make some columns! Use columnHelper.columns([...]) for better type inference with nested groups const defaultColumns = columnHelper.columns([ // Display Column columnHelper.display({ id: 'actions', cell: props => , }), // Grouping Column columnHelper.group({ header: 'Name', footer: props => props.column.id, columns: [ // Accessor Column columnHelper.accessor('firstName', { cell: info => info.getValue(), footer: props => props.column.id, }), // Accessor Column columnHelper.accessor(row => row.lastName, { id: 'lastName', cell: info => info.getValue(), header: () => Last Name, footer: props => props.column.id, }), ], }), // Grouping Column columnHelper.group({ header: 'Info', footer: props => props.column.id, columns: [ // Accessor Column columnHelper.accessor('age', { header: () => 'Age', footer: props => props.column.id, }), // Grouping Column columnHelper.group({ header: 'More Info', columns: [ // Accessor Column columnHelper.accessor('visits', { header: () => Visits, footer: props => props.column.id, }), // Accessor Column columnHelper.accessor('status', { header: 'Status', footer: props => props.column.id, }), // Accessor Column columnHelper.accessor('progress', { header: 'Profile Progress', footer: props => props.column.id, }), ], }), ], }), ]) ``` ## Creating Accessor Columns Data columns are unique in that they must be configured to extract primitive values for each item in your `data` array. There are 3 ways to do this: - If your items are `objects`, use an object-key that corresponds to the value you want to extract. - If your items are nested `arrays`, use an array index that corresponds to the value you want to extract. - Use an accessor function that returns the value you want to extract. ## Object Keys If each of your items is an object with the following shape: ```tsx type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } ``` You could extract the `firstName` value like so: ```tsx columnHelper.accessor('firstName') // OR { accessorKey: 'firstName', } ``` ## Deep Keys If each of your items is an object with the following shape: ```tsx type Person = { name: { first: string last: string } info: { age: number visits: number } } ``` You could extract the `first` value like so: ```tsx columnHelper.accessor('name.first', { id: 'firstName', }) // OR { accessorKey: 'name.first', id: 'firstName', } ``` ## Array Indices If each of your items is an array with the following shape: ```tsx type Sales = [Date, number] ``` You could extract the `number` value like so: ```tsx columnHelper.accessor(1) // OR { accessorKey: 1, } ``` ## Accessor Functions If each of your items is an object with the following shape: ```tsx type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } ``` You could extract a computed full-name value like so: ```tsx columnHelper.accessor(row => `${row.firstName} ${row.lastName}`, { id: 'fullName', }) // OR { id: 'fullName', accessorFn: row => `${row.firstName} ${row.lastName}`, } ``` > 🧠 Remember, the accessed value is what is used to sort, filter, etc. so you'll want to make sure your accessor function returns a primitive value that can be manipulated in a meaningful way. If you return a non-primitive value like an object or array, you will need the appropriate filter/sort/grouping functions to manipulate them, or even supply your own! 😬 ## Unique Column IDs Columns are uniquely identified with 3 strategies: - If defining an accessor column with an object key or array index, the same will be used to uniquely identify the column. - Any periods (`.`) in an object key will be replaced by underscores (`_`). - If defining an accessor column with an accessor function - The columns `id` property will be used to uniquely identify the column OR - If a primitive `string` header is supplied, that header string will be used to uniquely identify the column > 🧠 An easy way to remember: If you define a column with an accessor function, either provide a string header or provide a unique `id` property. ## Column Formatting & Rendering By default, columns cells will display their data model value as a string. You can override this behavior by providing custom rendering implementations. Each implementation is provided relevant information about the cell, header or footer and returns something your framework adapter can render eg. JSX/Components/strings/etc. This will depend on which adapter you are using. There are a couple of formatters available to you: - `cell`: Used for formatting cells. - `aggregatedCell`: Used for formatting cells when aggregated. - `header`: Used for formatting headers. - `footer`: Used for formatting footers. ## Cell Formatting You can provide a custom cell formatter by passing a function to the `cell` property and using the `props.getValue()` function to access your cell's value: ```tsx columnHelper.accessor('firstName', { cell: props => {props.getValue().toUpperCase()}, }) ``` Cell formatters are also provided the `row` and `table` objects, allowing you to customize the cell formatting beyond just the cell value. The example below provides `firstName` as the accessor, but also displays a prefixed user ID located on the original row object: ```tsx columnHelper.accessor('firstName', { cell: props => ( {`${props.row.original.id} - ${props.getValue()}`} ), }) ``` ## Aggregated Cell Formatting For more info on aggregated cells, see [grouping](./grouping). ## Header & Footer Formatting Headers and footers do not have access to row data, but still use the same concepts for displaying custom content. ================================================ FILE: docs/guide/column-faceting.md ================================================ --- title: Column Faceting Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [filters-faceted](../framework/react/examples/filters-faceted) ## API [Column Faceting API](../api/features/column-faceting) ## Column Faceting Guide Column Faceting is a feature that allows you to generate lists of values for a given column from that column's data. For example, a list of unique values in a column can be generated from all rows in that column to be used as search suggestions in an autocomplete filter component. Or, a tuple of minimum and maximum values can be generated from a column of numbers to be used as a range for a range slider filter component. ### Column Faceting Row Models In order to use any of the column faceting features, add the `columnFacetingFeature` to your features and the appropriate faceted row models to `_rowModels`. ```ts import { useTable, tableFeatures, columnFacetingFeature, createFacetedRowModel, createFacetedMinMaxValues, createFacetedUniqueValues, } from '@tanstack/react-table' const _features = tableFeatures({ columnFacetingFeature }) const table = useTable({ _features, _rowModels: { facetedRowModel: createFacetedRowModel(), // required for faceting (other faceted row models depend on this) facetedMinMaxValues: createFacetedMinMaxValues(), // if you need min/max values facetedUniqueValues: createFacetedUniqueValues(), // if you need a list of unique values }, columns, data, }) ``` First, you must include the `facetedRowModel`. This row model will generate a list of values for a given column. If you need a list of unique values, include the `facetedUniqueValues` row model. If you need a tuple of minimum and maximum values, include the `facetedMinMaxValues` row model. ### Use Faceted Row Models Once you have included the appropriate row models in your table options, you will be able to use the faceting column instance APIs to access the lists of values generated by the faceted row models. ```ts // list of unique values for autocomplete filter const autoCompleteSuggestions = Array.from(column.getFacetedUniqueValues().keys()) .sort() .slice(0, 5000); ``` ```ts // tuple of min and max values for range filter const [min, max] = column.getFacetedMinMaxValues() ?? [0, 1]; ``` ### Custom (Server-Side) Faceting If instead of using the built-in client-side faceting features, you can implement your own faceting logic on the server-side and pass the faceted values to the client-side. You can use the `getFacetedUniqueValues` and `getFacetedMinMaxValues` table options to resolve the faceted values from the server-side. ```ts const facetingQuery = useQuery( //... ) const table = useTable({ _features, _rowModels: { facetedRowModel: createFacetedRowModel(), facetedUniqueValues: createFacetedUniqueValues(), facetedMinMaxValues: createFacetedMinMaxValues(), }, columns, data, getFacetedUniqueValues: (table, columnId) => { const uniqueValueMap = new Map() //... return uniqueValueMap }, getFacetedMinMaxValues: (table, columnId) => { //... return [min, max] }, //... }) ``` Alternatively, you don't have to put any of your faceting logic through the TanStack Table APIs at all. Just fetch your lists and pass them to your filter components directly. ================================================ FILE: docs/guide/column-filtering.md ================================================ --- title: Column Filtering Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [Column Filters](../framework/react/examples/filters) - [Faceted Filters](../framework/react/examples/filters-faceted) (Autocomplete and Range filters) - [Fuzzy Search](../framework/react/examples/filters-fuzzy) (Match Sorter) - [Editable Data](../framework/react/examples/editable-data) - [Expanding](../framework/react/examples/expanding) (Filtering from Sub-Rows) - [Grouping](../framework/react/examples/grouping) - [Pagination](../framework/react/examples/pagination) - [Row Selection](../framework/react/examples/row-selection) ## API [Column Filtering API](../api/features/column-filtering) ## Column Filtering Guide Filtering comes in 2 flavors: Column Filtering and Global Filtering. This guide will focus on column filtering, which is a filter that is applied to a single column's accessor value. TanStack table supports both client-side and manual server-side filtering. This guide will go over how to implement and customize both, and help you decide which one is best for your use-case. ### Client-Side vs Server-Side Filtering If you have a large dataset, you may not want to load all of that data into the client's browser in order to filter it. In this case, you will most likely want to implement server-side filtering, sorting, pagination, etc. However, as also discussed in the [Pagination Guide](./pagination#should-you-use-client-side-pagination), a lot of developers underestimate how many rows can be loaded client-side without a performance hit. The TanStack table examples are often tested to handle up to 100,000 rows or more with decent performance for client-side filtering, sorting, pagination, and grouping. This doesn't necessarily mean that your app will be able to handle that many rows, but if your table is only going to have a few thousand rows at most, you might be able to take advantage of the client-side filtering, sorting, pagination, and grouping that TanStack table provides. > TanStack Table can handle thousands of client-side rows with good performance. Don't rule out client-side filtering, pagination, sorting, etc. without some thought first. Every use-case is different and will depend on the complexity of the table, how many columns you have, how large every piece of data is, etc. The main bottlenecks to pay attention to are: 1. Can your server query all of the data in a reasonable amount of time (and cost)? 2. What is the total size of the fetch? (This might not scale as badly as you think if you don't have many columns.) 3. Is the client's browser using too much memory if all of the data is loaded at once? If you're not sure, you can always start with client-side filtering and pagination and then switch to server-side strategies in the future as your data grows. ### Manual Server-Side Filtering If you have decided that you need to implement server-side filtering instead of using the built-in client-side filtering, here's how you do that. No `filteredRowModel` is needed for manual server-side filtering. Instead, the `data` that you pass to the table should already be filtered. However, if you have added a `filteredRowModel` to `_rowModels`, you can tell the table to skip it by setting the `manualFiltering` option to `true`. ```jsx const table = useTable({ _features: tableFeatures({ columnFilteringFeature }), _rowModels: {}, // no filteredRowModel needed for manual server-side filtering data, columns, manualFiltering: true, }) ``` > **Note:** When using manual filtering, many of the options that are discussed in the rest of this guide will have no effect. When `manualFiltering` is set to `true`, the table instance will not apply any filtering logic to the rows that are passed to it. Instead, it will assume that the rows are already filtered and will use the `data` that you pass to it as-is. ### Client-Side Filtering If you are using the built-in client-side filtering features, add the `columnFilteringFeature` to your features and the `filteredRowModel` to your row models. Import `createFilteredRowModel` and `filterFns` from TanStack Table: ```jsx import { useTable, tableFeatures, columnFilteringFeature, createFilteredRowModel, filterFns, } from '@tanstack/react-table' const _features = tableFeatures({ columnFilteringFeature }) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), }, data, columns, }) ``` ### Column Filter State Whether or not you use client-side or server-side filtering, you can take advantage of the built-in column filter state management that TanStack Table provides. There are many table and column APIs to mutate and interact with the filter state and retrieving the column filter state. The column filtering state is defined as an array of objects with the following shape: ```ts interface ColumnFilter { id: string value: unknown } type ColumnFiltersState = ColumnFilter[] ``` Since the column filter state is an array of objects, you can have multiple column filters applied at once. #### Accessing Column Filter State You can access the column filter state from the table instance just like any other table state using the `table.store.state` API. ```jsx const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, columns, data, //... }) console.log(table.store.state.columnFilters) // access the column filters state from the table instance ``` However, if you need to access the column filter state before the table is initialized, you can "control" the column filter state like down below. ### Controlled Column Filter State If you need easy access to the column filter state, you can control/manage the column filter state in your own state management with the `state.columnFilters` and `onColumnFiltersChange` table options. ```tsx const [columnFilters, setColumnFilters] = useState([]) // can set initial column filter state here //... const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, columns, data, //... state: { columnFilters, }, onColumnFiltersChange: setColumnFilters, }) ``` #### Initial Column Filter State If you do not need to control the column filter state in your own state management or scope, but you still want to set an initial column filter state, you can use the `initialState` table option instead of `state`. ```jsx const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, columns, data, //... initialState: { columnFilters: [ { id: 'name', value: 'John', // filter the name column by 'John' by default }, ], }, }) ``` > **NOTE**: Do not use both `initialState.columnFilters` and `state.columnFilters` at the same time, as the initialized state in the `state.columnFilters` will override the `initialState.columnFilters`. ### FilterFns Each column can have its own unique filtering logic. Choose from any of the filter functions that are provided by TanStack Table, or create your own. By default there are 10 built-in filter functions to choose from: - `includesString` - Case-insensitive string inclusion - `includesStringSensitive` - Case-sensitive string inclusion - `equalsString` - Case-insensitive string equality - `equalsStringSensitive` - Case-sensitive string equality - `arrIncludes` - Item inclusion within an array - `arrIncludesAll` - All items included in an array - `arrIncludesSome` - Some items included in an array - `equals` - Object/referential equality `Object.is`/`===` - `weakEquals` - Weak object/referential equality `==` - `inNumberRange` - Number range inclusion You can also define your own custom filter functions either as the `filterFn` column option, or as a global filter function using the `filterFns` table option. #### Custom Filter Functions > **Note:** These filter functions only run during client-side filtering. When defining a custom filter function in either the `filterFn` column option or the `filterFns` table option, it should have the following signature: ```ts const myCustomFilterFn: FilterFn = (row: Row, columnId: string, filterValue: any, addMeta: (meta: any) => void) => boolean ``` Every filter function receives: - The row to filter - The columnId to use to retrieve the row's value - The filter value and should return `true` if the row should be included in the filtered rows, and `false` if it should be removed. ```jsx const columns = [ { header: () => 'Name', accessorKey: 'name', filterFn: 'includesString', // use built-in filter function }, { header: () => 'Age', accessorKey: 'age', filterFn: 'inNumberRange', }, { header: () => 'Birthday', accessorKey: 'birthday', filterFn: 'myCustomFilterFn', // use custom global filter function }, { header: () => 'Profile', accessorKey: 'profile', // use custom filter function directly filterFn: (row, columnId, filterValue) => { return // true or false based on your custom logic }, } ] //... const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel({ ...filterFns, myCustomFilterFn: (row, columnId, filterValue) => { return // true or false based on your custom logic }, startsWith: startsWithFilterFn, // defined elsewhere }), }, columns, data, }) ``` ##### Customize Filter Function Behavior You can attach a few other properties to filter functions to customize their behavior: - `filterFn.resolveFilterValue` - This optional "hanging" method on any given `filterFn` allows the filter function to transform/sanitize/format the filter value before it is passed to the filter function. - `filterFn.autoRemove` - This optional "hanging" method on any given `filterFn` is passed a filter value and expected to return `true` if the filter value should be removed from the filter state. eg. Some boolean-style filters may want to remove the filter value from the table state if the filter value is set to `false`. ```tsx const startsWithFilterFn = ( row: Row, columnId: string, filterValue: number | string, //resolveFilterValue will transform this to a string ) => row .getValue(columnId) .toString() .toLowerCase() .trim() .startsWith(filterValue); // toString, toLowerCase, and trim the filter value in `resolveFilterValue` // remove the filter value from filter state if it is falsy (empty string in this case) startsWithFilterFn.autoRemove = (val: any) => !val; // transform/sanitize/format the filter value before it is passed to the filter function startsWithFilterFn.resolveFilterValue = (val: any) => val.toString().toLowerCase().trim(); ``` ### Customize Column Filtering There are a lot of table and column options that you can use to further customize the column filtering behavior. #### Disable Column Filtering By default, column filtering is enabled for all columns. You can disable the column filtering for all columns or for specific columns by using the `enableColumnFilters` table option or the `enableColumnFilter` column option. You can also turn off both column and global filtering by setting the `enableFilters` table option to `false`. Disabling column filtering for a column will cause the `column.getCanFilter` API to return `false` for that column. ```jsx const columns = [ { header: () => 'Id', accessorKey: 'id', enableColumnFilter: false, // disable column filtering for this column }, //... ] //... const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, columns, data, enableColumnFilters: false, // disable column filtering for all columns }) ``` #### Filtering Sub-Rows (Expanding) There are a few additional table options to customize the behavior of column filtering when using features like expanding, grouping, and aggregation. ##### Filter From Leaf Rows By default, filtering is done from parent rows down, so if a parent row is filtered out, all of its child sub-rows will be filtered out as well. Depending on your use-case, this may be the desired behavior if you only want the user to be searching through the top-level rows, and not the sub-rows. This is also the most performant option. However, if you want to allow sub-rows to be filtered and searched through, regardless of whether the parent row is filtered out, you can set the `filterFromLeafRows` table option to `true`. Setting this option to `true` will cause filtering to be done from leaf rows up, which means parent rows will be included so long as one of their child or grand-child rows is also included. ```jsx const table = useTable({ _features: tableFeatures({ columnFilteringFeature, rowExpandingFeature }), _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), expandedRowModel: createExpandedRowModel(), }, columns, data, filterFromLeafRows: true, // filter and search through sub-rows }) ``` ##### Max Leaf Row Filter Depth By default, filtering is done for all rows in a tree, no matter if they are root level parent rows or the child leaf rows of a parent row. Setting the `maxLeafRowFilterDepth` table option to `0` will cause filtering to only be applied to the root level parent rows, with all sub-rows remaining unfiltered. Similarly, setting this option to `1` will cause filtering to only be applied to child leaf rows 1 level deep, and so on. Use `maxLeafRowFilterDepth: 0` if you want to preserve a parent row's sub-rows from being filtered out while the parent row is passing the filter. ```jsx const table = useTable({ _features: tableFeatures({ columnFilteringFeature, rowExpandingFeature }), _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), expandedRowModel: createExpandedRowModel(), }, columns, data, maxLeafRowFilterDepth: 0, // only filter root level parent rows out }) ``` ### Column Filter APIs There are a lot of Column and Table APIs that you can use to interact with the column filter state and hook up to your UI components. Here is a list of the available APIs and their most common use-cases: - `table.setColumnFilters` - Overwrite the entire column filter state with a new state. - `table.resetColumnFilters` - Useful for a "clear all/reset filters" button. - **`column.getFilterValue`** - Useful for getting the default initial filter value for an input, or even directly providing the filter value to a filter input. - **`column.setFilterValue`** - Useful for connecting filter inputs to their `onChange` or `onBlur` handlers. - `column.getCanFilter` - Useful for disabling/enabling filter inputs. - `column.getIsFiltered` - Useful for displaying a visual indicator that a column is currently being filtered. - `column.getFilterIndex` - Useful for displaying in what order the current filter is being applied. - `column.getAutoFilterFn` - Used internally to find the default filter function for a column if none is specified. - `column.getFilterFn` - Useful for displaying which filter mode or function is currently being used. ================================================ FILE: docs/guide/column-ordering.md ================================================ --- title: Column Ordering Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [column-ordering](../framework/react/examples/column-ordering) - [column-dnd](../framework/react/examples/column-dnd) ## API [Column Ordering API](../api/features/column-ordering) ## Column Ordering Guide By default, columns are ordered in the order they are defined in the `columns` array. However, you can manually specify the column order using the `columnOrder` state. Other features like column pinning and grouping can also affect the column order. ### What Affects Column Order There are 3 table features that can reorder columns, which happen in the following order: 1. [Column Pinning](./column-pinning) - If pinning, columns are split into left, center (unpinned), and right pinned columns. 2. Manual **Column Ordering** - A manually specified column order is applied. 3. [Grouping](./grouping) - If grouping is enabled, a grouping state is active, and `tableOptions.groupedColumnMode` is set to `'reorder' | 'remove'`, then the grouped columns are reordered to the start of the column flow. > **Note:** `columnOrder` state will only affect unpinned columns if used in conjunction with column pinning. ### Column Order State If you don't provide a `columnOrder` state, TanStack Table will just use the order of the columns in the `columns` array. However, you can provide an array of string column ids to the `columnOrder` state to specify the order of the columns. #### Default Column Order If all you need to do is specify the initial column order, you can just specify the `columnOrder` state in the `initialState` table option. ```jsx const table = useTable({ _features: tableFeatures({ columnOrderingFeature }), _rowModels: {}, //... initialState: { columnOrder: ['columnId1', 'columnId2', 'columnId3'], }, //... }) ``` > **Note:** If you are using the `state` table option to also specify the `columnOrder` state, the `initialState` will have no effect. Only specify particular states in either `initialState` or `state`, not both. #### Managing Column Order State If you need to dynamically change the column order, or set the column order after the table has been initialized, you can manage the `columnOrder` state just like any other table state. ```jsx const [columnOrder, setColumnOrder] = useState(['columnId1', 'columnId2', 'columnId3']) //... const table = useTable({ _features: tableFeatures({ columnOrderingFeature }), _rowModels: {}, //... state: { columnOrder, //... } onColumnOrderChange: setColumnOrder, //... }); ``` ### Reordering Columns If the table has UI that allows the user to reorder columns, you can set up the logic something like this: ```tsx const [columnOrder, setColumnOrder] = useState(columns.map(c => c.id)); //depending on your dnd solution of choice, you may or may not need state like this const [movingColumnId, setMovingColumnId] = useState(null); const [targetColumnId, setTargetColumnId] = useState(null); //util function to splice and reorder the columnOrder array const reorderColumn = ( movingColumnId: Column, targetColumnId: Column, ): string[] => { const newColumnOrder = [...columnOrder]; newColumnOrder.splice( newColumnOrder.indexOf(targetColumnId), 0, newColumnOrder.splice(newColumnOrder.indexOf(movingColumnId), 1)[0], ); setColumnOrder(newColumnOrder); }; const handleDragEnd = (e: DragEvent) => { if(!movingColumnId || !targetColumnId) return; setColumnOrder(reorderColumn(movingColumnId, targetColumnId)); }; //use your dnd solution of choice ``` #### Drag and Drop Column Reordering Suggestions (React) There are undoubtedly many ways to implement drag and drop features along-side TanStack Table. Here are a few suggestions in order for you to not have a bad time: 1. Do NOT try to use [`"react-dnd"`](https://react-dnd.github.io/react-dnd/docs/overview) _if you are using React 18 or newer_. React DnD was an important library for its time, but it now does not get updated very often, and it has incompatibilities with React 18, especially in React Strict Mode. It is still possible to get it to work, but there are newer alternatives that have better compatibility and are more actively maintained. React DnD's Provider may also interfere and conflict with any other DnD solutions you may want to try in your app. 2. Use [`"@dnd-kit/core"`](https://dndkit.com/). DnD Kit is a modern, modular and lightweight drag and drop library that is highly compatible with the modern React ecosystem, and it works well with semantic `` markup. Both of the official TanStack DnD examples, [Column DnD](../framework/react/examples/column-dnd) and [Row DnD](../framework/react/examples/row-dnd), now use DnD Kit. 3. Consider other DnD libraries like [`"react-beautiful-dnd"`](https://github.com/atlassian/react-beautiful-dnd), but be aware of their potentially large bundle sizes, maintenance status, and compatibility with `
` markup. 4. Consider using native browser events and state management to implement lightweight drag and drop features. However, be aware that this approach may not be best for mobile users if you do not go the extra mile to implement proper touch events. [Material React Table V2](https://www.material-react-table.com/docs/examples/column-ordering) is an example of a library that implements TanStack Table with only browser drag and drop events such as `onDragStart`, `onDragEnd`, `onDragEnter` and no other dependencies. Browse its source code to see how it is done. ================================================ FILE: docs/guide/column-pinning.md ================================================ --- title: Column Pinning Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [column-pinning](../framework/react/examples/column-pinning) - [sticky-column-pinning](../framework/react/examples/column-pinning-sticky) ### Other Examples - [Svelte column-pinning](../framework/svelte/examples/column-pinning) - [Vue column-pinning](../framework/vue/examples/column-pinning) ## API [Column Pinning API](../api/features/column-pinning) ## Column Pinning Guide TanStack Table offers state and APIs helpful for implementing column pinning features in your table UI. You can implement column pinning in multiple ways. You can either split pinned columns into their own separate tables, or you can keep all columns in the same table, but use the pinning state to order the columns correctly and use sticky CSS to pin the columns to the left or right. ### How Column Pinning Affects Column Order There are 3 table features that can reorder columns, which happen in the following order: 1. **Column Pinning** - If pinning, columns are split into left, center (unpinned), and right pinned columns. 2. Manual [Column Ordering](./column-ordering) - A manually specified column order is applied. 3. [Grouping](./grouping) - If grouping is enabled, a grouping state is active, and `tableOptions.groupedColumnMode` is set to `'reorder' | 'remove'`, then the grouped columns are reordered to the start of the column flow. The only way to change the order of the pinned columns is in the `columnPinning.left` and `columnPinning.right` state itself. `columnOrder` state will only affect the order of the unpinned ("center") columns. ### Column Pinning State Managing the `columnPinning` state is optional, and usually not necessary unless you are adding persistent state features. TanStack Table will already keep track of the column pinning state for you. Manage the `columnPinning` state just like any other table state if you need to. ```jsx import { useTable, tableFeatures, columnPinningFeature } from '@tanstack/react-table' const _features = tableFeatures({ columnPinningFeature }) const [columnPinning, setColumnPinning] = useState({ left: [], right: [], }) const table = useTable({ _features, _rowModels: {}, //... state: { columnPinning, //... }, onColumnPinningChange: setColumnPinning, //... }) ``` ### Pin Columns by Default A very common use case is to pin some columns by default. You can do this by either initializing the `columnPinning` state with the pinned columnIds, or by using the `initialState` table option ```jsx const table = useTable({ _features, _rowModels: {}, //... initialState: { columnPinning: { left: ['expand-column'], right: ['actions-column'], }, //... }, //... }) ``` ### Useful Column Pinning APIs > Note: These APIs are available when using `columnPinningFeature`. There are a handful of useful Column API methods to help you implement column pinning features: - [`column.getCanPin`](../api/features/column-pinning#getcanpin): Use to determine if a column can be pinned. - [`column.pin`](../api/features/column-pinning#pin): Use to pin a column to the left or right. Or use to unpin a column. - [`column.getIsPinned`](../api/features/column-pinning#getispinned): Use to determine where a column is pinned. - [`column.getStart`](../api/features/column-pinning#getstart): Use to provide the correct `left` CSS value for a pinned column. - [`column.getAfter`](../api/features/column-pinning#getafter): Use to provide the correct `right` CSS value for a pinned column. - [`column.getIsLastColumn`](../api/features/column-pinning#getislastcolumn): Use to determine if a column is the last column in its pinned group. Useful for adding a box-shadow - [`column.getIsFirstColumn`](../api/features/column-pinning#getisfirstcolumn): Use to determine if a column is the first column in its pinned group. Useful for adding a box-shadow ### Split Table Column Pinning If you are just using sticky CSS to pin columns, you can for the most part, just render the table as you normally would with the `table.getHeaderGroups` and `row.getVisibleCells` methods. However, if you are splitting up pinned columns into their own separate tables, you can make use of the `table.getLeftHeaderGroups`, `table.getCenterHeaderGroups`, `table.getRightHeaderGroups`, `row.getLeftVisibleCells`, `row.getCenterVisibleCells`, and `row.getRightVisibleCells` methods to only render the columns that are relevant to the current table. ================================================ FILE: docs/guide/column-sizing.md ================================================ --- title: Column Sizing Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [column-sizing](../framework/react/examples/column-sizing) - [column-resizing-performant](../framework/react/examples/column-resizing-performant) ## API [Column Sizing API](../api/features/column-sizing) ## Column Sizing Guide The column sizing feature allows you to optionally specify the width of each column including min and max widths. It also allows you and your users the ability to dynamically change the width of all columns at will, eg. by dragging the column headers. ### Column Widths Columns by default are given the following measurement options: ```tsx export const defaultColumnSizing = { size: 150, minSize: 20, maxSize: Number.MAX_SAFE_INTEGER, } ``` These defaults can be overridden by both `tableOptions.defaultColumn` and individual column defs, in that order. ```tsx const columns = [ { accessorKey: 'col1', size: 270, //set column size for this column }, //... ] const table = useTable({ _features: tableFeatures({ columnSizingFeature, columnResizingFeature }), // columnResizingFeature for drag-to-resize _rowModels: {}, defaultColumn: { size: 200, // starting column size minSize: 50, // enforced during column resizing maxSize: 500, // enforced during column resizing }, //... }) ``` The column "sizes" are stored in the table state as numbers, and are usually interpreted as pixel unit values, but you can hook up these column sizing values to your css styles however you see fit. As a headless utility, table logic for column sizing is really only a collection of states that you can apply to your own layouts how you see fit (our example above implements 2 styles of this logic). You can apply these width measurements in a variety of ways: - semantic `table` elements or any elements being displayed in a table css mode - `div/span` elements or any elements being displayed in a non-table css mode - Block level elements with strict widths - Absolutely positioned elements with strict widths - Flexbox positioned elements with loose widths - Grid positioned elements with loose widths - Really any layout mechanism that can interpolate cell widths into a table structure. Each of these approaches has its own tradeoffs and limitations which are usually opinions held by a UI/component library or design system, luckily not you 😉. ### Column Resizing TanStack Table provides built-in column resizing state and APIs that allow you to easily implement column resizing in your table UI with a variety of options for UX and performance. #### Enable Column Resizing By default, the `column.getCanResize()` API will return `true` by default for all columns, but you can either disable column resizing for all columns with the `enableColumnResizing` table option, or disable column resizing on a per-column basis with the `enableResizing` column option. ```tsx const columns = [ { accessorKey: 'id', enableResizing: false, //disable resizing for just this column size: 200, //starting column size }, //... ] ``` #### Column Resize Mode By default, the column resize mode is set to `"onEnd"`. This means that the `column.getSize()` API will not return the new column size until the user has finished resizing (dragging) the column. Usually a small UI indicator will be displayed while the user is resizing the column. In React TanStack Table adapter, where achieving 60 fps column resizing renders can be difficult, depending on the complexity of your table or web page, the `"onEnd"` column resize mode can be a good default option to avoid stuttering or lagging while the user resizes columns. That is not to say that you cannot achieve 60 fps column resizing renders while using TanStack React Table, but you may have to do some extra memoization or other performance optimizations in order to achieve this. > Advanced column resizing performance tips will be discussed [down below](#advanced-column-resizing-performance). If you want to change the column resize mode to `"onChange"` for immediate column resizing renders, you can do so with the `columnResizeMode` table option. ```tsx const table = useTable({ //... columnResizeMode: 'onChange', //change column resize mode to "onChange" }) ``` #### Column Resize Direction By default, TanStack Table assumes that the table markup is laid out in a left-to-right direction. For right-to-left layouts, you may need to change the column resize direction to `"rtl"`. ```tsx const table = useTable({ //... columnResizeDirection: 'rtl', //change column resize direction to "rtl" for certain locales }) ``` #### Connect Column Resizing APIs to UI There are a few really handy APIs that you can use to hook up your column resizing drag interactions to your UI. ##### Column Size APIs To apply the size of a column to the column head cells, data cells, or footer cells, you can use the following APIs: ```ts header.getSize() column.getSize() cell.column.getSize() ``` How you apply these size styles to your markup is up to you, but it is pretty common to use either CSS variables or inline styles to apply the column sizes. ```tsx ) ``` #### Do We Have to Do It This Way? This is just a new way to integrate custom code along-side the built-in features in TanStack Table. In our example up above, we could have just as easily stored the `density` state in a `React.useState`, defined our own `toggleDensity` handler wherever, and just used it in our code separately from the table instance. Building table features along-side TanStack Table instead of deeply integrating them into the table instance is still a perfectly valid way to build custom features. Depending on your use case, this may or may not be the cleanest way to extend TanStack Table with custom features. ================================================ FILE: docs/guide/data.md ================================================ --- title: Data Guide --- ## Data Guide Tables start with your data. Your column definitions and rows will depend on the shape of your data. TanStack Table has some TypeScript features that will help you create the rest of your table code with a great type-safe experience. If you set up your data and types correctly, TanStack Table will be able to infer the shape of your data and enforce that your column definitions are made correctly. ### TypeScript TypeScript is NOT required to use the TanStack Table packages... ***BUT*** TanStack Table is written and organized in such a way that makes the awesome TypeScript experience that you get feel like it is one of the main selling points of the library. If you are not using TypeScript, you will be missing out on a lot of great autocompletion and type-checking features that will both speed up your development time and reduce the number of bugs in your code. #### TypeScript Generics Having a basic understanding of what TypeScript Generics are and how they work will help you understand this guide better, but it should be easy enough to pick up as you go. The official [TypeScript Generics Docs](https://www.typescriptlang.org/docs/handbook/2/generics.html) may be helpful for those not yet familiar with TypeScript. ### Defining Data Types `data` is an array of objects that will be turned into the rows of your table. Each object in the array represents a row of data (under normal circumstances). If you are using TypeScript, we usually define a type for the shape of our data. This type is used as a generic type for all of the other table, column, row, and cell instances. This Generic is usually referred to as `TData` throughout the rest of the TanStack Table types and APIs. For example, if we have a table that displays a list of users in an array like this: ```json [ { "firstName": "Tanner", "lastName": "Linsley", "age": 33, "visits": 100, "progress": 50, "status": "Married" }, { "firstName": "Kevin", "lastName": "Vandy", "age": 27, "visits": 200, "progress": 100, "status": "Single" } ] ``` Then we can define a User (TData) type like this: ```ts //TData type User = { firstName: string lastName: string age: number visits: number progress: number status: string } ``` We can then define our `data` array with this type, and then TanStack Table will be able to intelligently infer lots of types for us later on in our columns, rows, cells, etc. This is because the `data` type is literally defined as the `TData` generic type. Whatever you pass to the `data` table option will become the `TData` type for the rest of the table instance. Just make sure your column definitions use the same `TData` type as the `data` type when you define them later. ```ts //note: data needs a "stable" reference in order to prevent infinite re-renders const data: User[] = [] //or const [data, setData] = React.useState([]) //or const data = ref([]) //vue //etc... ``` #### Deep Keyed Data If your data is not a nice flat array of objects, that's okay! Once you get around to defining your columns, there are strategies for accessing deeply nested data in your accessors. If your `data` looks something like this: ```json [ { "name": { "first": "Tanner", "last": "Linsley" }, "info": { "age": 33, "visits": 100, } }, { "name": { "first": "Kevin", "last": "Vandy" }, "info": { "age": 27, "visits": 200, } } ] ``` You can define a type like this: ```ts type User = { name: { first: string last: string } info: { age: number visits: number } } ``` And you will be able to access the data in your column definitions with either dot notation in an accessorKey or simply by using an accessorFn. ```ts const columns = [ { header: 'First Name', accessorKey: 'name.first', }, { header: 'Last Name', accessorKey: 'name.last', }, { header: 'Age', accessorFn: info => info.age, }, //... ] ``` This is discussed in more detail in the [Column Def Guide](./column-defs). > NOTE: The "keys" in your json data can usually be anything, but any periods in the keys will be interpreted as a deep key and will cause errors. #### Nested Sub-Row Data If you are using expanding features, it can be common to have nested sub-rows in your data. This results in a recursive type that is a bit different. So if your data looks like this: ```json [ { "firstName": "Tanner", "lastName": "Linsley", "subRows": [ { "firstName": "Kevin", "lastName": "Vandy", }, { "firstName": "John", "lastName": "Doe", "subRows": [ //... ] } ] }, { "firstName": "Jane", "lastName": "Doe", } ] ``` You can define a type like this: ```ts type User = { firstName: string lastName: string subRows?: User[] //does not have to be called "subRows", can be called anything } ``` Where `subRows` is an optional array of `User` objects. This is discussed in more detail in the [Expanding Guide](./expanding). ### Give Data a "Stable" Reference The `data` array that you pass to the table instance ***MUST*** have a "stable" reference in order to prevent bugs that cause infinite re-renders (especially in React). This will depend on which framework adapter you are using, but in React, you should often use `React.useState`, `React.useMemo`, or similar to ensure that both the `data` and `columns` table options have stable references. ```tsx const fallbackData = [] const _features = tableFeatures({}) // Define outside component for stable reference export default function MyComponent() { //✅ GOOD: This will not cause an infinite loop of re-renders because `columns` is a stable reference const columns = useMemo(() => [ // ... ], []); //✅ GOOD: This will not cause an infinite loop of re-renders because `data` is a stable reference const [data, setData] = useState(() => [ // ... ]); // Columns and data are defined in a stable reference, will not cause infinite loop! const table = useTable({ _features, _rowModels: {}, columns, data ?? fallbackData, //also good to use a fallback array that is defined outside of the component (stable reference) }); return
``` Though, as discussed in the [advanced column resizing performance section](#advanced-column-resizing-performance), you may want to consider using CSS variables to apply column sizes to your markup. ##### Column Resize APIs TanStack Table provides a pre-built event handler to make your drag interactions easy to implement. These event handlers are just convenience functions that call other internal APIs to update the column sizing state and re-render the table. Use `header.getResizeHandler()` to connect to your column resize drag interactions, for both mouse and touch events. ```tsx ``` ##### Column Resize Indicator with ColumnSizingInfoState TanStack Table keeps track of an state object called `columnSizingInfo` that you can use to render a column resize indicator UI. ```jsx ``` #### Advanced Column Resizing Performance If you are creating large or complex tables (and using React 😉), you may find that if you do not add proper memoization to your render logic, your users may experience degraded performance while resizing columns. We have created a [performant column resizing example](../framework/react/examples/column-resizing-performant) that demonstrates how to achieve 60 fps column resizing renders with a complex table that may otherwise have slow renders. It is recommended that you just look at that example to see how it is done, but these are the basic things to keep in mind: 1. Don't use `column.getSize()` on every header and every data cell. Instead, calculate all column widths once upfront, **memoized**! 2. Memoize your Table Body while resizing is in progress. 3. Use CSS variables to communicate column widths to your table cells. If you follow these steps, you should see significant performance improvements while resizing columns. If you are not using React, and are using the Svelte, Vue, or Solid adapters instead, you may not need to worry about this as much, but similar principles apply. ================================================ FILE: docs/guide/column-visibility.md ================================================ --- title: Column Visibility Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [column-visibility](../framework/react/examples/column-visibility) - [column-ordering](../framework/react/examples/column-ordering) - [sticky-column-pinning](../framework/react/examples/column-pinning-sticky) ### Other Examples - [SolidJS column-visibility](../framework/solid/examples/column-visibility) - [Svelte column-visibility](../framework/svelte/examples/column-visibility) ## API [Column Visibility API](../api/features/column-visibility) ## Column Visibility Guide The column visibility feature allows table columns to be hidden or shown dynamically. In v9, add `columnVisibilityFeature` to your `_features` to enable this. There is a dedicated `columnVisibility` state and APIs for managing column visibility dynamically. ### Column Visibility State The `columnVisibility` state is a map of column IDs to boolean values. A column will be hidden if its ID is present in the map and the value is `false`. If the column ID is not present in the map, or the value is `true`, the column will be shown. ```jsx import { useTable, tableFeatures, columnVisibilityFeature } from '@tanstack/react-table' const [columnVisibility, setColumnVisibility] = useState({ columnId1: true, columnId2: false, // hide this column by default columnId3: true, }) const table = useTable({ _features: tableFeatures({ columnVisibilityFeature }), _rowModels: {}, //... state: { columnVisibility, //... }, onColumnVisibilityChange: setColumnVisibility, }) ``` Alternatively, if you don't need to manage the column visibility state outside of the table, you can still set the initial default column visibility state using the `initialState` option. > **Note**: If `columnVisibility` is provided to both `initialState` and `state`, the `state` initialization will take precedence and `initialState` will be ignored. Do not provide `columnVisibility` to both `initialState` and `state`, only one or the other. ```jsx const table = useTable({ _features: tableFeatures({ columnVisibilityFeature }), _rowModels: {}, //... initialState: { columnVisibility: { columnId1: true, columnId2: false, // hide this column by default columnId3: true, }, //... }, }) ``` ### Disable Hiding Columns By default, all columns can be hidden or shown. If you want to prevent certain columns from being hidden, you set the `enableHiding` column option to `false` for those columns. ```jsx const columns = [ { header: 'ID', accessorKey: 'id', enableHiding: false, // disable hiding for this column }, { header: 'Name', accessor: 'name', // can be hidden }, ]; ``` ### Column Visibility Toggle APIs There are several column API methods that are useful for rendering column visibility toggles in the UI. - `column.getCanHide` - Useful for disabling the visibility toggle for a column that has `enableHiding` set to `false`. - `column.getIsVisible` - Useful for setting the initial state of the visibility toggle. - `column.toggleVisibility` - Useful for toggling the visibility of a column. - `column.getToggleVisibilityHandler` - Shortcut for hooking up the `column.toggleVisibility` method to a UI event handler. ```jsx {table.getAllColumns().map((column) => ( ))} ``` ### Column Visibility Aware Table APIs When you render your header, body, and footer cells, there are a lot of API options available. You may see APIs like `table.getAllLeafColumns` and `row.getAllCells`, but if you use these APIs, they will not take column visibility into account. Instead, you need to use the "visible" variants of these APIs, such as `table.getVisibleLeafColumns` and `row.getVisibleCells`. ```jsx {table.getVisibleLeafColumns().map((column) => ( // takes column visibility into account // ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( // takes column visibility into account // ))} ))}
``` If you are using the Header Group APIs, they will already take column visibility into account. ================================================ FILE: docs/guide/columns.md ================================================ --- title: Columns Guide --- ## API [Column API](../api/core/column) ## Columns Guide > Note: This guide is about the actual `column` objects that are generated within the table instance and NOT about setting up the [column definitions](./column-defs) for your table. This quick guide will discuss the different ways you can retrieve and interact with `column` objects in TanStack Table. ### Where to Get Columns From You can find the `column` objects in many places. They are often attached #### Header and Cell Objects Before you reach for one of the `table` instance APIs, consider if you actually need to retrieve either [headers](./headers) or [cells](./cells) instead of `columns`. If you are rending out the markup for your table, you will most likely want to reach for the APIs that return headers or cells instead of columns. The column objects themselves are not really meant to render out the headers or cells, but the `header` and `cell` objects will contain references to these `column` objects from which they can derive the necessary information to render their UI. ```js const column = cell.column; // get column from cell const column = header.column; // get column from header ``` #### Column Table Instance APIs There are dozens of `table` instance APIs you can use to retrieve columns from the table instance. Which APIs you will use will depend entirely on which features you are using in your table and your use-case. ##### Get Column If you need to just get a single column by its ID, you can use the `table.getColumn` API. ```js const column = table.getColumn('firstName'); ``` ##### Get Columns The simplest column API is `table.getAllColumns`, which will return a list of all columns in the table. There are dozens of other column APIs that are affected by other features and the state of the table that come alongside this API though. `table.getAllFlatColumns`, `table.getAllLeafColumns`, `getCenterLeafColumns`, `table.getLeftVisibleLeafColumns` are just some examples of other column APIs that you might use in tandem with the column visibility or column pinning features. ### Column Objects Column objects are not actually meant to be used to render out the table UI directly, so they are not associated 1-to-1 with any `
` or `` elements in your table, but they contain a lot of useful properties and methods that you can use to interact with the table state. #### Column IDs Every column must have a unique `id` defined in their associated [Column Definition](./column-defs). Usually, you define this `id` yourself, or it is derived from the `accessorKey` or `header` properties in the column definition. #### ColumnDef A reference to the original `columnDef` object that was used to created the column is always available on the column object. #### Nested Grouped Columns Properties There are a few properties on `column` objects that are only useful if the column is part of a nested or grouped column structure. These properties include: - `columns`: An array of child columns that belong to a group column. - `depth`: The header group "row index" that the column group belongs to. - `parent`: The parent column of the column. If the column is a top-level column, this will be `undefined`. ### More Column APIs There are dozens of Column APIs that you can use to interact with the table state and extract cell values from the table based on the state of the table. See each features column API documentation for more information. ### Column Rendering Don't necessarily use `column` objects to render `headers` or `cells` directly. Instead, use the [`header`](./headers) and [`cell`](./cells) objects, as discussed above. But if you are just rendering a list of columns somewhere else in your UI for something like a column visibility menu or something similar, you can just map over a columns array and render out the UI as you normally would. ================================================ FILE: docs/guide/custom-features.md ================================================ --- title: Custom Features Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [custom-features](../framework/react/examples/custom-features) ## Custom Features Guide In this guide, we'll cover how to extend TanStack Table with custom features, and along the way, we'll learn more about how the TanStack Table v9 codebase is structured and how it works. ### TanStack Table Strives to be Lean TanStack Table has a core set of features that are built into the library such as sorting, filtering, pagination, etc. We've received a lot of requests and sometimes even some well thought out PRs to add even more features to the library. While we are always open to improving the library, we also want to make sure that TanStack Table remains a lean library that does not include too much bloat and code that is unlikely to be used in most use cases. Not every PR can, or should, be accepted into the core library, even if it does solve a real problem. This can be frustrating to developers where TanStack Table solves 90% of their use case, but they need a little bit more control. TanStack Table has always been built in a way that allows it to be highly extensible (at least since v7). The `table` instance that is returned from whichever framework adapter that you are using (`createTable`, `useTable`, etc) is a plain JavaScript object that can have extra properties or APIs added to it. It has always been possible to use composition to add custom logic, state, and APIs to the table instance. Libraries like [Material React Table](https://github.com/KevinVandy/material-react-table/blob/v2/packages/material-react-table/src/hooks/useMRT_TableInstance.ts) have simply created custom wrapper hooks around the `useTable` hook to extend the table instance with custom functionality. In v9, TanStack Table uses the `_features` option (via `tableFeatures()`) to declare which features your table uses. This enables tree-shaking—you only bundle the code for the features you need. You can add custom features to the table instance in exactly the same way as the built-in features. > In v9, features are opt-in. Use `tableFeatures({ ... })` to declare which features your table uses, including custom features. ### How TanStack Table Features Work TanStack Table's source code is arguably somewhat simple (at least we think so). All code for each feature is split up into its own object/file with instantiation methods to create initial state, default table and column options, and API methods that can be added to the `table`, `header`, `column`, `row`, and `cell` instances. All of the functionality of a feature object can be described with the `TableFeature` type that is exported from TanStack Table. This type is a TypeScript interface that describes the shape of a feature object needed to create a feature. ```ts export interface TableFeature { constructCell?: ( cell: Cell, column: Column, row: Row, table: Table ) => void constructColumn?: (column: Column, table: Table) => void constructHeader?: (header: Header, table: Table) => void constructRow?: (row: Row, table: Table) => void constructTable?: (table: Table) => void getDefaultColumnDef?: () => Partial> getDefaultTableOptions?: ( table: Table ) => Partial> getInitialState?: (initialState?: InitialTableState) => Partial } ``` This might be a bit confusing, so let's break down what each of these methods do: #### Default Options and Initial State
##### getDefaultTableOptions The `getDefaultTableOptions` method in a table feature is responsible for setting the default table options for that feature. For example, in the [Column Sizing](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/columnSizingFeature.ts) feature, the `getDefaultTableOptions` method sets the default `columnResizeMode` option with a default value of `"onEnd"`.
##### getDefaultColumnDef The `getDefaultColumnDef` method in a table feature is responsible for setting the default column options for that feature. For example, in the [Sorting](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/rowSortingFeature.ts) feature, the `getDefaultColumnDef` method sets the default `sortUndefined` column option with a default value of `1`.
##### getInitialState The `getInitialState` method in a table feature is responsible for setting the default state for that feature. For example, in the [Pagination](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/rowPaginationFeature.ts) feature, the `getInitialState` method sets the default `pageSize` state with a value of `10` and the default `pageIndex` state with a value of `0`. #### API Creators
##### constructTable The `constructTable` method in a table feature is responsible for adding methods to the `table` instance. For example, in the [Row Selection](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/rowSelectionFeature.ts) feature, the `constructTable` method adds many table instance API methods such as `toggleAllRowsSelected`, `getIsAllRowsSelected`, `getIsSomeRowsSelected`, etc. So then, when you call `table.toggleAllRowsSelected()`, you are calling a method that was added to the table instance by the `rowSelectionFeature` feature.
##### constructHeader The `constructHeader` method in a table feature is responsible for adding methods to the `header` instance. For example, in the [Column Sizing](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/columnSizingFeature.ts) feature, the `constructHeader` method adds many header instance API methods such as `getStart`, and many others. So then, when you call `header.getStart()`, you are calling a method that was added to the header instance by the `columnSizingFeature` feature.
##### constructColumn The `constructColumn` method in a table feature is responsible for adding methods to the `column` instance. For example, in the [Sorting](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/rowSortingFeature.ts) feature, the `constructColumn` method adds many column instance API methods such as `getNextSortingOrder`, `toggleSorting`, etc. So then, when you call `column.toggleSorting()`, you are calling a method that was added to the column instance by the `rowSortingFeature` feature.
##### constructRow The `constructRow` method in a table feature is responsible for adding methods to the `row` instance. For example, in the [Row Selection](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/rowSelectionFeature.ts) feature, the `constructRow` method adds many row instance API methods such as `toggleSelected`, `getIsSelected`, etc. So then, when you call `row.toggleSelected()`, you are calling a method that was added to the row instance by the `rowSelectionFeature` feature.
##### constructCell The `constructCell` method in a table feature is responsible for adding methods to the `cell` instance. For example, in the [Column Grouping](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/columnGroupingFeature.ts) feature, the `constructCell` method adds many cell instance API methods such as `getIsGrouped`, `getIsAggregated`, etc. So then, when you call `cell.getIsGrouped()`, you are calling a method that was added to the cell instance by the `columnGroupingFeature` feature. ### Adding a Custom Feature Let's walk through making a custom table feature for a hypothetical use case. Let's say we want to add a feature to the table instance that allows the user to change the "density" (padding of cells) of the table. Check out the full [custom-features](../framework/react/examples/custom-features) example to see the full implementation, but here's an in-depth look at the steps to create a custom feature. #### Step 1: Set up TypeScript Types Assuming you want the same full type-safety that the built-in features in TanStack Table have, let's set up all of the TypeScript types for our new feature. We'll create types for new table options, state, and table instance API methods. These types are following the naming convention used internally within TanStack Table, but you can name them whatever you want. We are not adding these types to TanStack Table yet, but we'll do that in the next step. ```ts // define types for our new feature's custom state export type DensityState = 'sm' | 'md' | 'lg' export interface DensityTableState { density: DensityState } // define types for our new feature's table options export interface DensityOptions { enableDensity?: boolean onDensityChange?: OnChangeFn } // Define types for our new feature's table APIs export interface DensityInstance { setDensity: (updater: Updater) => void toggleDensity: (value?: DensityState) => void } ``` #### Step 2: Use Declaration Merging to Add New Types to TanStack Table We can tell TypeScript to modify the exported types from TanStack Table to include our new feature's types. This is called "declaration merging" and it's a powerful feature of TypeScript. This way, we should not have to use any TypeScript hacks such as `as unknown as CustomTable` or `// @ts-ignore` in our new feature's code or in our application code. ```ts // Use declaration merging to add our new feature APIs and state types to TanStack Table's existing types. declare module '@tanstack/react-table' { // or whatever framework adapter you are using //merge our new feature's state with the existing table state interface TableState extends DensityTableState {} //merge our new feature's options with the existing table options interface TableOptions extends DensityOptions {} //merge our new feature's instance APIs with the existing table instance APIs interface Table extends DensityInstance {} // if you need to add cell instance APIs... // interface Cell extends DensityCell // if you need to add row instance APIs... // interface Row extends DensityRow // if you need to add column instance APIs... // interface Column extends DensityColumn // if you need to add header instance APIs... // interface Header extends DensityHeader // Note: declaration merging on `ColumnDef` is not possible because it is a complex type, not an interface. // But you can still use declaration merging on `ColumnDef.meta` } ``` Once we do this correctly, we should have no TypeScript errors when we try to both create our new feature's code and use it in our application. ##### Caveats of Using Declaration Merging One caveat of using declaration merging is that it will affect the TanStack Table types for every table across your codebase. This is not a problem if you plan on loading the same feature set for every table in your application, but it could be a problem if some of your tables load extra features and some do not. Alternatively, you can just make a bunch of custom types that extend off of the TanStack Table types with your new features added. This is what [Material React Table](https://github.com/KevinVandy/material-react-table/blob/v2/packages/material-react-table/src/types.ts) does in order to avoid affecting the types of vanilla TanStack Table tables, but it's a bit more tedious, and requires a lot of type casting at certain points. #### Step 3: Create the Feature Object With all of that TypeScript setup out of the way, we can now create the feature object for our new feature. This is where we define all of the methods that will be added to the table instance. Use the `TableFeature` type to ensure that you are creating the feature object correctly. If the TypeScript types are set up correctly, you should have no TypeScript errors when you create the feature object with the new state, options, and instance APIs. ```ts export const DensityFeature: TableFeature = { //Use the TableFeature type!! // define the new feature's initial state getInitialState: (state): DensityTableState => { return { density: 'md', ...state, } }, // define the new feature's default options getDefaultTableOptions: ( table: Partial> ): DensityOptions => { return { enableDensity: true, onDensityChange: makeStateUpdater('density', table), } as DensityOptions }, // if you need to add a default column definition... // getDefaultColumnDef: (): Partial> => { // return { meta: {} } //use meta instead of directly adding to the columnDef to avoid typescript stuff that's hard to workaround // }, // define the new feature's table instance methods constructTable: (table: Table): void => { table.setDensity = updater => { const safeUpdater: Updater = old => { let newState = functionalUpdate(updater, old) return newState } return table.options.onDensityChange?.(safeUpdater) } table.toggleDensity = value => { table.setDensity(old => { if (value) return value return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' //cycle through the 3 options }) } }, // if you need to add row instance APIs... // constructRow: (row, table): void => {}, // if you need to add cell instance APIs... // constructCell: (cell, column, row, table): void => {}, // if you need to add column instance APIs... // constructColumn: (column, table): void => {}, // if you need to add header instance APIs... // constructHeader: (header, table): void => {}, } ``` #### Step 4: Add the Feature to the Table Now that we have our feature object, we can add it to the table instance by including it in the `tableFeatures()` call and passing the result to the `_features` option when we create the table instance. ```ts const _features = tableFeatures({ DensityFeature }) const table = useTable({ _features, _rowModels: {}, columns, data, //.. }) ``` #### Step 5: Use the Feature in Your Application Now that the feature is added to the table instance, you can use the new instance APIs options, and state in your application. ```tsx const _features = tableFeatures({ DensityFeature }) const table = useTable({ _features, _rowModels: {}, columns, data, //... state: { density, }, onDensityChange: setDensity, }) //... const { density } = table.store.state return(
{flexRender(cell.column.columnDef.cell, cell.getContext())}
...
; } ``` `React.useState` and `React.useMemo` are not the only ways to give your data a stable reference. You can also define your data outside of the component or use a 3rd party state management library like Redux, Zustand, or TanStack Query. The main thing to avoid is defining the `data` array inside the same scope as the `useTable` call. That will cause the `data` array to be redefined on every render, which will cause an infinite loop of re-renders. ```tsx export default function MyComponent() { //😵 BAD: This will cause an infinite loop of re-renders because `columns` is redefined as a new array on every render! const columns = [ // ... ]; //😵 BAD: This will cause an infinite loop of re-renders because `data` is redefined as a new array on every render! const data = [ // ... ]; //❌ Columns and data are defined in the same scope as `useTable` without a stable reference, will cause infinite loop! const table = useTable({ _features: tableFeatures({}), //❌ Also re-created on every render _rowModels: {}, columns, data ?? [], //❌ Also bad because the fallback array is re-created on every render }); return ...
; } ``` ### How TanStack Table Transforms Data Later, in other parts of these docs, you will see how TanStack Table processes the `data` that you pass to the table and generates the row and cell objects that are used to create the table. The `data` that you pass to the table is never mutated by TanStack Table, but the actual values in the rows and cells may be transformed by the accessors in your column definitions, or by other features performed by [row models](./row-models) like grouping or aggregation. ### How Much Data Can TanStack Table Handle? Believe it or not, TanStack Table was actually built to scale up to handle potentially hundreds of thousands of rows of data in the client. This is obviously not always possible, depending on the size of each column's data and the number of columns. However, the sorting, filtering, pagination, and grouping features are all built with performance in mind for large datasets. The default mindset of a developer building a data grid is to implement server-side pagination, sorting, and filtering for large datasets. This is still usually a good idea, but a lot of developers underestimate how much data can actually be handled in the client with modern browsers and the right optimizations. If your table will never have more than a few thousand rows, you can probably take advantage of the client-side features in TanStack Table instead of implementing them yourself on the server. Before committing to letting TanStack Table's client-side features handle your large dataset, you should test it with your actual data to see if it performs well enough for your needs, of course. This is discussed in more detail in the [Pagination Guide](./pagination#should-you-use-client-side-pagination). ================================================ FILE: docs/guide/expanding.md ================================================ --- title: Expanding Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [expanding](../framework/react/examples/expanding) - [grouping](../framework/react/examples/grouping) - [sub-components](../framework/react/examples/sub-components) ## API [Expanding API](../api/features/expanding) ## Expanding Feature Guide Expanding is a feature that allows you to show and hide additional rows of data related to a specific row. This can be useful in cases where you have hierarchical data and you want to allow users to drill down into the data from a higher level. Or it can be useful for showing additional information related to a row. ### Different use cases for Expanding Features There are multiple use cases for expanding features in TanStack Table that will be discussed below. 1. Expanding sub-rows (child rows, aggregate rows, etc.) 2. Expanding custom UI (detail panels, sub-tables, etc.) ### Enable Client-Side Expanding To use the client-side expanding features, add the `rowExpandingFeature` to your features and the `expandedRowModel` to your row models: ```ts import { useTable, tableFeatures, rowExpandingFeature, createExpandedRowModel, } from '@tanstack/react-table' const _features = tableFeatures({ rowExpandingFeature }) const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel(), }, // other options... }) ``` Expanded data can either contain table rows or any other data you want to display. We will discuss how to handle both cases in this guide. ### Table rows as expanded data Expanded rows are essentially child rows that inherit the same column structure as their parent rows. If your data object already includes these expanded rows data, you can utilize the `getSubRows` function to specify these child rows. However, if your data object does not contain the expanded rows data, they can be treated as custom expanded data, which is discussed in next section. For example, if you have a data object like this: ```ts type Person = { id: number name: string age: number children?: Person[] | undefined } const data: Person[] = [ { id: 1, name: 'John', age: 30, children: [ { id: 2, name: 'Jane', age: 5 }, { id: 5, name: 'Jim', age: 10 } ] }, { id: 3, name: 'Doe', age: 40, children: [ { id: 4, name: 'Alice', age: 10 } ] }, ] ``` Then you can use the getSubRows function to return the children array in each row as expanded rows. The table instance will now understand where to look for the sub rows on each row. ```ts const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel(), }, getSubRows: (row) => row.children, // return the children array as sub-rows // other options... }) ``` > **Note:** You can have a complicated `getSubRows` function, but keep in mind that it will run for every row and every sub-row. This can be expensive if the function is not optimized. Async functions are not supported. ### Custom Expanding UI In some cases, you may wish to show extra details or information, which may or may not be part of your table data object, such as expanded data for rows. This kind of expanding row UI has gone by many names over the years including "expandable rows", "detail panels", "sub-components", etc. By default, the `row.getCanExpand()` row instance API will return false unless it finds `subRows` on a row. This can be overridden by implementing your own `getRowCanExpand` function in the table instance options. ```ts //... const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel(), }, getRowCanExpand: (row) => true, // Add your logic to determine if a row can be expanded. True means all rows include expanded data // other options... }) //... {table.getRowModel().rows.map((row) => ( {/* Normal row UI */} {row.getVisibleCells().map((cell) => ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} {/* If the row is expanded, render the expanded UI as a separate row with a single cell that spans the width of the table */} {row.getIsExpanded() && ( // The number of columns you wish to span for the expanded data if it is not a row that shares the same columns as the parent row // Your custom UI goes here )} ))} //... ``` ### Expanded rows state If you need to control the expanded state of the rows in your table, you can do so by using the expanded state and the `onExpandedChange` option. This allows you to manage the expanded state according to your requirements. ```ts const [expanded, setExpanded] = useState({}) const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel() }, // other options... state: { expanded, }, onExpandedChange: setExpanded, }) ``` The ExpandedState type is defined as follows: ```ts type ExpandedState = true | Record ``` If the ExpandedState is true, it means all rows are expanded. If it's a record, only the rows with IDs present as keys in the record and have their value set to true are expanded. For example, if the expanded state is { row1: true, row2: false }, it means the row with ID row1 is expanded and the row with ID row2 is not expanded. This state is used by the table to determine which rows are expanded and should display their subRows, if any. ### UI toggling handler for expanded rows TanStack table will not add a toggling handler UI for expanded data to your table. You should manually add it within each row's UI to allow users to expand and collapse the row. For example, you can add a button UI within the columns definition. ```ts const columns = [ { accessorKey: 'name', header: 'Name', }, { accessorKey: 'age', header: 'Age', }, { header: 'Children', cell: ({ row }) => { return row.getCanExpand() ? : ''; }, }, ] ``` ### Filtering Expanded Rows By default, the filtering process starts from the parent rows and moves downwards. This means if a parent row is excluded by the filter, all its child rows will also be excluded. However, you can change this behavior by using the `filterFromLeafRows` option. When this option is enabled, the filtering process starts from the leaf (child) rows and moves upwards. This ensures that a parent row will be included in the filtered results as long as at least one of its child or grandchild rows meets the filter criteria. Additionally, you can control how deep into the child hierarchy the filter process goes by using the `maxLeafRowFilterDepth` option. This option allows you to specify the maximum depth of child rows that the filter should consider. ```ts //... const table = useTable({ _features: tableFeatures({ columnFilteringFeature, rowExpandingFeature }), _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), expandedRowModel: createExpandedRowModel(), }, getSubRows: (row) => row.subRows, filterFromLeafRows: true, // search through the expanded rows maxLeafRowFilterDepth: 1, // limit the depth of the expanded rows that are searched // other options... }) ``` ### Paginating Expanded Rows By default, expanded rows are paginated along with the rest of the table (which means expanded rows may span multiple pages). If you want to disable this behavior (which means expanded rows will always render on their parents page. This also means more rows will be rendered than the set page size) you can use the `paginateExpandedRows` option. ```ts const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel() }, // other options... paginateExpandedRows: false, }) ``` ### Pinning Expanded Rows Pinning expanded rows works the same way as pinning regular rows. You can pin expanded rows to the top or bottom of the table. Please refer to the [Pinning Guide](./pinning.md) for more information on row pinning. ### Sorting Expanded Rows By default, expanded rows are sorted along with the rest of the table. ### Manual Expanding (server-side) If you are doing server-side expansion, you can enable manual row expansion by setting the manualExpanding option to true. This means that the `getExpandedRowModel` will not be used to expand rows and you would be expected to perform the expansion in your own data model. ```ts const table = useTable({ _features: tableFeatures({ rowExpandingFeature }), _rowModels: {}, // no expandedRowModel needed for manual expanding // other options... manualExpanding: true, }) ``` ================================================ FILE: docs/guide/features.md ================================================ --- title: Features Guide --- TanStack Table comes with many features, each with their own associated options and API. > **v9 note:** In v9, features are opt-in. You declare which features your table uses via the `_features` option (using `tableFeatures()`). This enables tree-shaking—you only bundle the code for the features you need. See the [Table Instance Guide](./tables) and [Row Models Guide](./row-models) for setup. To include all features (v8-style), use `stockFeatures`. - [Column Ordering](./column-ordering) - [Column Pinning](./column-pinning) - [Column Sizing](./column-sizing) - [Column Visibility](./column-visibility) - [Expanding](./expanding) - [Column Faceting](./column-faceting) - [Column Filtering](./column-filtering) - [Global Faceting](./global-faceting) - [Global Filtering](./global-filtering) - [Grouping](./grouping) - [Pagination](./pagination) - [Row Pinning](./row-pinning) - [Row Selection](./row-selection) - [Sorting](./sorting) - [Virtualization](./virtualization) ================================================ FILE: docs/guide/filters.md ================================================ --- title: Filters Guide --- The filter guides are now split into multiple guides: - [Column Filtering](./column-filtering) - [Global Filtering](./global-filtering) - [Fuzzy Filtering](./fuzzy-filtering) - [Column Faceting](./column-faceting) - [Global Faceting](./global-faceting) ================================================ FILE: docs/guide/fuzzy-filtering.md ================================================ --- title: Fuzzy Filtering Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [filters-fuzzy](../framework/react/examples/filters-fuzzy) ## API [Filters API](../api/features/filters) ## Fuzzy Filtering Guide Fuzzy filtering is a technique that allows you to filter data based on approximate matches. This can be useful when you want to search for data that is similar to a given value, rather than an exact match. You can implement a client side fuzzy filtering by defining a custom filter function. This function should take in the row, columnId, and filter value, and return a boolean indicating whether the row should be included in the filtered data. Fuzzy filtering is mostly used with global filtering, but you can also apply it to individual columns. We will discuss how to implement fuzzy filtering for both cases. > **Note:** You will need to install the `@tanstack/match-sorter-utils` library to use fuzzy filtering. > TanStack Match Sorter Utils is a fork of [match-sorter](https://github.com/kentcdodds/match-sorter) by Kent C. Dodds. It was forked in order to work better with TanStack Table's row by row filtering approach. Using the match-sorter libraries is optional, but the TanStack Match Sorter Utils library provides a great way to both fuzzy filter and sort by the rank information it returns, so that rows can be sorted by their closest matches to the search query. ### Defining a Custom Fuzzy Filter Function Here's an example of a custom fuzzy filter function: ```typescript import { rankItem } from '@tanstack/match-sorter-utils'; import { FilterFn } from '@tanstack/table'; const fuzzyFilter: FilterFn = (row, columnId, value, addMeta) => { // Rank the item const itemRank = rankItem(row.getValue(columnId), value) // Store the itemRank info addMeta({ itemRank }) // Return if the item should be filtered in/out return itemRank.passed } ``` In this function, we're using the rankItem function from the @tanstack/match-sorter-utils library to rank the item. We then store the ranking information in the meta data of the row, and return whether the item passed the ranking criteria. ### Using Fuzzy Filtering with Global Filtering To use fuzzy filtering with global filtering, you can specify the fuzzy filter function in the globalFilterFn option of the table instance: ```typescript import { useTable, tableFeatures, globalFilteringFeature, rowSortingFeature, createFilteredRowModel, createSortedRowModel, filterFns, sortFns, } from '@tanstack/react-table' const _features = tableFeatures({ globalFilteringFeature, rowSortingFeature }) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel({ ...filterFns, fuzzy: fuzzyFilter, }), sortedRowModel: createSortedRowModel(sortFns), // needed if you want sorting with fuzzy rank }, columns, data, globalFilterFn: 'fuzzy', }) ``` ### Using Fuzzy Filtering with Column Filtering To use fuzzy filtering with column filtering, pass your fuzzy filter function to `createFilteredRowModel` (merging it with the built-in `filterFns`). You can then specify the fuzzy filter by name in the `filterFn` option of the column definition: ```typescript const column = [ { accessorFn: row => `${row.firstName} ${row.lastName}`, id: 'fullName', header: 'Full Name', cell: info => info.getValue(), filterFn: 'fuzzy', //using our custom fuzzy filter function }, // other columns... ]; ``` In this example, we're applying the fuzzy filter to a column that combines the firstName and lastName fields of the data. #### Sorting with Fuzzy Filtering When using fuzzy filtering with column filtering, you might also want to sort the data based on the ranking information. You can do this by defining a custom sorting function: ```typescript import { compareItems } from '@tanstack/match-sorter-utils' import { sortFns } from '@tanstack/table' const fuzzySort: SortFn = (rowA, rowB, columnId) => { let dir = 0 // Only sort by rank if the column has ranking information if (rowA.columnFiltersMeta[columnId]) { dir = compareItems( rowA.columnFiltersMeta[columnId]?.itemRank!, rowB.columnFiltersMeta[columnId]?.itemRank! ) } // Provide an alphanumeric fallback for when the item ranks are equal return dir === 0 ? sortFns.alphanumeric(rowA, rowB, columnId) : dir } ``` In this function, we're comparing the ranking information of the two rows. If the ranks are equal, we fall back to alphanumeric sorting. You can then specify this sorting function in the sortFn option of the column definition: ```typescript { accessorFn: row => `${row.firstName} ${row.lastName}`, id: 'fullName', header: 'Full Name', cell: info => info.getValue(), filterFn: 'fuzzy', //using our custom fuzzy filter function sortFn: 'fuzzySort', //using our custom fuzzy sort function } ``` ================================================ FILE: docs/guide/global-faceting.md ================================================ --- title: Global Faceting Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [filters-faceted](../framework/react/examples/filters) ## API [Global Faceting API](../api/features/global-faceting) ## Global Faceting Guide Global Faceting allows you to generate lists of values for all columns from the table's data. For example, a list of unique values in a table can be generated from all rows in all columns to be used as search suggestions in an autocomplete filter component. Or, a tuple of minimum and maximum values can be generated from a table of numbers to be used as a range for a range slider filter component. ### Global Faceting Row Models In order to use any of the global faceting features, add the appropriate faceted row models to your `_rowModels`: ```ts import { useTable, tableFeatures, createFacetedRowModel, createFacetedMinMaxValues, createFacetedUniqueValues, } from '@tanstack/react-table' const _features = tableFeatures({}) // add globalFilteringFeature if using global filtering const table = useTable({ _features, _rowModels: { facetedRowModel: createFacetedRowModel(), // required (other faceting methods depend on this) facetedMinMaxValues: createFacetedMinMaxValues(), // if you need min/max values facetedUniqueValues: createFacetedUniqueValues(), // if you need a list of unique values }, // other options... }) ``` ### Use Global Faceted Row Models Once you have included the appropriate row models in your table options, you will be able to use the faceting table instance APIs to access the lists of values generated by the faceted row models. ```ts // list of unique values for autocomplete filter const autoCompleteSuggestions = Array.from(table.getGlobalFacetedUniqueValues().keys()) .sort() .slice(0, 5000); ``` ```ts // tuple of min and max values for range filter const [min, max] = table.getGlobalFacetedMinMaxValues() ?? [0, 1]; ``` ### Custom Global (Server-Side) Faceting If instead of using the built-in client-side faceting features, you can implement your own faceting logic on the server-side and pass the faceted values to the client-side. You can use the getGlobalFacetedUniqueValues and getGlobalFacetedMinMaxValues table options to resolve the faceted values from the server-side. ```ts const facetingQuery = useQuery( 'faceting', async () => { const response = await fetch('/api/faceting'); return response.json(); }, { onSuccess: (data) => { table.getGlobalFacetedUniqueValues = () => data.uniqueValues; table.getGlobalFacetedMinMaxValues = () => data.minMaxValues; }, } ); ``` In this example, we use the `useQuery` hook from `react-query` to fetch faceting data from the server. Once the data is fetched, we set the `getGlobalFacetedUniqueValues` and `getGlobalFacetedMinMaxValues` table options to return the faceted values from the server response. This will allow the table to use the server-side faceting data for generating autocomplete suggestions and range filters. ================================================ FILE: docs/guide/global-filtering.md ================================================ --- title: Global Filtering Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [Global Filters](../framework/react/examples/filters-global) ## API [Global Filtering API](../api/features/global-filtering) ## Global Filtering Guide Filtering comes in 2 flavors: Column Filtering and Global Filtering. This guide will focus on global filtering, which is a filter that is applied across all columns. ### Client-Side vs Server-Side Filtering If you have a large dataset, you may not want to load all of that data into the client's browser in order to filter it. In this case, you will most likely want to implement server-side filtering, sorting, pagination, etc. However, as also discussed in the [Pagination Guide](./pagination#should-you-use-client-side-pagination), a lot of developers underestimate how many rows can be loaded client-side without a performance hit. The TanStack table examples are often tested to handle up to 100,000 rows or more with decent performance for client-side filtering, sorting, pagination, and grouping. This doesn't necessarily mean that your app will be able to handle that many rows, but if your table is only going to have a few thousand rows at most, you might be able to take advantage of the client-side filtering, sorting, pagination, and grouping that TanStack table provides. > TanStack Table can handle thousands of client-side rows with good performance. Don't rule out client-side filtering, pagination, sorting, etc. without some thought first. Every use-case is different and will depend on the complexity of the table, how many columns you have, how large every piece of data is, etc. The main bottlenecks to pay attention to are: 1. Can your server query all of the data in a reasonable amount of time (and cost)? 2. What is the total size of the fetch? (This might not scale as badly as you think if you don't have many columns.) 3. Is the client's browser using too much memory if all of the data is loaded at once? If you're not sure, you can always start with client-side filtering and pagination and then switch to server-side strategies in the future as your data grows. ### Manual Server-Side Global Filtering If you have decided that you need to implement server-side global filtering instead of using the built-in client-side global filtering, here's how you do that. No `filteredRowModel` is needed for manual server-side global filtering. Instead, the `data` that you pass to the table should already be filtered. However, if you have added a `filteredRowModel` to `_rowModels`, you can tell the table to skip it by setting the `manualFiltering` option to `true`. ```jsx import { useTable, tableFeatures, globalFilteringFeature, } from '@tanstack/react-table' const _features = tableFeatures({ globalFilteringFeature }) const table = useTable({ _features, _rowModels: {}, // no filteredRowModel needed for manual server-side global filtering data, columns, manualFiltering: true, }) ``` Note: When using manual global filtering, many of the options that are discussed in the rest of this guide will have no effect. When manualFiltering is set to true, the table instance will not apply any global filtering logic to the rows that are passed to it. Instead, it will assume that the rows are already filtered and will use the data that you pass to it as-is. ### Client-Side Global Filtering If you are using the built-in client-side global filtering, add the `globalFilteringFeature` to your features and the `filteredRowModel` to your row models: ```jsx import { useTable, tableFeatures, globalFilteringFeature, createFilteredRowModel, filterFns, } from '@tanstack/react-table' const _features = tableFeatures({ globalFilteringFeature }) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), }, // other options... }) ``` ### Global Filter Function The globalFilterFn option allows you to specify the filter function that will be used for global filtering. The filter function can be a string that references a built-in filter function, a string that references a custom filter function provided via the tableOptions.filterFns option, or a custom filter function. ```jsx const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), }, data, columns, globalFilterFn: 'text', // built-in filter function }) ``` By default there are 10 built-in filter functions to choose from: - includesString - Case-insensitive string inclusion - includesStringSensitive - Case-sensitive string inclusion - equalsString - Case-insensitive string equality - equalsStringSensitive - Case-sensitive string equality - arrIncludes - Item inclusion within an array - arrIncludesAll - All items included in an array - arrIncludesSome - Some items included in an array - equals - Object/referential equality Object.is/=== - weakEquals - Weak object/referential equality == - inNumberRange - Number range inclusion You can also define your own custom filter functions either as the globalFilterFn table option. ### Global Filter State The global filter state is stored in the table's internal state and can be accessed via the table.store.state.globalFilter property. If you want to persist the global filter state outside of the table, you can use the onGlobalFilterChange option to provide a callback function that will be called whenever the global filter state changes. ```jsx const [globalFilter, setGlobalFilter] = useState([]) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, // other options... state: { globalFilter, }, onGlobalFilterChange: setGlobalFilter, }) ``` The global filtering state is defined as an object with the following shape: ```jsx interface GlobalFilter { globalFilter: any } ``` ### Adding global filter input to UI TanStack table will not add a global filter input UI to your table. You should manually add it to your UI to allow users to filter the table. For example, you can add an input UI above the table to allow users to enter a search term. ```jsx return (
table.setGlobalFilter(String(e.target.value))} placeholder="Search..." />
) ``` ### Custom Global Filter Function If you want to use a custom global filter function, you can define the function and pass it to the globalFilterFn option. > **Note:** It is often a popular idea to use fuzzy filtering functions for global filtering. This is discussed in the [Fuzzy Filtering Guide](./fuzzy-filtering.md). ```jsx const customFilterFn = (rows, columnId, filterValue) => { // custom filter logic } const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, // other options... globalFilterFn: customFilterFn, }) ``` ### Initial Global Filter State If you want to set an initial global filter state when the table is initialized, you can pass the global filter state as part of the table initialState option. However, you can also just specify the initial global filter state in the state.globalFilter option. ```jsx const [globalFilter, setGlobalFilter] = useState("search term") //recommended to initialize globalFilter state here const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, // other options... initialState: { globalFilter: 'search term', // if not managing globalFilter state, set initial state here }, state: { globalFilter, // pass our managed globalFilter state to the table }, }) ``` > NOTE: Do not use both initialState.globalFilter and state.globalFilter at the same time, as the initialized state in the state.globalFilter will override the initialState.globalFilter. ### Disable Global Filtering By default, global filtering is enabled for all columns. You can disable the global filtering for all columns by using the enableGlobalFilter table option. You can also turn off both column and global filtering by setting the enableFilters table option to false. Disabling global filtering will cause the column.getCanGlobalFilter API to return false for that column. ```jsx const columns = [ { header: () => 'Id', accessorKey: 'id', enableGlobalFilter: false, // disable global filtering for this column }, //... ] //... const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }, // other options... columns, enableGlobalFilter: false, // disable global filtering for all columns }) ``` ================================================ FILE: docs/guide/grouping.md ================================================ --- title: Grouping Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [grouping](../framework/react/examples/grouping) ## API [Grouping API](../api/features/grouping) ## Grouping Guide There are 3 table features that can reorder columns, which happen in the following order: 1. [Column Pinning](./column-pinning) - If pinning, columns are split into left, center (unpinned), and right pinned columns. 2. Manual [Column Ordering](./column-ordering) - A manually specified column order is applied. 3. **Grouping** - If grouping is enabled, a grouping state is active, and `tableOptions.groupedColumnMode` is set to `'reorder' | 'remove'`, then the grouped columns are reordered to the start of the column flow. Grouping in TanStack table is a feature that applies to columns and allows you to categorize and organize the table rows based on specific columns. This can be useful in cases where you have a large amount of data and you want to group them together based on certain criteria. To use the grouping feature, add the `columnGroupingFeature` to your features and the `groupedRowModel` to your row models. The grouped row model is responsible for grouping the rows based on the grouping state. ```tsx import { useTable, tableFeatures, columnGroupingFeature, createGroupedRowModel, aggregationFns, } from '@tanstack/react-table' const _features = tableFeatures({ columnGroupingFeature }) const table = useTable({ _features, _rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns), }, // other options... }) ``` When grouping state is active, the table will add matching rows as subRows to the grouped row. The grouped row will be added to the table rows at the same index as the first matching row. The matching rows will be removed from the table rows. To allow the user to expand and collapse the grouped rows, you can use the expanding feature. ```tsx const _features = tableFeatures({ columnGroupingFeature, rowExpandingFeature }) const table = useTable({ _features, _rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns), expandedRowModel: createExpandedRowModel(), }, // other options... }) ``` ### Grouping state The grouping state is an array of strings, where each string is the ID of a column to group by. The order of the strings in the array determines the order of the grouping. For example, if the grouping state is ['column1', 'column2'], then the table will first group by column1, and then within each group, it will group by column2. You can control the grouping state using the setGrouping function: ```tsx table.setGrouping(['column1', 'column2']); ``` You can also reset the grouping state to its initial state using the resetGrouping function: ```tsx table.resetGrouping(); ``` By default, when a column is grouped, it is moved to the start of the table. You can control this behavior using the groupedColumnMode option. If you set it to 'reorder', then the grouped columns will be moved to the start of the table. If you set it to 'remove', then the grouped columns will be removed from the table. If you set it to false, then the grouped columns will not be moved or removed. ```tsx const table = useTable({ _features, _rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns) }, // other options... groupedColumnMode: 'reorder', }) ``` ### Aggregations When rows are grouped, you can aggregate the data in the grouped rows by columns using the aggregationFn option. This is a string that is the ID of the aggregation function. You can define the aggregation functions using the aggregationFns option. ```tsx const column = columnHelper.accessor('key', { aggregationFn: 'sum', }) ``` In the above example, the sum aggregation function will be used to aggregate the data in the grouped rows. By default, numeric columns will use the sum aggregation function, and non-numeric columns will use the count aggregation function. You can override this behavior by specifying the aggregationFn option in the column definition. There are several built-in aggregation functions that you can use: - sum - Sums the values in the grouped rows. - count - Counts the number of rows in the grouped rows. - min - Finds the minimum value in the grouped rows. - max - Finds the maximum value in the grouped rows. - extent - Finds the extent (min and max) of the values in the grouped rows. - mean - Finds the mean of the values in the grouped rows. - median - Finds the median of the values in the grouped rows. - unique - Returns an array of unique values in the grouped rows. - uniqueCount - Counts the number of unique values in the grouped rows. #### Custom Aggregations When rows are grouped, you can aggregate the data in the grouped rows using the aggregationFns option. This is a record where the keys are the IDs of the aggregation functions, and the values are the aggregation functions themselves. You can then reference these aggregation functions in a column's aggregationFn option. ```tsx const table = useTable({ _features, _rowModels: { groupedRowModel: createGroupedRowModel({ ...aggregationFns, myCustomAggregation: (columnId, leafRows, childRows) => { // return the aggregated value }, }), }, // other options... }) ``` In the above example, myCustomAggregation is a custom aggregation function that takes the column ID, the leaf rows, and the child rows, and returns the aggregated value. You can then use this aggregation function in a column's aggregationFn option: ```tsx const column = columnHelper.accessor('key', { aggregationFn: 'myCustomAggregation', }) ``` ### Manual Grouping If you are doing server-side grouping and aggregation, you can enable manual grouping using the manualGrouping option. When this option is set to true, the table will not automatically group rows using getGroupedRowModel() and instead will expect you to manually group the rows before passing them to the table. ```tsx const table = useTable({ _features: tableFeatures({ columnGroupingFeature }), _rowModels: {}, // no groupedRowModel needed for manual grouping // other options... manualGrouping: true, }) ``` > **Note:** There are not currently many known easy ways to do server-side grouping with TanStack Table. You will need to do lots of custom cell rendering to make this work. ### Grouping Change Handler If you want to manage the grouping state yourself, you can use the onGroupingChange option. This option is a function that is called when the grouping state changes. You can pass the managed state back to the table via the tableOptions.state.grouping option. ```tsx const [grouping, setGrouping] = useState([]) const table = useTable({ _features, _rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns) }, // other options... state: { grouping, }, onGroupingChange: setGrouping, }) ``` ================================================ FILE: docs/guide/header-groups.md ================================================ --- title: Header Groups Guide --- ## API [Header Group API](../api/core/header-group) ## Header Groups Guide This quick guide will discuss the different ways you can retrieve and interact with header group objects in TanStack Table. ### What are Header Groups? Header Groups are simply "rows" of headers. Don't let the name confuse you, it's just that simple. The large majority of tables will only have one row of headers (a single header group), but if you define your column structure with nested columns as with the [Column Groups example](../framework/react/examples/column-groups), you can have multiple rows of headers (multiple header groups). ### Where to Get Header Groups From There are multiple `table` instance APIs you can use to retrieve header groups from the table instance. `table.getHeaderGroups` is the most common API to use, but depending on the features that you are using, you may need to use other APIs, such as `table.get[Left/Center/Right]HeaderGroups` if you are using column pinning features. ### Header Group Objects Header Group objects are similar to [Row](./rows) objects, though simpler since there is not as much going on in header rows as there are in the body rows. By default, header groups only have three properties: - `id`: The unique identifier for the header group that is generated from its depth (index). This is useful as a key for React components. - `depth`: The depth of the header group, zero-indexed based. Think of this as the row index amongst all header rows. - `headers`: An array of [Header](./headers) cell objects that belong to this header group (row). ### Access Header Cells To render the header cells in a header group, you just map over the `headers` array from the header group object. ```jsx {table.getHeaderGroups().map(headerGroup => { return ( {headerGroup.headers.map(header => ( // map over the headerGroup headers array {/* */} ))} ) })} ``` ================================================ FILE: docs/guide/headers.md ================================================ --- title: Headers Guide --- ## API [Header API](../api/core/header) ## Headers Guide This quick guide will discuss the different ways you can retrieve and interact with `header` objects in TanStack Table. Headers are the equivalent of cells, but meant for the `` section of the table instead of the `` section. ### Where to Get Headers From Headers come from [Header Groups](./header-groups), which are the equivalent of rows, but meant for the `` section of the table instead of the `` section. #### HeaderGroup Headers If you are in a header group, the headers are stored as an array in the `headerGroup.headers` property. Usually you will just map over this array to render your headers. ```jsx {table.getHeaderGroups().map(headerGroup => { return ( {headerGroup.headers.map(header => ( // map over the headerGroup headers array {/* */} ))} ) })} ``` #### Header Table Instance APIs There are multiple `table` instance APIs that you can use to retrieve a list of headers depending on the features that you are using. The most common API you might use is `table.getFlatHeaders`, which will return a flat list of all headers in the table, but there are at least a dozen other headers that are useful in tandem with the column visibility and column pinning features. APIs like `table.getLeftLeafHeaders` or `table.getRightFlatHeaders` could be useful depending on your use case. ### Header Objects Header objects are similar to [Cell](./cells) objects, but meant for the `` section of the table instead of the `` section. Every header object can be associated with a `` or similar cell element in your UI. There are a few properties and methods on `header` objects that you can use to interact with the table state and extract cell values from the table based on the state of the table. #### Header IDs Every header object has an `id` property that makes it unique within the table instance. Usually you only need this `id` as a unique identifier for React keys or if you are following the [performant column resizing example](../framework/react/examples/column-resizing-performant). For simple headers with no advanced nested or grouped headers logic, the `header.id` will be the same as it's parent `column.id`. However, if the header is part group column or a placeholder cell, it will have a more complicated id that is constructed from the header family, depth/header row index, column id, and header group id. #### Nested Grouped Headers Properties There are a few properties on `header` objects that are only useful if the header is part of a nested or grouped header structure. These properties include: - `colspan`: The number of columns that the header should span. This is useful for rendering the `colSpan` attribute on the `` element. - `rowSpan`: The number of rows that the header should span. This is useful for rendering the `rowSpan` attribute on the `` element. (Currently not implemented in default TanStack Table) - `depth`: The header group "row index" that the header group belongs to. - `isPlaceholder`: A boolean flag that is true if the header is a placeholder header. Placeholder headers are used to fill in the gaps when a column is hidden or when a column is part of a group column. - `placeholderId`: The unique identifier for the placeholder header. - `subHeaders`: The array of sub/child headers that belong to this header. Will be empty if the header is a leaf header. > Note: `header.index` refers to its index within the header group (row of headers), i.e. its position from left to right. It is not the same as `header.depth`, which refers to the header group "row index". #### Header Parent Objects Every header stores a reference to its parent [column](./columns) object and its parent [header group](./header-groups) object. ### More Header APIs Headers have a few more useful APIs attached to them that are useful for interacting with the table state. Most of them relate to the Column sizing and resizing features. See the [Column Resizing Guide](./column-resizing) for more information. ### Header Rendering Since the `header` column option you defined can be either a string, jsx, or a function returning either of those, the best way to render the headers is to use the `flexRender` utility from your adapter, which will handle all of those cases for you. ```jsx {headerGroup.headers.map(header => ( {/* Handles all possible header column def scenarios for `header` */} {flexRender(header.column.columnDef.header, header.getContext())} ))} ================================================ FILE: docs/guide/pagination.md ================================================ --- title: Pagination Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [pagination](../framework/react/examples/pagination) - [pagination-controlled (React Query)](../framework/react/examples/pagination-controlled) - [editable-data](../framework/react/examples/editable-data) - [expanding](../framework/react/examples/expanding) - [filters](../framework/react/examples/filters) - [fully-controlled](../framework/react/examples/fully-controlled) - [row-selection](../framework/react/examples/row-selection) ## API [Pagination API](../api/features/pagination) ## Pagination Guide TanStack Table has great support for both client-side and server-side pagination. This guide will walk you through the different ways to implement pagination in your table. ### Client-Side Pagination Using client-side pagination means that the `data` that you fetch will contain ***ALL*** of the rows for the table, and the table instance will handle pagination logic in the front-end. #### Should You Use Client-Side Pagination? Client-side pagination is usually the simplest way to implement pagination when using TanStack Table, but it might not be practical for very large datasets. However, a lot of people underestimate just how much data can be handled client-side. If your table will only ever have a few thousand rows or less, client-side pagination can still be a viable option. TanStack Table is designed to scale up to 10s of thousands of rows with decent performance for pagination, filtering, sorting, and grouping. The [official pagination example](../framework/react/examples/pagination) loads 100,000 rows and still performs well, albeit with only handful of columns. Every use-case is different and will depend on the complexity of the table, how many columns you have, how large every piece of data is, etc. The main bottlenecks to pay attention to are: 1. Can your server query all of the data in a reasonable amount of time (and cost)? 2. What is the total size of the fetch? (This might not scale as badly as you think if you don't have many columns.) 3. Is the client's browser using too much memory if all of the data is loaded at once? If you're not sure, you can always start with client-side pagination and then switch to server-side pagination in the future as your data grows. #### Should You Use Virtualization Instead? Alternatively, instead of paginating the data, you can render all rows of a large dataset on the same page, but only use the browser's resources to render the rows that are visible in the viewport. This strategy is often called "virtualization" or "windowing". TanStack offers a virtualization library called [TanStack Virtual](https://tanstack.com/virtual/latest) that can work well with TanStack Table. The UI/UX of both virtualization and pagination have their own trade-offs, so see which one works best for your use-case. #### Pagination Row Model If you want to take advantage of the built-in client-side pagination in TanStack Table, add the `rowPaginationFeature` to your features and the `paginatedRowModel` to your row models: ```jsx import { useTable, tableFeatures, rowPaginationFeature, createPaginatedRowModel, } from '@tanstack/react-table' const _features = tableFeatures({ rowPaginationFeature }) const table = useTable({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, columns, data, }) ``` > **Migrating from v8?** See [useLegacyTable](../framework/react/guide/use-legacy-table) for incremental migration. ### Manual Server-Side Pagination If you decide that you need to use server-side pagination, here is how you can implement it. No pagination row model is needed for server-side pagination, but if you have provided it for other tables that do need it in a shared component, you can still turn off the client-side pagination by setting the `manualPagination` option to `true`. Setting the `manualPagination` option to `true` will tell the table instance to use the `table.getPrePaginatedRowModel` row model under the hood, and it will make the table instance assume that the `data` that you pass in is already paginated. #### Page Count and Row Count The table instance will have no way of knowing how many rows/pages there are in total in your back-end unless you tell it. Provide either the `rowCount` or `pageCount` table option to let the table instance know how many pages there are in total. If you provide a `rowCount`, the table instance will calculate the `pageCount` internally from `rowCount` and `pageSize`. Otherwise, you can directly provide the `pageCount` if you already have it. If you don't know the page count, you can just pass in `-1` for the `pageCount`, but the `getCanNextPage` and `getCanPreviousPage` row model functions will always return `true` in this case. ```jsx import { useTable, tableFeatures, rowPaginationFeature, } from '@tanstack/react-table' const _features = tableFeatures({ rowPaginationFeature }) const table = useTable({ _features, _rowModels: {}, // no paginatedRowModel needed for server-side pagination columns, data, manualPagination: true, // turn off client-side pagination rowCount: dataQuery.data?.rowCount, // pass in the total row count so the table knows how many pages there are (pageCount calculated internally if not provided) // pageCount: dataQuery.data?.pageCount, // alternatively directly pass in pageCount instead of rowCount }) ``` > **Note**: Setting the `manualPagination` option to `true` will make the table instance assume that the `data` that you pass in is already paginated. ### Pagination State Whether or not you are using client-side or manual server-side pagination, you can use the built-in `pagination` state and APIs. The `pagination` state is an object that contains the following properties: - `pageIndex`: The current page index (zero-based). - `pageSize`: The current page size. You can manage the `pagination` state just like any other state in the table instance. ```jsx import { useTable, tableFeatures, rowPaginationFeature, createPaginatedRowModel, } from '@tanstack/react-table' const _features = tableFeatures({ rowPaginationFeature }) const [pagination, setPagination] = useState({ pageIndex: 0, // initial page index pageSize: 10, // default page size }) const table = useTable({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, columns, data, onPaginationChange: setPagination, state: { pagination, }, }) ``` Alternatively, if you have no need for managing the `pagination` state in your own scope, but you need to set different initial values for the `pageIndex` and `pageSize`, you can use the `initialState` option. ```jsx const table = useTable({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, columns, data, initialState: { pagination: { pageIndex: 2, // custom initial page index pageSize: 25, // custom default page size }, }, }) ``` > **Note**: Do NOT pass the `pagination` state to both the `state` and `initialState` options. `state` will overwrite `initialState`. Only use one or the other. ### Pagination Options Besides the `manualPagination`, `pageCount`, and `rowCount` options which are useful for manual server-side pagination (and discussed [above](#manual-server-side-pagination)), there is one other table option that is useful to understand. #### Auto Reset Page Index By default, `pageIndex` is reset to `0` when page-altering state changes occur, such as when the `data` is updated, filters change, grouping changes, etc. This behavior is automatically disabled when `manualPagination` is true but it can be overridden by explicitly assigning a boolean value to the `autoResetPageIndex` table option. ```jsx const table = useTable({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, columns, data, autoResetPageIndex: false, // turn off auto reset of pageIndex }) ``` Be aware, however, that if you turn off `autoResetPageIndex`, you may need to add some logic to handle resetting the `pageIndex` yourself to avoid showing empty pages. ### Pagination APIs There are several pagination table instance APIs that are useful for hooking up your pagination UI components. #### Pagination Button APIs - `getCanPreviousPage`: Useful for disabling the "previous page" button when on the first page. - `getCanNextPage`: Useful for disabling the "next page" button when there are no more pages. - `previousPage`: Useful for going to the previous page. (Button click handler) - `nextPage`: Useful for going to the next page. (Button click handler) - `firstPage`: Useful for going to the first page. (Button click handler) - `lastPage`: Useful for going to the last page. (Button click handler) - `setPageIndex`: Useful for a "go to page" input. - `resetPageIndex`: Useful for resetting the table state to the original page index. - `setPageSize`: Useful for a "page size" input/select. - `resetPageSize`: Useful for resetting the table state to the original page size. - `setPagination`: Useful for setting all of the pagination state at once. - `resetPagination`: Useful for resetting the table state to the original pagination state. > **Note**: These pagination APIs are available when using `rowPaginationFeature`. ```jsx ``` #### Pagination Info APIs - `getPageCount`: Useful for showing the total number of pages. - `getRowCount`: Useful for showing the total number of rows. ================================================ FILE: docs/guide/pinning.md ================================================ --- title: Pinning Guide --- Pinning is split into 2 different feature guides: - [Column Pinning](./column-pinning) - [Row Pinning](./row-pinning) ================================================ FILE: docs/guide/row-models.md ================================================ --- title: Row Models Guide --- ## Row Models Guide If you take a look at the most basic example of TanStack Table, you'll see a code snippet like this: ```ts import { tableFeatures, useTable } from '@tanstack/react-table' const _features = tableFeatures({}) // Core features only function Component() { const table = useTable({ _features, _rowModels: {}, // Core row model is automatic; add others as needed columns, data, }) } ``` In v9, row models are configured via the `_rowModels` option. The core row model is always included automatically. You only add the row models you need for filtering, sorting, pagination, etc. This keeps your bundle small—you only import and use the code for the features you enable. ### What are Row Models? Row models run under the hood of TanStack Table to transform your original data in useful ways that are needed for data grid features like filtering, sorting, grouping, expanding, and pagination. The rows that get generated and render on screen won't necessarily be a 1:1 mapping of the original data that you passed to the table. They may be sorted, filtered, paginated, etc. ### Configuring Row Models You should only add the row models that you need. Here are all of the row models that are available via `_rowModels`: | `_rowModels` Key | Factory Function | Purpose | |------------------|------------------|---------| | (automatic) | — | Core row model (always included) | | `filteredRowModel` | `createFilteredRowModel(filterFns)` | Filtering (column + global) | | `sortedRowModel` | `createSortedRowModel(sortFns)` | Sorting | | `paginatedRowModel` | `createPaginatedRowModel()` | Pagination | | `expandedRowModel` | `createExpandedRowModel()` | Row expanding | | `groupedRowModel` | `createGroupedRowModel(aggregationFns)` | Grouping and aggregation | | `facetedRowModel` | `createFacetedRowModel()` | Faceted filtering | | `facetedMinMaxValues` | `createFacetedMinMaxValues()` | Min/max for faceted filters | | `facetedUniqueValues` | `createFacetedUniqueValues()` | Unique values for faceted filters | You must also add the corresponding features to `_features` for each row model you use. For example: ```ts import { tableFeatures, useTable, columnFilteringFeature, rowSortingFeature, rowPaginationFeature, createFilteredRowModel, createSortedRowModel, createPaginatedRowModel, filterFns, sortFns, } from '@tanstack/react-table' const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, }) const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, }) ``` Note that `createFilteredRowModel`, `createSortedRowModel`, and `createGroupedRowModel` accept their processing functions (`filterFns`, `sortFns`, `aggregationFns`) as parameters. This enables tree-shaking—if you use a custom filter, you don't pay for built-in filters you never use. ### Customize/Fork Row Models You don't have to use the exact row models that are provided by TanStack Table. If you need some advanced customization for certain row models, feel free to copy the [source code](https://github.com/TanStack/table/tree/main/packages/table-core/src/utils) for the row model you want to customize and modify it to your needs. ### Using Row Models Once your table instance has been created, you can access all of the row models that you may need directly from the table instance. There are even more derived row models available apart from the ones that you may have imported. For normal rendering use cases, you will probably only need to use the `table.getRowModel()` method, as this row model will use all/any of the other row models depending on which features you have enabled or disabled. All of the other row models are available for you to "dig into" some of the underlying data transformations that are happening in the table. ### Available Row Models on Table Instance - **`getRowModel`** - This is the main row model that you should use for rendering your table rows markup. It will use all of the other row models to generate the final row model that you will use to render your table rows. - `getCoreRowModel` - returns a basic row model that is just a 1:1 mapping of the original data passed to the table. - `getFilteredRowModel` - returns a row model that accounts for column filtering and global filtering. - `getPreFilteredRowModel` - returns a row model before column filtering and global filtering are applied. - `getGroupedRowModel` - returns a row model that applies grouping and aggregation to the data and creates sub-rows. - `getPreGroupedRowModel` - returns a row model before grouping and aggregation are applied. - `getSortedRowModel` - returns a row model that has had sorting applied to it. - `getPreSortedRowModel` - returns a row model before sorting is applied (rows are in original order). - `getExpandedRowModel` - returns a row model that accounts for expanded/hidden sub-rows. - `getPreExpandedRowModel` - returns a row model that only includes root level rows with no expanded sub-rows included. Still includes sorting. - `getPaginatedRowModel` - returns a row model that only includes the rows that should be displayed on the current page based on the pagination state. - `getPrePaginatedRowModel` - returns a row model without pagination applied (includes all rows). - `getSelectedRowModel` - returns a row model of all selected rows (but only based on the data that was passed to the table). Runs after getCoreRowModel. - `getPreSelectedRowModel` - returns a row model before row selection is applied (Just returns getCoreRowModel). - `getGroupedSelectedRowModel` - returns a row model of selected rows after grouping. Runs after getSortedRowModel, which runs after getGroupedRowModel, which runs after getFilteredRowModel. - `getFilteredSelectedRowModel` - returns a row model of selected rows after column filtering and global filtering. Runs after getFilteredRowModel. ### The Order of Row Model Execution Knowing how TanStack Table processes rows internally can help you gain a better understanding of what is happening under the hood, and help you debug any issues you may encounter. Internally, this is the order in which each of the row models are applied to the data, if their respective features are enabled: `getCoreRowModel` -> `getFilteredRowModel` -> `getGroupedRowModel` -> `getSortedRowModel` -> `getExpandedRowModel` -> `getPaginatedRowModel` -> `getRowModel` If in any case the respective feature is disabled or turned off with a `"manual*"` table option, the `getPre*RowModel` will be used instead in that step of the process. As you can see above, first the data is filtered, then grouped, then sorted, then expanded, and then finally paginated as the final step. ### Row Model Data Structure Each row model will provide you the rows in 3 different useful formats: 1. `rows` - An array of rows. 2. `flatRows` - An array of rows, but all sub-rows are flattened into the top level. 3. `rowsById` - An object of rows, where each row is keyed by its `id`. This is useful for quickly looking up rows by their `id` with better performance. ```ts console.log(table.getRowModel().rows) // array of rows console.log(table.getRowModel().flatRows) // array of rows, but all sub-rows are flattened into the top level console.log(table.getRowModel().rowsById['row-id']) // object of rows, where each row is keyed by its `id` ``` ================================================ FILE: docs/guide/row-pinning.md ================================================ --- title: Row Pinning Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [row-pinning](../framework/react/examples/row-pinning) ## API [Row Pinning API](../api/features/row-pinning) ## Row Pinning Guide There are 2 table features that can reorder rows, which happen in the following order: 1. **Row Pinning** - If pinning, rows are split into top, center (unpinned), and bottom pinned rows. 2. [Sorting](./sorting) ================================================ FILE: docs/guide/row-selection.md ================================================ --- title: Row Selection Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [React row-selection](../framework/react/examples/row-selection) - [Vue row-selection](../framework/vue/row-selection) - [React expanding](../framework/react/examples/expanding) ## API [Row Selection API](../api/features/row-selection) ## Row Selection Guide The row selection feature keeps track of which rows are selected and allows you to toggle the selection of rows in a myriad of ways. Let's take a look at some common use cases. ### Access Row Selection State The table instance already manages the row selection state for you (though as seen down below, it may be more convenient to manage the row selection state in your own scope). You can access the internal row selection state or the selected rows from a few APIs. - `table.store.state.rowSelection` - returns the internal row selection state - `getSelectedRowModel()` - returns selected rows - `getFilteredSelectedRowModel()` - returns selected rows after filtering - `getGroupedSelectedRowModel()` - returns selected rows after grouping and sorting ```ts console.log(table.store.state.rowSelection) //get the row selection state - { 1: true, 2: false, etc... } console.log(table.getSelectedRowModel().rows) //get full client-side selected rows console.log(table.getFilteredSelectedRowModel().rows) //get filtered client-side selected rows console.log(table.getGroupedSelectedRowModel().rows) //get grouped client-side selected rows ``` > Note: If you are using `manualPagination`, be aware that the `getSelectedRowModel` API will only return selected rows on the current page because table row models can only generate rows based on the `data` that is passed in. Row selection state, however, can contain row ids that are not present in the `data` array just fine. ### Manage Row Selection State Even though the table instance will already manage the row selection state for you, it is usually more convenient to manage the state yourself in order to have easy access to the selected row ids that you can use to make API calls or other actions. Use the `onRowSelectionChange` table option to hoist up the row selection state to your own scope. Then pass the row selection state back to the table instance using in the `state` table option. ```ts import { useTable, tableFeatures, rowSelectionFeature } from '@tanstack/react-table' const _features = tableFeatures({ rowSelectionFeature }) const [rowSelection, setRowSelection] = useState({}) const table = useTable({ _features, _rowModels: {}, //... onRowSelectionChange: setRowSelection, state: { rowSelection, }, }) ``` ### Useful Row Ids By default, the row id for each row is simply the `row.index`. If you are using row selection features, you most likely want to use a more useful row identifier, since the row selection state is keyed by row id. You can use the `getRowId` table option to specify a function that returns a unique row id for each row. ```ts const table = useTable({ _features, _rowModels: {}, //... getRowId: (row) => row.uuid, // use the row's uuid from your database as the row id }) ``` Now as rows are selected, the row selection state will look something like this: ```json { "13e79140-62a8-4f9c-b087-5da737903b76": true, "f3e2a5c0-5b7a-4d8a-9a5c-9c9b8a8e5f7e": false //... } ``` instead of this: ```json { "0": true, "1": false //... } ``` ### Enable Row Selection Conditionally Row selection is enabled by default for all rows. To either enable row selection conditionally for certain rows or disable row selection for all rows, you can use the `enableRowSelection` table option which accepts either a boolean or a function for more granular control. ```ts const table = useTable({ //... enableRowSelection: row => row.original.age > 18, //only enable row selection for adults }) ``` To enforce whether a row is selectable or not in your UI, you can use the `row.getCanSelect()` API for your checkboxes or other selection UI. ### Single Row Selection By default, the table allows multiple rows to be selected at once. If, however, you only want to allow a single row to be selected at once, you can set the `enableMultiRowSelection` table option to `false` to disable multi-row selection, or pass in a function to disable multi-row selection conditionally for a row's sub-rows. This is useful for making tables that have radio buttons instead of checkboxes. ```ts const table = useTable({ //... enableMultiRowSelection: false, //only allow a single row to be selected at once // enableMultiRowSelection: row => row.original.age > 18, //only allow a single row to be selected at once for adults }) ``` ### Sub-Row Selection By default, selecting a parent row will select all of its sub-rows. If you want to disable auto sub-row selection, you can set the `enableSubRowSelection` table option to `false` to disable sub-row selection, or pass in a function to disable sub-row selection conditionally for a row's sub-rows. ```ts const table = useTable({ //... enableSubRowSelection: false, //disable sub-row selection // enableSubRowSelection: row => row.original.age > 18, //disable sub-row selection for adults }) ``` ### Render Row Selection UI TanStack table does not dictate how you should render your row selection UI. You can use checkboxes, radio buttons, or simply hook up click events to the row itself. The table instance provides a few APIs to help you render your row selection UI. #### Connect Row Selection APIs to Checkbox Inputs TanStack Table provides some handler functions that you can connect directly to your checkbox inputs to make it easy to toggle row selection. These function automatically call other internal APIs to update the row selection state and re-render the table. Use the `row.getToggleSelectedHandler()` API to connect to your checkbox inputs to toggle the selection of a row. Use the `table.getToggleAllRowsSelectedHandler()` or `table.getToggleAllPageRowsSelectedHandler` APIs to connect to your "select all" checkbox input to toggle the selection of all rows. If you need more granular control over these function handlers, you can always just use the `row.toggleSelected()` or `table.toggleAllRowsSelected()` APIs directly. Or you can even just call the `table.setRowSelection()` API to directly set the row selection state just as you would with any other state updater. These handler functions are just a convenience. ```tsx const columns = [ { id: 'select-col', header: ({ table }) => ( ), cell: ({ row }) => ( ), }, //... more column definitions... ] ``` #### Connect Row Selection APIs to UI If you want a simpler row selection UI, you can just hook up click events to the row itself. The `row.getToggleSelectedHandler()` API is also useful for this use case. ```tsx {table.getRowModel().rows.map(row => { return ( {row.getVisibleCells().map(cell => { return {/* */} })} ) })} ``` ================================================ FILE: docs/guide/rows.md ================================================ --- title: Rows Guide --- ## API [Row API](../api/core/row) ## Rows Guide This quick guide will discuss the different ways you can retrieve and interact with row objects in TanStack Table. ### Where to Get Rows From There are multiple `table` instance APIs you can use to retrieve rows from the table instance. #### table.getRow If you need to access a specific row by its `id`, you can use the `table.getRow` table instance API. ```js const row = table.getRow(rowId) ``` #### Row Models The `table` instance generates `row` objects and stores them in useful arrays called ["Row Models"](./row-models). This is discussed in much more detail in the [Row Models Guide](./row-models), but here are the most common ways you may access the row models. ##### Render Rows ```jsx {table.getRowModel().rows.map(row => ( {/* ... */} ))} ``` ##### Get Selected Rows ```js const selectedRows = table.getSelectedRowModel().rows ``` ### Row Objects Every row object contains row data and many APIs to either interact with the table state or extract cells from the row based on the state of the table. #### Row IDs Every row object has an `id` property that makes it unique within the table instance. By default the `row.id` is the same as the `row.index` that is created in the row model. However, it can be useful to override each row's `id` with a unique identifier from the row's data. You can use the `getRowId` table option to do this. ```js const table = useTable({ _features, _rowModels: {}, columns, data, getRowId: (originalRow) => originalRow.uuid, // override the row.id with the uuid from the original row's data }) ``` > Note: In some features like grouping and expanding, the `row.id` will have additional string appended to it. #### Access Row Values The recommended way to access data values from a row is to use either the `row.getValue` or `row.renderValue` APIs. Using either of these APIs will cache the results of the accessor functions and keep rendering efficient. The only difference between the two is that `row.renderValue` will return either the value or the `renderFallbackValue` if the value is undefined, whereas `row.getValue` will return the value or `undefined` if the value is undefined. ```js // Access data from any of the columns const firstName = row.getValue('firstName') // read the row value from the firstName column const renderedLastName = row.renderValue('lastName') // render the value from the lastName column ``` > Note: `cell.getValue` and `cell.renderValue` are shortcuts for the `row.getValue` and `row.renderValue` APIs, respectively. #### Access Original Row Data For every row object, you can access the original corresponding `data` that was passed to the table instance via the `row.original` property. None of the data in the `row.original` will have been modified by the accessors in your column definitions, so if you were doing any sort of data transformations in your accessors, those will not be reflected in the `row.original` object. ```js // Access any data from the original row const firstName = row.original.firstName // { firstName: 'John', lastName: 'Doe' } ``` ### Sub Rows If you are using either grouping or expanding features, your rows may contain sub-rows or parent row references. This is discussed in much more detail in the [Expanding Guide](./expanding), but here is a quick overview of useful properties and methods for working with sub-rows. - `row.subRows`: An array of sub-rows for the row. - `row.depth`: The depth of the row (if nested or grouped) relative to the root row array. 0 for root level rows, 1 for child rows, 2 for grandchild rows, etc. - `row.parentId`: The unique ID of the parent row for the row (The row that contains this row in its subRows array). - `row.getParentRow`: Returns the parent row for the row, if it exists. ### More Row APIs Depending on the features that you are using for your table, there are dozens more useful APIs for interacting with rows. See each features' respective API docs or guide for more information. ================================================ FILE: docs/guide/sorting.md ================================================ --- title: Sorting Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [sorting](../framework/react/examples/sorting) - [filters](../framework/react/examples/filters) ## API [Sorting API](../api/features/sorting) ## Sorting Guide TanStack Table provides solutions for just about any sorting use-case you might have. This guide will walk you through the various options that you can use to customize the built-in client-side sorting functionality, as well as how to opt out of client-side sorting in favor of manual server-side sorting. ### Sorting State The sorting state is defined as an array of objects with the following shape: ```tsx type ColumnSort = { id: string desc: boolean } type SortingState = ColumnSort[] ``` Since the sorting state is an array, it is possible to sort by multiple columns at once. Read more about the multi-sorting customizations down [below](#multi-sorting). #### Accessing Sorting State You can access the sorting state directly from the table instance just like any other state using the `table.store.state` API. ```tsx const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, //... }) console.log(table.store.state.sorting) // access the sorting state from the table instance ``` However, if you need to access the sorting state before the table is initialized, you can "control" the sorting state like down below. #### Controlled Sorting State If you need easy access to the sorting state, you can control/manage the sorting state in your own state management with the `state.sorting` and `onSortingChange` table options. ```tsx const [sorting, setSorting] = useState([]) // can set initial sorting state here //... // use sorting state to fetch data from your server or something... //... const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, //... state: { sorting, }, onSortingChange: setSorting, }) ``` #### Initial Sorting State If you do not need to control the sorting state in your own state management or scope, but you still want to set an initial sorting state, you can use the `initialState` table option instead of `state`. ```jsx const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, //... initialState: { sorting: [ { id: 'name', desc: true, // sort by name in descending order by default }, ], }, }) ``` > **NOTE**: Do not use both `initialState.sorting` and `state.sorting` at the same time, as the initialized state in the `state.sorting` will override the `initialState.sorting`. ### Client-Side vs Server-Side Sorting Whether or not you should use client-side or server-side sorting depends entirely on whether you are also using client-side or server-side pagination or filtering. Be consistent, because using client-side sorting with server-side pagination or filtering will only sort the data that is currently loaded, and not the entire dataset. ### Manual Server-Side Sorting If you plan to just use your own server-side sorting in your back-end logic, you do not need to provide a sorted row model. But if you have provided a sorting row model, but you want to disable it, you can use the `manualSorting` table option. ```jsx const [sorting, setSorting] = useState([]) //... const table = useTable({ _features: tableFeatures({ rowSortingFeature }), // feature needed for sorting state/APIs _rowModels: {}, // no sortedRowModel needed for manual sorting columns, data, manualSorting: true, // use pre-sorted row model instead of sorted row model state: { sorting, }, onSortingChange: setSorting, }) ``` > **NOTE**: When `manualSorting` is set to `true`, the table will assume that the data that you provide is already sorted, and will not apply any sorting to it. ### Client-Side Sorting To implement client-side sorting, add the `rowSortingFeature` to your features and the `sortedRowModel` to your row models. Import `createSortedRowModel` and `sortFns` from TanStack Table: ```jsx import { useTable, tableFeatures, rowSortingFeature, createSortedRowModel, sortFns, } from '@tanstack/react-table' const _features = tableFeatures({ rowSortingFeature }) const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), }, columns, data, }) ``` ### Sorting RowModelFns The default sorting function for all columns is inferred from the data type of the column. However, it can be useful to define the exact sorting function that you want to use for a specific column, especially if any of your data is nullable or not a standard data type. You can determine a custom sorting function on a per-column basis using the `sortFn` column option. By default, there are 6 built-in sorting functions to choose from: - `alphanumeric` - Sorts by mixed alphanumeric values without case-sensitivity. Slower, but more accurate if your strings contain numbers that need to be naturally sorted. - `alphanumericCaseSensitive` - Sorts by mixed alphanumeric values with case-sensitivity. Slower, but more accurate if your strings contain numbers that need to be naturally sorted. - `text` - Sorts by text/string values without case-sensitivity. Faster, but less accurate if your strings contain numbers that need to be naturally sorted. - `textCaseSensitive` - Sorts by text/string values with case-sensitivity. Faster, but less accurate if your strings contain numbers that need to be naturally sorted. - `datetime` - Sorts by time, use this if your values are `Date` objects. - `basic` - Sorts using a basic/standard `a > b ? 1 : a < b ? -1 : 0` comparison. This is the fastest sorting function, but may not be the most accurate. You can also define your own custom sorting functions either as the `sortFn` column option, or as a global sorting function using the `sortFns` table option. #### Custom Sorting Functions When defining a custom sorting function in either the `sortFns` table option or as a `sortFn` column option, it should have the following signature: ```tsx //optionally use the SortFn to infer the parameter types const myCustomSortFn: SortFn = (rowA: Row, rowB: Row, columnId: string) => { return //-1, 0, or 1 - access any row data using rowA.original and rowB.original } ``` > Note: The comparison function does not need to take whether or not the column is in descending or ascending order into account. The row models will take of that logic. `sortFn` functions only need to provide a consistent comparison. Every sorting function receives 2 rows and a column ID and are expected to compare the two rows using the column ID to return `-1`, `0`, or `1` in ascending order. Here's a cheat sheet: | Return | Ascending Order | | ------ | --------------- | | `-1` | `a < b` | | `0` | `a === b` | | `1` | `a > b` | ```jsx const columns = [ { header: () => 'Name', accessorKey: 'name', sortFn: 'alphanumeric', // use built-in sorting function by name }, { header: () => 'Age', accessorKey: 'age', sortFn: 'myCustomSortFn', // use custom global sorting function }, { header: () => 'Birthday', accessorKey: 'birthday', sortFn: 'datetime', // recommended for date columns }, { header: () => 'Profile', accessorKey: 'profile', // use custom sorting function directly sortFn: (rowA, rowB, columnId) => { return rowA.original.someProperty - rowB.original.someProperty }, } ] //... const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel({ ...sortFns, myCustomSortFn: (rowA, rowB, columnId) => rowA.original[columnId] > rowB.original[columnId] ? 1 : rowA.original[columnId] < rowB.original[columnId] ? -1 : 0, }), }, columns, data, }) ``` ### Customize Sorting There are a lot of table and column options that you can use to further customize the sorting UX and behavior. #### Disable Sorting You can disable sorting for either a specific column or the entire table using the `enableSorting` column option or table option. ```jsx const columns = [ { header: () => 'ID', accessorKey: 'id', enableSorting: false, // disable sorting for this column }, { header: () => 'Name', accessorKey: 'name', }, //... ] //... const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, enableSorting: false, // disable sorting for the entire table }) ``` #### Sorting Direction By default, the first sorting direction when cycling through the sorting for a column using the `toggleSorting` APIs is ascending for string columns and descending for number columns. You can change this behavior with the `sortDescFirst` column option or table option. ```jsx const columns = [ { header: () => 'Name', accessorKey: 'name', sortDescFirst: true, //sort by name in descending order first (default is ascending for string columns) }, { header: () => 'Age', accessorKey: 'age', sortDescFirst: false, //sort by age in ascending order first (default is descending for number columns) }, //... ] //... const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, sortDescFirst: true, //sort by all columns in descending order first (default is ascending for string columns and descending for number columns) }) ``` > **NOTE**: You may want to explicitly set the `sortDescFirst` column option on any columns that have nullable values. The table may not be able to properly determine if a column is a number or a string if it contains nullable values. #### Invert Sorting Inverting sorting is not the same as changing the default sorting direction. If `invertSorting` column option is `true` for a column, then the "desc/asc" sorting states will still cycle like normal, but the actual sorting of the rows will be inverted. This is useful for values that have an inverted best/worst scale where lower numbers are better, eg. a ranking (1st, 2nd, 3rd) or golf-like scoring. ```jsx const columns = [ { header: () => 'Rank', accessorKey: 'rank', invertSorting: true, // invert the sorting for this column. 1st -> 2nd -> 3rd -> ... even if "desc" sorting is applied }, //... ] ``` #### Sort Undefined Values Any undefined values will be sorted to the beginning or end of the list based on the `sortUndefined` column option or table option. You can customize this behavior for your specific use-case. In not specified, the default value for `sortUndefined` is `1`, and undefined values will be sorted with lower priority (descending), if ascending, undefined will appear on the end of the list. - `'first'` - Undefined values will be pushed to the beginning of the list - `'last'` - Undefined values will be pushed to the end of the list - `false` - Undefined values will be considered tied and need to be sorted by the next column filter or original index (whichever applies) - `-1` - Undefined values will be sorted with higher priority (ascending) (if ascending, undefined will appear on the beginning of the list) - `1` - Undefined values will be sorted with lower priority (descending) (if ascending, undefined will appear on the end of the list) > NOTE: `'first'` and `'last'` options are available in v9. ```jsx const columns = [ { header: () => 'Rank', accessorKey: 'rank', sortUndefined: -1, // 'first' | 'last' | 1 | -1 | false }, ] ``` #### Sorting Removal By default, the ability to remove sorting while cycling through the sorting states for a column is enabled. You can disable this behavior using the `enableSortingRemoval` table option. This behavior is useful if you want to ensure that at least one column is always sorted. The default behavior when using either the `getToggleSortingHandler` or `toggleSorting` APIs is to cycle through the sorting states like this: `'none' -> 'desc' -> 'asc' -> 'none' -> 'desc' -> 'asc' -> ...` If you disable sorting removal, the behavior will be like this: `'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ...` Once a column is sorted and `enableSortingRemoval` is `false`, toggling the sorting on that column will never remove the sorting. However, if the user sorts by another column and it is not a multi-sort event, then the sorting will be removed from the previous column and just applied to the new column. > Set `enableSortingRemoval` to `false` if you want to ensure that at least one column is always sorted. ```jsx const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, enableSortingRemoval: false, // disable the ability to remove sorting on columns (always none -> asc -> desc -> asc) }) ``` #### Multi-Sorting Sorting by multiple columns at once is enabled by default if using the `column.getToggleSortingHandler` API. If the user holds the `Shift` key while clicking on a column header, the table will sort by that column in addition to the columns that are already sorted. If you use the `column.toggleSorting` API, you have to manually pass in whether or not to use multi-sorting. (`column.toggleSorting(desc, multi)`). ##### Disable Multi-Sorting You can disable multi-sorting for either a specific column or the entire table using the `enableMultiSort` column option or table option. Disabling multi-sorting for a specific column will replace all existing sorting with the new column's sorting. ```jsx const columns = [ { header: () => 'Created At', accessorKey: 'createdAt', enableMultiSort: false, // always sort by just this column if sorting by this column }, //... ] //... const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, enableMultiSort: false, // disable multi-sorting for the entire table }) ``` ##### Customize Multi-Sorting Trigger By default, the `Shift` key is used to trigger multi-sorting. You can change this behavior with the `isMultiSortEvent` table option. You can even specify that all sorting events should trigger multi-sorting by returning `true` from the custom function. ```jsx const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, isMultiSortEvent: (e) => true, // normal click triggers multi-sorting //or isMultiSortEvent: (e) => e.ctrlKey || e.shiftKey, // also use the `Ctrl` key to trigger multi-sorting }) ``` ##### Multi-Sorting Limit By default, there is no limit to the number of columns that can be sorted at once. You can set a limit using the `maxMultiSortColCount` table option. ```jsx const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, maxMultiSortColCount: 3, // only allow 3 columns to be sorted at once }) ``` ##### Multi-Sorting Removal By default, the ability to remove multi-sorts is enabled. You can disable this behavior using the `enableMultiRemove` table option. ```jsx const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, enableMultiRemove: false, // disable the ability to remove multi-sorts }) ``` ### Sorting APIs There are a lot of sorting related APIs that you can use to hook up to your UI or other logic. Here is a list of all of the sorting APIs and some of their use-cases. - `table.setSorting` - Set the sorting state directly. - `table.resetSorting` - Reset the sorting state to the initial state or clear it. - `column.getCanSort` - Useful for enabling/disabling the sorting UI for a column. - `column.getIsSorted` - Useful for showing a visual sorting indicator for a column. - `column.getToggleSortingHandler` - Useful for hooking up the sorting UI for a column. Add to a sort arrow (icon button), menu item, or simply the entire column header cell. This handler will call `column.toggleSorting` with the correct parameters. - `column.toggleSorting` - Useful for hooking up the sorting UI for a column. If using instead of `column.getToggleSortingHandler`, you have to manually pass in whether or not to use multi-sorting. (`column.toggleSorting(desc, multi)`) - `column.clearSorting` - Useful for a "clear sorting" button or menu item for a specific column. - `column.getNextSortingOrder` - Useful for showing which direction the column will sort by next. (asc/desc/clear in a tooltip/menu item/aria-label or something) - `column.getFirstSortDir` - Useful for showing which direction the column will sort by first. (asc/desc in a tooltip/menu item/aria-label or something) - `column.getAutoSortDir` - Determines whether the first sorting direction will be ascending or descending for a column. - `column.getAutoSortFn` - Used internally to find the default sorting function for a column if none is specified. - `column.getSortFn` - Returns the exact sorting function being used for a column. - `column.getCanMultiSort` - Useful for enabling/disabling the multi-sorting UI for a column. - `column.getSortIndex` - Useful for showing a badge or indicator of the column's sort order in a multi-sort scenario. i.e. whether or not it is the first, second, third, etc. column to be sorted. ================================================ FILE: docs/guide/tables.md ================================================ --- title: Table Instance Guide --- ## API [Table API](../api/core/table) ## Table Instance Guide TanStack Table is a headless UI library. When we talk about the `table` or "table instance", we're not talking about a literal `` element. Instead, we're referring to the core table object that contains the table state and APIs. The `table` instance is created by calling your adapter's `_createTable` function (e.g. `useTable`, `createTable`, or `injectTable`). The `table` instance that is returned from the `_createTable` function (from the framework adapter) is the main object that you will interact with to read and mutate the table state. It is the one place where everything happens in TanStack Table. When you get to the point where you are rendering your UI, you will use APIs from this `table` instance. ### Creating a Table Instance To create a table instance, 3 `options` are required: `columns`, `data`, and `_features`. The `_features` option declares which table features your table uses (enabling tree-shaking—you only bundle what you use). The core row model is included automatically; add additional row models via `_rowModels` when you need filtering, sorting, pagination, etc. There are dozens of other table options to configure features and behavior. #### Defining Data Define your data as an array of objects with a stable reference. `data` can come from anywhere like an API response or defined statically in your code, but it must have a stable reference to prevent infinite re-renders. If using TypeScript, the type that you give your data will be used as a `TData` generic. See the [Data Guide](./data) for more info. #### Defining Columns Column definitions are covered in detail in the previous section in the [Column Def Guide](./column-defs). We'll note here, however, that when you define the type of your columns, you should use the same `TData` type that you used for your data. ```ts const _features = tableFeatures({}) // Define which features your table uses const columns: ColumnDef[] = [] // Pass User type as TData; use typeof _features for TFeatures //or const columnHelper = createColumnHelper() // Pass both TFeatures and TData in v9 ``` The column definitions are where we will tell TanStack Table how each column should access and/or transform row data with either an `accessorKey` or `accessorFn`. See the [Column Def Guide](./column-defs#creating-accessor-columns) for more info. #### Defining Features and Row Models This is explained in much more detail in the [Row Models Guide](./row-models). In v9, you declare which features your table uses via `_features` (using `tableFeatures()`), and which row models to apply via `_rowModels`. The core row model is always included automatically. For a basic table with no filtering, sorting, or pagination, pass an empty features object and empty row models: ```ts import { tableFeatures } from '@tanstack/[framework]-table' const _features = tableFeatures({}) // Core features only; add columnFilteringFeature, rowSortingFeature, etc. as needed const table = _createTable({ _features, _rowModels: {}, // Core row model is automatic; add filteredRowModel, sortedRowModel, etc. as needed columns, data, }) ``` #### Initializing the Table Instance With our `_features`, `columns`, `data`, and `_rowModels` defined, we can now create our basic table instance, along side any other table options that we want to pass in. > **Framework note:** This guide uses React examples. Other frameworks (Angular, Lit, Solid, Svelte, Vue) use `createTable`, `injectTable`, or similar with the same options. ```ts //vanilla js const table = _createTable({ _features, _rowModels: {}, columns, data }) //angular this.table = injectTable({ _features, _rowModels: {}, columns: this.columns, data: this.data() }) //lit const table = this.tableController.table({ _features, _rowModels: {}, columns, data }) //react const table = useTable({ _features, _rowModels: {}, columns, data }) //solid const table = createTable({ _features, _rowModels: {}, columns, get data() { return data() } }) //svelte const table = createTable({ _features, _rowModels: {}, columns, data }) //vue const table = useTable({ _features, _rowModels: {}, columns, data }) ``` So what's in the `table` instance? Let's take a look at what interactions we can have with the table instance. ### Table State The table instance contains all of the table state, which can be accessed via the `table.store.state` API. Each table feature registers various states in the table state. For example, the row selection feature registers `rowSelection` state, the pagination feature registers `pagination` state, etc. Each feature will also have corresponding state setter APIs and state resetter APIs on the table instance. For example, the row selection feature will have a `setRowSelection` API and a `resetRowSelection`. ```ts table.store.state.rowSelection //read the row selection state table.setRowSelection((old) => ({...old})) //set the row selection state table.resetRowSelection() //reset the row selection state ``` This is covered in more detail in the [Table State Guides](../framework/react/guide/table-state) ### Table APIs There are dozens of table APIs created by each feature to help you either read or mutate the table state in different ways. API reference docs for the core table instance and all other feature APIs can be found throughout the API docs. For example, you can find the core table instance API docs here: [Table API](../api/core/table#table-api) ### Table Row Models There is a special set of table instance APIs for reading rows out of the table instance called row models. TanStack Table has advanced features where the rows that are generated may be very different than the array of `data` that you originally passed in. To learn more about the different row models that you can pass in as a table option, see the [Row Models Guide](./row-models). ================================================ FILE: docs/guide/virtualization.md ================================================ --- title: Virtualization Guide --- ## Examples Want to skip to the implementation? Check out these examples: - [virtualized-columns](../framework/react/examples/virtualized-columns) - [virtualized-rows (dynamic row height)](../framework/react/examples/virtualized-rows) - [virtualized-rows (fixed row height)](https://tanstack.com/virtual/latest/docs/framework/react/examples/table) - [virtualized-infinite-scrolling](../framework/react/examples/virtualized-infinite-scrolling) ## API [TanStack Virtual Virtualizer API](https://tanstack.com/virtual/latest/docs/api/virtualizer) ## Virtualization Guide The TanStack Table packages do not come with any virtualization APIs or features built-in, but TanStack Table can easily work with other virtualization libraries like [react-window](https://www.npmjs.com/package/react-window) or TanStack's own [TanStack Virtual](https://tanstack.com/virtual/v3). This guide will show some strategies for using TanStack Table with TanStack Virtual. ================================================ FILE: docs/installation.md ================================================ --- title: Installation --- Before we dig in to the API, let's get you set up! Install your table adapter as a dependency using your preferred package manager: react: @tanstack/react-table vue: @tanstack/vue-table solid: @tanstack/solid-table svelte: @tanstack/svelte-table angular: @tanstack/angular-table lit: @tanstack/lit-table # React The `@tanstack/react-table` package works with React 16.8, React 17, React 18, and React 19. > [!NOTE] > Even though the React adapter works with React 19, it may not work with the new React Compiler that's coming out alongside React 19. This may be fixed in future TanStack Table updates. # Vue The `@tanstack/vue-table` package works with Vue 3. # Solid The `@tanstack/solid-table` package works with Solid-JS 1. # Svelte The `@tanstack/svelte-table` package works with Svelte 3 and Svelte 4. > [!NOTE] > There is not a built-in Svelte 5 adapter yet, but you can still use TanStack Table with Svelte 5 by installing the `@tanstack/table-core` package and using a custom adapter from the community. See this [PR](https://github.com/TanStack/table/pull/5403) for inspiration. # Angular The `@tanstack/angular-table` package works with Angular 17. The Angular adapter uses a new Angular Signal implementation. # Lit The `@tanstack/lit-table` package works with Lit 3. Don't see your favorite framework (or favorite version of your framework) listed? You can always just use the `@tanstack/table-core` package and build your own adapter in your own codebase. Usually, only a thin wrapper is needed to manage state and rendering for your specific framework. Browse the [source code](https://github.com/TanStack/table/tree/main/packages) of all of the other adapters to see how they work. ================================================ FILE: docs/introduction.md ================================================ --- title: Introduction --- TanStack Table is a **Headless UI** library for building powerful tables & datagrids for TS/JS, React, Vue, Solid, and Svelte. ## What is "headless" UI? **Headless UI** is a term for libraries and utilities that provide the logic, state, processing and API for UI elements and interactions, but **do not provide markup, styles, or pre-built implementations**. Scratching your head yet? 😉 Headless UI has a few main goals: The hardest parts of building complex UIs usually revolve around state, events, side-effects, data computation/management. By removing these concerns from the markup, styles and implementation details, our logic and components can be more modular and reusable. Building UI is a very branded and custom experience, even if that means choosing a design system or adhering to a design spec. To support this custom experience, component-based UI libraries need to support a massive (and seemingly endless) API surface around markup and style customization. Headless UI libraries decouple your logic from your UI When you use a headless UI library, the complex task of **data-processing, state-management, and business logic** are handled for you, leaving you to worry about higher-cardinality decisions that differ across implementations and use cases. > Want to dive deeper? [Read more about Headless UI](https://www.merrickchristensen.com/articles/headless-user-interface-components/). ## Component-based libraries vs Headless libraries In the ecosystem of table/datagrid libraries, there are two main categories: - Component-based table libraries - Headless table libraries ### Which kind of table library should I use? Each approach has subtle tradeoffs. Understanding these subtleties will help you make the right decision for your application and team. ### Component-based Table Libraries Component-based table libraries will typically supply you with a feature-rich drop-in solution and ready-to-use components/markup complete with styles/theming. [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable) is a great example of this type of table library. **Pros:** - Ship with ready-to-use markup/styles - Little setup required - Turn-key experience **Cons:** - Less control over markup - Custom styles are typically theme-based - Larger bundle-sizes - Highly coupled to framework adapters and platforms **If you want a ready-to-use table and design/bundle-size are not hard requirements**, then you should consider using a component-based table library. There are a lot of component-based table libraries out there, but we believe [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable) is the gold standard and is by far our favorite grid-sibling (don't tell the others 🤫). ### Headless Table Libraries Headless table libraries will typically supply you with functions, state, utilities and event listeners to build your own table markup or attach to existing table markups. **Pros:** - Full control over markup and styles - Supports all styling patterns (CSS, CSS-in-JS, UI libraries, etc) - Smaller bundle-sizes - Portable. Run anywhere JS runs! **Cons:** - More setup required - No markup, styles or themes provided **If you want a lighter-weight table or full control over the design**, then you should consider using a headless table library. There are very few headless table libraries out there and obviously, **TanStack Table** is our favorite! ================================================ FILE: docs/overview.md ================================================ --- title: Overview --- TanStack Table's core is **framework agnostic**, which means its API is the same regardless of the framework you're using. Adapters are provided to make working with the table core easier depending on your framework. See the Adapters menu for available adapters. ## Typescript While TanStack Table is written in [TypeScript](https://www.typescriptlang.org/), using TypeScript in your application is optional (but recommended as it comes with outstanding benefits to both you and your codebase) If you use TypeScript, you will get top-notch type safety and editor autocomplete for all table APIs and state. ## Headless As it was mentioned extensively in the [Intro](./introduction) section, TanStack Table is **headless**. This means that it doesn't render any DOM elements, and instead relies on you, the UI/UX developer to provide the table's markup and styles. This is a great way to build a table that can be used in any UI framework, including React, Vue, Solid, Svelte, Angular, and even JS-to-native platforms like React Native! ## Agnostic Since TanStack Table is headless and runs on a vanilla JavaScript core, it is agnostic in a couple of ways: 1. TanStack Table is **Framework Agnostic**, which means you can use it with any JavaScript framework (or library) that you want. TanStack Table provides ready-to-use adapters for React, Vue, Solid, Svelte out of the box, but you can create your own adapter if you need to. 2. TanStack Table is **CSS / Component Library Agnostic**, which means that you can use TanStack Table with whatever CSS strategy or component library you want. TanStack Table itself does not render any table markup or styles. You bring your own! Want to use Tailwind or ShadCN? No problem! Want to use Material UI or Bootstrap? No problem! Have your own custom design system? TanStack Table was made for you! ## Core Objects and Types The table core uses the following abstractions, commonly exposed by adapters: - [Data](./guide/data) - The core data array you provide the table - [Column Defs](./guide/column-defs): Objects used to configure a column and its data model, display templates, and more - [Table Instance](./guide/tables): The core table object containing both state and API - [Row Models](./guide/row-models): How the `data` array is transformed into useful rows depending on the features you are using - [Rows](./guide/rows): Each row mirrors its respective row data and provides row-specific APIs - [Cells](./guide/cells): Each cell mirrors its respective row-column intersection and provides cell-specific APIs - [Header Groups](./guide/header-groups): Header groups are computed slices of nested header levels, each containing a group of headers - [Headers](./guide/headers): Each header is either directly associated with or derived from its column def and provides header-specific APIs - [Columns](./guide/columns): Each column mirrors its respective column def and also provides column-specific APIs ## Features TanStack Table will help you build just about any type of table you can imagine. It has built-in state and APIs for the following features: - [Column Faceting](./guide/column-faceting) - List unique lists of column values or min/max values for a column - [Column Filtering](./guide/column-filtering) - Filter rows based on search values for a column - [Column Grouping](./guide/grouping) - Group columns together, run aggregations, and more - [Column Ordering](./guide/column-ordering) - Dynamically change the order of columns - [Column Pinning](./guide/column-pinning) - Pin (Freeze) columns to the left or right of the table - [Column Sizing](./guide/column-sizing) - Dynamically change the size of columns (column resizing handles) - [Column Visibility](./guide/column-visibility) - Hide/show columns - [Global Faceting](./guide/global-faceting) - List unique lists of column values or min/max values for the entire table - [Global Filtering](./guide/global-filtering) - Filter rows based on search values for the entire table - [Row Expanding](./guide/expanding) - Expand/collapse rows (sub-rows) - [Row Pagination](./guide/pagination) - Paginate rows - [Row Pinning](./guide/row-pinning) - Pin (Freeze) rows to the top or bottom of the table - [Row Selection](./guide/row-selection) - Select/deselect rows (checkboxes) - [Row Sorting](./guide/sorting) - Sort rows by column values These are just some of the capabilities that you can build with TanStack Table. There are many more features that are possible with TanStack Table that you can add along-side the built-in features. [Virtualization](./guide/virtualization) is an example of a feature that is not built-in to TanStack Table, but can be achieved by using another library (like [TanStack Virtual](https://tanstack.com/virtual/v3)) and adding it along-side your other table rendering logic. TanStack Table also supports [Custom Features](./guide/custom-features) (plugins) that you can use to modify the table instance to add your own custom logic to the table in a more integrated way. And of course, you can just write your own state and hooks to add whatever other features you want for your table. The features from the TanStack Table core are just a solid foundation to build on, with a large focus on performance and DX. ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_arrIncludes/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:316](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L316) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_arrIncludes/index.md ================================================ --- id: filterFn_arrIncludes title: filterFn_arrIncludes --- # filterFn\_arrIncludes Filter function for checking if an array includes a given value. ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_arrIncludesAll/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:334](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L334) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_arrIncludesAll/index.md ================================================ --- id: filterFn_arrIncludesAll title: filterFn_arrIncludesAll --- # filterFn\_arrIncludesAll Filter function for checking if an array includes all of the given values. ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_arrIncludesSome/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:353](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L353) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_arrIncludesSome/index.md ================================================ --- id: filterFn_arrIncludesSome title: filterFn_arrIncludesSome --- # filterFn\_arrIncludesSome Filter function for checking if an array includes any of the given values. ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_equals/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L22) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_equals/index.md ================================================ --- id: filterFn_equals title: filterFn_equals --- # filterFn\_equals Filter function for checking if a value is exactly equal to a given value. (JS === comparison) ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_equalsString/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:99](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L99) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_equalsString/index.md ================================================ --- id: filterFn_equalsString title: filterFn_equalsString --- # filterFn\_equalsString Filter function for checking if a string is exactly equal to a given string. (Non-case-sensitive) ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_equalsStringSensitive/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:115](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L115) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_equalsStringSensitive/index.md ================================================ --- id: filterFn_equalsStringSensitive title: filterFn_equalsStringSensitive --- # filterFn\_equalsStringSensitive Filter function for checking if a string is exactly equal to a given string. (Case-sensitive) ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_greaterThan/functions/resolveFilterValue.md ================================================ --- id: resolveFilterValue title: resolveFilterValue --- # Function: resolveFilterValue() ```ts function resolveFilterValue(val): boolean; ``` Defined in: [fns/filterFns.ts:144](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L144) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_greaterThan/index.md ================================================ --- id: filterFn_greaterThan title: filterFn_greaterThan --- # filterFn\_greaterThan Filter function for checking if a number is greater than a given number. ## Functions - [resolveFilterValue](functions/resolveFilterValue.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_greaterThanOrEqualTo/functions/resolveFilterValue.md ================================================ --- id: resolveFilterValue title: resolveFilterValue --- # Function: resolveFilterValue() ```ts function resolveFilterValue(val): boolean; ``` Defined in: [fns/filterFns.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L163) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_greaterThanOrEqualTo/index.md ================================================ --- id: filterFn_greaterThanOrEqualTo title: filterFn_greaterThanOrEqualTo --- # filterFn\_greaterThanOrEqualTo Filter function for checking if a number is greater than or equal to a given number. ## Functions - [resolveFilterValue](functions/resolveFilterValue.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_inNumberRange/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:279](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L279) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_inNumberRange/functions/resolveFilterValue.md ================================================ --- id: resolveFilterValue title: resolveFilterValue --- # Function: resolveFilterValue() ```ts function resolveFilterValue(val): readonly [number, number]; ``` Defined in: [fns/filterFns.ts:258](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L258) ## Parameters ### val \[`any`, `any`\] ## Returns readonly \[`number`, `number`\] ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_inNumberRange/index.md ================================================ --- id: filterFn_inNumberRange title: filterFn_inNumberRange --- # filterFn\_inNumberRange Filter function for checking if a number is within a given range. ## Functions - [autoRemove](functions/autoRemove.md) - [resolveFilterValue](functions/resolveFilterValue.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_includesString/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L80) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_includesString/index.md ================================================ --- id: filterFn_includesString title: filterFn_includesString --- # filterFn\_includesString Filter function for checking if a string includes a given substring. (Non-case-sensitive) ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_includesStringSensitive/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L58) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_includesStringSensitive/index.md ================================================ --- id: filterFn_includesStringSensitive title: filterFn_includesStringSensitive --- # filterFn\_includesStringSensitive Filter function for checking if a string includes a given substring. (Case-sensitive) ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_lessThan/functions/resolveFilterValue.md ================================================ --- id: resolveFilterValue title: resolveFilterValue --- # Function: resolveFilterValue() ```ts function resolveFilterValue(val): boolean; ``` Defined in: [fns/filterFns.ts:179](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L179) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_lessThan/index.md ================================================ --- id: filterFn_lessThan title: filterFn_lessThan --- # filterFn\_lessThan Filter function for checking if a number is less than a given number. ## Functions - [resolveFilterValue](functions/resolveFilterValue.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_lessThanOrEqualTo/functions/resolveFilterValue.md ================================================ --- id: resolveFilterValue title: resolveFilterValue --- # Function: resolveFilterValue() ```ts function resolveFilterValue(val): boolean; ``` Defined in: [fns/filterFns.ts:195](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L195) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_lessThanOrEqualTo/index.md ================================================ --- id: filterFn_lessThanOrEqualTo title: filterFn_lessThanOrEqualTo --- # filterFn\_lessThanOrEqualTo Filter function for checking if a number is less than or equal to a given number. ## Functions - [resolveFilterValue](functions/resolveFilterValue.md) ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_weakEquals/functions/autoRemove.md ================================================ --- id: autoRemove title: autoRemove --- # Function: autoRemove() ```ts function autoRemove(val): boolean; ``` Defined in: [fns/filterFns.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L38) ## Parameters ### val `any` ## Returns `boolean` ================================================ FILE: docs/reference/@tanstack/namespaces/filterFn_weakEquals/index.md ================================================ --- id: filterFn_weakEquals title: filterFn_weakEquals --- # filterFn\_weakEquals Filter function for checking if a value is weakly equal to a given value. (JS == comparison) ## Functions - [autoRemove](functions/autoRemove.md) ================================================ FILE: docs/reference/functions/assignPrototypeAPIs.md ================================================ --- id: assignPrototypeAPIs title: assignPrototypeAPIs --- # Function: assignPrototypeAPIs() ```ts function assignPrototypeAPIs( feature, prototype, table, apis): void; ``` Defined in: [utils.ts:339](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L339) Assigns API methods to a prototype object for memory-efficient method sharing. All instances created with this prototype will share the same method references. For memoized methods, the memo state is lazily created and stored on each instance. This provides the best of both worlds: shared method code + per-instance caching. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TDeps `TDeps` *extends* readonly `any`[] ### TDepArgs `TDepArgs` ## Parameters ### feature keyof `TFeatures` & `string` ### prototype `Record`\<`string`, `any`\> ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### apis [`PrototypeAPIObject`](../type-aliases/PrototypeAPIObject.md)\<`TDeps`, [`NoInfer`](../type-aliases/NoInfer.md)\<`TDepArgs`\>\> ## Returns `void` ================================================ FILE: docs/reference/functions/assignTableAPIs.md ================================================ --- id: assignTableAPIs title: assignTableAPIs --- # Function: assignTableAPIs() ```ts function assignTableAPIs( feature, table, apis): void; ``` Defined in: [utils.ts:297](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L297) Assigns Table API methods directly to the table instance. Unlike row/cell/column/header, the table is a singleton so methods are assigned directly. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TDeps `TDeps` *extends* readonly `any`[] ### TDepArgs `TDepArgs` ## Parameters ### feature keyof `TFeatures` & `string` ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### apis [`APIObject`](../type-aliases/APIObject.md)\<`TDeps`, [`NoInfer`](../type-aliases/NoInfer.md)\<`TDepArgs`\>\> ## Returns `void` ================================================ FILE: docs/reference/functions/buildHeaderGroups.md ================================================ --- id: buildHeaderGroups title: buildHeaderGroups --- # Function: buildHeaderGroups() ```ts function buildHeaderGroups( allColumns, columnsToGroup, table, headerFamily?): HeaderGroup[]; ``` Defined in: [core/headers/buildHeaderGroups.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/buildHeaderGroups.ts#L11) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### allColumns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] ### columnsToGroup [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### headerFamily? `"left"` | `"right"` | `"center"` ## Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/callMemoOrStaticFn.md ================================================ --- id: callMemoOrStaticFn title: callMemoOrStaticFn --- # Function: callMemoOrStaticFn() ```ts function callMemoOrStaticFn( obj, fnKey, staticFn, ... args): ReturnType; ``` Defined in: [utils.ts:387](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L387) Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in. ## Type Parameters ### TObject `TObject` *extends* `Record`\<`string`, `any`\> ### TStaticFn `TStaticFn` *extends* `AnyFunction` ## Parameters ### obj `TObject` ### fnKey `string` ### staticFn `TStaticFn` ### args ...`Parameters`\<`TStaticFn`\> *extends* \[`any`, `...Rest[]`\] ? `Rest` : `never` ## Returns `ReturnType`\<`TStaticFn`\> ================================================ FILE: docs/reference/functions/cell_getContext.md ================================================ --- id: cell_getContext title: cell_getContext --- # Function: cell\_getContext() ```ts function cell_getContext(cell): object; ``` Defined in: [core/cells/coreCellsFeature.utils.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.utils.ts#L21) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### cell [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `object` ### cell ```ts cell: Cell; ``` ### column ```ts column: Column = cell.column; ``` ### getValue() ```ts getValue: () => NoInfer; ``` #### Returns [`NoInfer`](../type-aliases/NoInfer.md)\<`TValue`\> ### renderValue() ```ts renderValue: () => NoInfer; ``` #### Returns [`NoInfer`](../type-aliases/NoInfer.md)\<`TValue` \| `null`\> ### row ```ts row: Row = cell.row; ``` ### table ```ts table: Table_Internal = cell.table; ``` ================================================ FILE: docs/reference/functions/cell_getIsAggregated.md ================================================ --- id: cell_getIsAggregated title: cell_getIsAggregated --- # Function: cell\_getIsAggregated() ```ts function cell_getIsAggregated(cell): boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:182](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L182) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### cell [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/cell_getIsGrouped.md ================================================ --- id: cell_getIsGrouped title: cell_getIsGrouped --- # Function: cell\_getIsGrouped() ```ts function cell_getIsGrouped(cell): boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L163) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### cell [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/cell_getIsPlaceholder.md ================================================ --- id: cell_getIsPlaceholder title: cell_getIsPlaceholder --- # Function: cell\_getIsPlaceholder() ```ts function cell_getIsPlaceholder(cell): boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:174](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L174) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### cell [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/cell_getValue.md ================================================ --- id: cell_getValue title: cell_getValue --- # Function: cell\_getValue() ```ts function cell_getValue(cell): TValue; ``` Defined in: [core/cells/coreCellsFeature.utils.ts:5](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.utils.ts#L5) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### cell [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `TValue` ================================================ FILE: docs/reference/functions/cell_renderValue.md ================================================ --- id: cell_renderValue title: cell_renderValue --- # Function: cell\_renderValue() ```ts function cell_renderValue(cell): any; ``` Defined in: [core/cells/coreCellsFeature.utils.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.utils.ts#L13) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### cell [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `any` ================================================ FILE: docs/reference/functions/column_clearSorting.md ================================================ --- id: column_clearSorting title: column_clearSorting --- # Function: column\_clearSorting() ```ts function column_clearSorting(column): void; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:290](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L290) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `void` ================================================ FILE: docs/reference/functions/column_getAfter.md ================================================ --- id: column_getAfter title: column_getAfter --- # Function: column\_getAfter() ```ts function column_getAfter(column, position): number; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L66) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `number` ================================================ FILE: docs/reference/functions/column_getAggregationFn.md ================================================ --- id: column_getAggregationFn title: column_getAggregationFn --- # Function: column\_getAggregationFn() ```ts function column_getAggregationFn(column): | AggregationFn | undefined; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L97) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns \| [`AggregationFn`](../type-aliases/AggregationFn.md)\<`TFeatures`, `TData`\> \| `undefined` ================================================ FILE: docs/reference/functions/column_getAutoAggregationFn.md ================================================ --- id: column_getAutoAggregationFn title: column_getAutoAggregationFn --- # Function: column\_getAutoAggregationFn() ```ts function column_getAutoAggregationFn(column): | AggregationFn | undefined; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L75) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns \| [`AggregationFn`](../type-aliases/AggregationFn.md)\<`TFeatures`, `TData`\> \| `undefined` ================================================ FILE: docs/reference/functions/column_getAutoFilterFn.md ================================================ --- id: column_getAutoFilterFn title: column_getAutoFilterFn --- # Function: column\_getAutoFilterFn() ```ts function column_getAutoFilterFn(column): | FilterFn | undefined; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L15) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns \| [`FilterFn`](../interfaces/FilterFn.md)\<`TFeatures`, `TData`\> \| `undefined` ================================================ FILE: docs/reference/functions/column_getAutoSortDir.md ================================================ --- id: column_getAutoSortDir title: column_getAutoSortDir --- # Function: column\_getAutoSortDir() ```ts function column_getAutoSortDir(column): "asc" | "desc"; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L76) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `"asc"` \| `"desc"` ================================================ FILE: docs/reference/functions/column_getAutoSortFn.md ================================================ --- id: column_getAutoSortFn title: column_getAutoSortFn --- # Function: column\_getAutoSortFn() ```ts function column_getAutoSortFn(column): SortFn; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L38) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`SortFn`](../interfaces/SortFn.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/column_getCanFilter.md ================================================ --- id: column_getCanFilter title: column_getCanFilter --- # Function: column\_getCanFilter() ```ts function column_getCanFilter(column): boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L77) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanGlobalFilter.md ================================================ --- id: column_getCanGlobalFilter title: column_getCanGlobalFilter --- # Function: column\_getCanGlobalFilter() ```ts function column_getCanGlobalFilter(column): boolean; ``` Defined in: [features/global-filtering/globalFilteringFeature.utils.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.utils.ts#L9) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanGroup.md ================================================ --- id: column_getCanGroup title: column_getCanGroup --- # Function: column\_getCanGroup() ```ts function column_getCanGroup(column): boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L34) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanHide.md ================================================ --- id: column_getCanHide title: column_getCanHide --- # Function: column\_getCanHide() ```ts function column_getCanHide(column): boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L44) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanMultiSort.md ================================================ --- id: column_getCanMultiSort title: column_getCanMultiSort --- # Function: column\_getCanMultiSort() ```ts function column_getCanMultiSort(column): boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:257](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L257) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanPin.md ================================================ --- id: column_getCanPin title: column_getCanPin --- # Function: column\_getCanPin() ```ts function column_getCanPin(column): boolean; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L69) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanResize.md ================================================ --- id: column_getCanResize title: column_getCanResize --- # Function: column\_getCanResize() ```ts function column_getCanResize(column): boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L26) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getCanSort.md ================================================ --- id: column_getCanSort title: column_getCanSort --- # Function: column\_getCanSort() ```ts function column_getCanSort(column): boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:245](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L245) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getFacetedMinMaxValues.md ================================================ --- id: column_getFacetedMinMaxValues title: column_getFacetedMinMaxValues --- # Function: column\_getFacetedMinMaxValues() ```ts function column_getFacetedMinMaxValues(column, table): [number, number] | undefined; ``` Defined in: [features/column-faceting/columnFacetingFeature.utils.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts#L7) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns \[`number`, `number`\] \| `undefined` ================================================ FILE: docs/reference/functions/column_getFacetedRowModel.md ================================================ --- id: column_getFacetedRowModel title: column_getFacetedRowModel --- # Function: column\_getFacetedRowModel() ```ts function column_getFacetedRowModel(column, table): RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.utils.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts#L21) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> | `undefined` ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/column_getFacetedUniqueValues.md ================================================ --- id: column_getFacetedUniqueValues title: column_getFacetedUniqueValues --- # Function: column\_getFacetedUniqueValues() ```ts function column_getFacetedUniqueValues(column, table): Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.utils.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts#L35) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/functions/column_getFilterFn.md ================================================ --- id: column_getFilterFn title: column_getFilterFn --- # Function: column\_getFilterFn() ```ts function column_getFilterFn(column): | FilterFn | undefined; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L51) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns \| [`FilterFn`](../interfaces/FilterFn.md)\<`TFeatures`, `TData`\> \| `undefined` ================================================ FILE: docs/reference/functions/column_getFilterIndex.md ================================================ --- id: column_getFilterIndex title: column_getFilterIndex --- # Function: column\_getFilterIndex() ```ts function column_getFilterIndex(column): number; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:107](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L107) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/column_getFilterValue.md ================================================ --- id: column_getFilterValue title: column_getFilterValue --- # Function: column\_getFilterValue() ```ts function column_getFilterValue(column): unknown; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L98) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `unknown` ================================================ FILE: docs/reference/functions/column_getFirstSortDir.md ================================================ --- id: column_getFirstSortDir title: column_getFirstSortDir --- # Function: column\_getFirstSortDir() ```ts function column_getFirstSortDir(column): "asc" | "desc"; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:211](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L211) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `"asc"` \| `"desc"` ================================================ FILE: docs/reference/functions/column_getFlatColumns.md ================================================ --- id: column_getFlatColumns title: column_getFlatColumns --- # Function: column\_getFlatColumns() ```ts function column_getFlatColumns(column): Column[]; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] ================================================ FILE: docs/reference/functions/column_getGroupedIndex.md ================================================ --- id: column_getGroupedIndex title: column_getGroupedIndex --- # Function: column\_getGroupedIndex() ```ts function column_getGroupedIndex(column): number; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L54) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/column_getIndex.md ================================================ --- id: column_getIndex title: column_getIndex --- # Function: column\_getIndex() ```ts function column_getIndex(column, position?): number; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `number` ================================================ FILE: docs/reference/functions/column_getIsFiltered.md ================================================ --- id: column_getIsFiltered title: column_getIsFiltered --- # Function: column\_getIsFiltered() ```ts function column_getIsFiltered(column): boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L90) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getIsFirstColumn.md ================================================ --- id: column_getIsFirstColumn title: column_getIsFirstColumn --- # Function: column\_getIsFirstColumn() ```ts function column_getIsFirstColumn(column, position?): boolean; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L26) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getIsGrouped.md ================================================ --- id: column_getIsGrouped title: column_getIsGrouped --- # Function: column\_getIsGrouped() ```ts function column_getIsGrouped(column): boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L46) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getIsLastColumn.md ================================================ --- id: column_getIsLastColumn title: column_getIsLastColumn --- # Function: column\_getIsLastColumn() ```ts function column_getIsLastColumn(column, position?): boolean; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L38) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getIsPinned.md ================================================ --- id: column_getIsPinned title: column_getIsPinned --- # Function: column\_getIsPinned() ```ts function column_getIsPinned(column): ColumnPinningPosition; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L85) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) ================================================ FILE: docs/reference/functions/column_getIsResizing.md ================================================ --- id: column_getIsResizing title: column_getIsResizing --- # Function: column\_getIsResizing() ```ts function column_getIsResizing(column): boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L37) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getIsSorted.md ================================================ --- id: column_getIsSorted title: column_getIsSorted --- # Function: column\_getIsSorted() ```ts function column_getIsSorted(column): false | SortDirection; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L269) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `false` \| [`SortDirection`](../type-aliases/SortDirection.md) ================================================ FILE: docs/reference/functions/column_getIsVisible.md ================================================ --- id: column_getIsVisible title: column_getIsVisible --- # Function: column\_getIsVisible() ```ts function column_getIsVisible(column): boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L29) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/column_getLeafColumns.md ================================================ --- id: column_getLeafColumns title: column_getLeafColumns --- # Function: column\_getLeafColumns() ```ts function column_getLeafColumns(column): Column[]; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L24) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] ================================================ FILE: docs/reference/functions/column_getNextSortingOrder.md ================================================ --- id: column_getNextSortingOrder title: column_getNextSortingOrder --- # Function: column\_getNextSortingOrder() ```ts function column_getNextSortingOrder(column, multi?): false | "asc" | "desc"; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:223](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L223) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### multi? `boolean` ## Returns `false` \| `"asc"` \| `"desc"` ================================================ FILE: docs/reference/functions/column_getPinnedIndex.md ================================================ --- id: column_getPinnedIndex title: column_getPinnedIndex --- # Function: column\_getPinnedIndex() ```ts function column_getPinnedIndex(column): number; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:103](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L103) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/column_getSize.md ================================================ --- id: column_getSize title: column_getSize --- # Function: column\_getSize() ```ts function column_getSize(column): number; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L29) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/column_getSortFn.md ================================================ --- id: column_getSortFn title: column_getSortFn --- # Function: column\_getSortFn() ```ts function column_getSortFn(column): SortFn; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L92) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`SortFn`](../interfaces/SortFn.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/column_getSortIndex.md ================================================ --- id: column_getSortIndex title: column_getSortIndex --- # Function: column\_getSortIndex() ```ts function column_getSortIndex(column): number; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:280](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L280) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/column_getStart.md ================================================ --- id: column_getStart title: column_getStart --- # Function: column\_getStart() ```ts function column_getStart(column, position): number; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L46) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `number` ================================================ FILE: docs/reference/functions/column_getToggleGroupingHandler.md ================================================ --- id: column_getToggleGroupingHandler title: column_getToggleGroupingHandler --- # Function: column\_getToggleGroupingHandler() ```ts function column_getToggleGroupingHandler(column): () => void; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L62) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns ```ts (): void; ``` ### Returns `void` ================================================ FILE: docs/reference/functions/column_getToggleSortingHandler.md ================================================ --- id: column_getToggleSortingHandler title: column_getToggleSortingHandler --- # Function: column\_getToggleSortingHandler() ```ts function column_getToggleSortingHandler(column): (e) => void; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:301](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L301) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/column_getToggleVisibilityHandler.md ================================================ --- id: column_getToggleVisibilityHandler title: column_getToggleVisibilityHandler --- # Function: column\_getToggleVisibilityHandler() ```ts function column_getToggleVisibilityHandler(column): (e) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L55) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/column_pin.md ================================================ --- id: column_pin title: column_pin --- # Function: column\_pin() ```ts function column_pin(column, position): void; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L31) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) ## Returns `void` ================================================ FILE: docs/reference/functions/column_resetSize.md ================================================ --- id: column_resetSize title: column_resetSize --- # Function: column\_resetSize() ```ts function column_resetSize(column): void; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L88) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `void` ================================================ FILE: docs/reference/functions/column_setFilterValue.md ================================================ --- id: column_setFilterValue title: column_setFilterValue --- # Function: column\_setFilterValue() ```ts function column_setFilterValue(column, value): void; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:119](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L119) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### value `any` ## Returns `void` ================================================ FILE: docs/reference/functions/column_toggleGrouping.md ================================================ --- id: column_toggleGrouping title: column_toggleGrouping --- # Function: column\_toggleGrouping() ```ts function column_toggleGrouping(column): void; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L19) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `void` ================================================ FILE: docs/reference/functions/column_toggleSorting.md ================================================ --- id: column_toggleSorting title: column_toggleSorting --- # Function: column\_toggleSorting() ```ts function column_toggleSorting( column, desc?, multi?): void; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L108) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### desc? `boolean` ### multi? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/column_toggleVisibility.md ================================================ --- id: column_toggleVisibility title: column_toggleVisibility --- # Function: column\_toggleVisibility() ```ts function column_toggleVisibility(column, visible?): void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ### visible? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/constructCell.md ================================================ --- id: constructCell title: constructCell --- # Function: constructCell() ```ts function constructCell( column, row, table): Cell; ``` Defined in: [core/cells/constructCell.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/constructCell.ts#L26) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### column [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `TValue`\> ================================================ FILE: docs/reference/functions/constructColumn.md ================================================ --- id: constructColumn title: constructColumn --- # Function: constructColumn() ```ts function constructColumn( table, columnDef, depth, parent?): Column; ``` Defined in: [core/columns/constructColumn.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/constructColumn.ts#L30) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### columnDef [`ColumnDef`](../type-aliases/ColumnDef.md)\<`TFeatures`, `TData`, `TValue`\> ### depth `number` ### parent? [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> ================================================ FILE: docs/reference/functions/constructColumnFacetingFeature.md ================================================ --- id: constructColumnFacetingFeature title: constructColumnFacetingFeature --- # Function: constructColumnFacetingFeature() ```ts function constructColumnFacetingFeature(): TableFeature>; ``` Defined in: [features/column-faceting/columnFacetingFeature.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts#L32) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnFacetingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnFilteringFeature.md ================================================ --- id: constructColumnFilteringFeature title: constructColumnFilteringFeature --- # Function: constructColumnFilteringFeature() ```ts function constructColumnFilteringFeature(): TableFeature>; ``` Defined in: [features/column-filtering/columnFilteringFeature.ts:47](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.ts#L47) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnFilteringFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnGroupingFeature.md ================================================ --- id: constructColumnGroupingFeature title: constructColumnGroupingFeature --- # Function: constructColumnGroupingFeature() ```ts function constructColumnGroupingFeature(): TableFeature>; ``` Defined in: [features/column-grouping/columnGroupingFeature.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.ts#L54) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnGroupingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnOrderingFeature.md ================================================ --- id: constructColumnOrderingFeature title: constructColumnOrderingFeature --- # Function: constructColumnOrderingFeature() ```ts function constructColumnOrderingFeature(): TableFeature>; ``` Defined in: [features/column-ordering/columnOrderingFeature.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts#L34) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnOrderingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnPinningFeature.md ================================================ --- id: constructColumnPinningFeature title: constructColumnPinningFeature --- # Function: constructColumnPinningFeature() ```ts function constructColumnPinningFeature(): TableFeature>; ``` Defined in: [features/column-pinning/columnPinningFeature.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.ts#L62) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnPinningFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnResizingFeature.md ================================================ --- id: constructColumnResizingFeature title: constructColumnResizingFeature --- # Function: constructColumnResizingFeature() ```ts function constructColumnResizingFeature(): TableFeature>; ``` Defined in: [features/column-resizing/columnResizingFeature.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.ts#L35) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnResizingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnSizingFeature.md ================================================ --- id: constructColumnSizingFeature title: constructColumnSizingFeature --- # Function: constructColumnSizingFeature() ```ts function constructColumnSizingFeature(): TableFeature>; ``` Defined in: [features/column-sizing/columnSizingFeature.ts:47](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.ts#L47) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnSizingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructColumnVisibilityFeature.md ================================================ --- id: constructColumnVisibilityFeature title: constructColumnVisibilityFeature --- # Function: constructColumnVisibilityFeature() ```ts function constructColumnVisibilityFeature(): TableFeature>; ``` Defined in: [features/column-visibility/columnVisibilityFeature.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts#L51) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`ColumnVisibilityFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructCoreCellsFeature.md ================================================ --- id: constructCoreCellsFeature title: constructCoreCellsFeature --- # Function: constructCoreCellsFeature() ```ts function constructCoreCellsFeature(): TableFeature>; ``` Defined in: [core/cells/coreCellsFeature.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.ts#L19) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`CoreCellsFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructCoreColumnsFeature.md ================================================ --- id: constructCoreColumnsFeature title: constructCoreColumnsFeature --- # Function: constructCoreColumnsFeature() ```ts function constructCoreColumnsFeature(): TableFeature>; ``` Defined in: [core/columns/coreColumnsFeature.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.ts#L29) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`CoreColumnsFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructCoreHeadersFeature.md ================================================ --- id: constructCoreHeadersFeature title: constructCoreHeadersFeature --- # Function: constructCoreHeadersFeature() ```ts function constructCoreHeadersFeature(): TableFeature>; ``` Defined in: [core/headers/coreHeadersFeature.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.ts#L31) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`CoreHeadersFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructCoreRowModelsFeature.md ================================================ --- id: constructCoreRowModelsFeature title: constructCoreRowModelsFeature --- # Function: constructCoreRowModelsFeature() ```ts function constructCoreRowModelsFeature(): TableFeature>; ``` Defined in: [core/row-models/coreRowModelsFeature.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.ts#L27) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`CoreRowModelsFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructCoreRowsFeature.md ================================================ --- id: constructCoreRowsFeature title: constructCoreRowsFeature --- # Function: constructCoreRowsFeature() ```ts function constructCoreRowsFeature(): TableFeature>; ``` Defined in: [core/rows/coreRowsFeature.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.ts#L31) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`CoreRowsFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructCoreTablesFeature.md ================================================ --- id: constructCoreTablesFeature title: constructCoreTablesFeature --- # Function: constructCoreTablesFeature() ```ts function constructCoreTablesFeature(): TableFeature>; ``` Defined in: [core/table/coreTablesFeature.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.ts#L15) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`CoreTablesFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructGlobalFilteringFeature.md ================================================ --- id: constructGlobalFilteringFeature title: constructGlobalFilteringFeature --- # Function: constructGlobalFilteringFeature() ```ts function constructGlobalFilteringFeature(): TableFeature>; ``` Defined in: [features/global-filtering/globalFilteringFeature.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.ts#L34) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`GlobalFilteringFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructHeader.md ================================================ --- id: constructHeader title: constructHeader --- # Function: constructHeader() ```ts function constructHeader( table, column, options): Header; ``` Defined in: [core/headers/constructHeader.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/constructHeader.ts#L25) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### column [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> ### options #### depth `number` #### id? `string` #### index `number` #### isPlaceholder? `boolean` #### placeholderId? `string` ## Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\> ================================================ FILE: docs/reference/functions/constructRow.md ================================================ --- id: constructRow title: constructRow --- # Function: constructRow() ```ts function constructRow( table, id, original, rowIndex, depth, subRows?, parentId?): Row; ``` Defined in: [core/rows/constructRow.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/constructRow.ts#L24) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### id `string` ### original `TData` ### rowIndex `number` ### depth `number` ### subRows? [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] ### parentId? `string` ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/constructRowExpandingFeature.md ================================================ --- id: constructRowExpandingFeature title: constructRowExpandingFeature --- # Function: constructRowExpandingFeature() ```ts function constructRowExpandingFeature(): TableFeature>; ``` Defined in: [features/row-expanding/rowExpandingFeature.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.ts#L46) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`RowExpandingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructRowPaginationFeature.md ================================================ --- id: constructRowPaginationFeature title: constructRowPaginationFeature --- # Function: constructRowPaginationFeature() ```ts function constructRowPaginationFeature(): TableFeature>; ``` Defined in: [features/row-pagination/rowPaginationFeature.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.ts#L42) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`RowPaginationFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructRowPinningFeature.md ================================================ --- id: constructRowPinningFeature title: constructRowPinningFeature --- # Function: constructRowPinningFeature() ```ts function constructRowPinningFeature(): TableFeature>; ``` Defined in: [features/row-pinning/rowPinningFeature.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.ts#L38) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`RowPinningFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructRowSelectionFeature.md ================================================ --- id: constructRowSelectionFeature title: constructRowSelectionFeature --- # Function: constructRowSelectionFeature() ```ts function constructRowSelectionFeature(): TableFeature>; ``` Defined in: [features/row-selection/rowSelectionFeature.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.ts#L50) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`RowSelectionFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructRowSortingFeature.md ================================================ --- id: constructRowSortingFeature title: constructRowSortingFeature --- # Function: constructRowSortingFeature() ```ts function constructRowSortingFeature(): TableFeature>; ``` Defined in: [features/row-sorting/rowSortingFeature.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.ts#L50) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`TableFeature`](../interfaces/TableFeature.md)\<`RowSortingFeatureConstructors`\<`TFeatures`, `TData`\>\> ================================================ FILE: docs/reference/functions/constructTable.md ================================================ --- id: constructTable title: constructTable --- # Function: constructTable() ```ts function constructTable(tableOptions): Table; ``` Defined in: [core/table/constructTable.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L29) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### tableOptions [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ## Returns [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/constructTableHelper.md ================================================ --- id: constructTableHelper title: constructTableHelper --- # Function: constructTableHelper() ```ts function constructTableHelper(tableCreator, tableHelperOptions): TableHelper_Core; ``` Defined in: [helpers/tableHelper.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L44) Internal function to create a table helper that each adapter package will use to create their own table helper ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ## Parameters ### tableCreator \<`TData`\>(`tableOptions`, `selector?`) => [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### tableHelperOptions [`TableHelperOptions`](../type-aliases/TableHelperOptions.md)\<`TFeatures`\> ## Returns [`TableHelper_Core`](../type-aliases/TableHelper_Core.md)\<`TFeatures`\> ================================================ FILE: docs/reference/functions/createColumnHelper.md ================================================ --- id: createColumnHelper title: createColumnHelper --- # Function: createColumnHelper() ```ts function createColumnHelper(): ColumnHelper; ``` Defined in: [helpers/columnHelper.ts:94](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/columnHelper.ts#L94) A helper utility for creating column definitions with slightly better type inference for each individual column. The `TValue` generic is inferred based on the accessor key or function provided. **Note:** From a JavaScript perspective, the functions in these helpers do not do anything. They are only used to help TypeScript infer the correct types for the column definitions. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns [`ColumnHelper`](../type-aliases/ColumnHelper.md)\<`TFeatures`, `TData`\> ## Example ```tsx const helper = createColumnHelper() // _features is the result of `tableFeatures({})` helper const columns = [ helper.display({ id: 'actions', header: 'Actions' }), helper.accessor('firstName', {}), helper.accessor((row) => row.lastName, {} ] ``` ================================================ FILE: docs/reference/functions/createCoreRowModel.md ================================================ --- id: createCoreRowModel title: createCoreRowModel --- # Function: createCoreRowModel() ```ts function createCoreRowModel(): (table) => () => RowModel; ``` Defined in: [core/row-models/createCoreRowModel.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/createCoreRowModel.ts#L10) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Returns ```ts (table): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createExpandedRowModel.md ================================================ --- id: createExpandedRowModel title: createExpandedRowModel --- # Function: createExpandedRowModel() ```ts function createExpandedRowModel(): (table) => () => RowModel; ``` Defined in: [features/row-expanding/createExpandedRowModel.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts#L9) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Returns ```ts (table): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createFacetedMinMaxValues.md ================================================ --- id: createFacetedMinMaxValues title: createFacetedMinMaxValues --- # Function: createFacetedMinMaxValues() ```ts function createFacetedMinMaxValues(): (table, columnId) => () => [number, number] | undefined; ``` Defined in: [features/column-faceting/createFacetedMinMaxValues.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts#L8) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Returns ```ts (table, columnId): () => [number, number] | undefined; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### columnId `string` ### Returns ```ts (): [number, number] | undefined; ``` #### Returns \[`number`, `number`\] \| `undefined` ================================================ FILE: docs/reference/functions/createFacetedRowModel.md ================================================ --- id: createFacetedRowModel title: createFacetedRowModel --- # Function: createFacetedRowModel() ```ts function createFacetedRowModel(): (table, columnId) => () => RowModel; ``` Defined in: [features/column-faceting/createFacetedRowModel.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts#L13) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Returns ```ts (table, columnId): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### columnId `string` ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createFacetedUniqueValues.md ================================================ --- id: createFacetedUniqueValues title: createFacetedUniqueValues --- # Function: createFacetedUniqueValues() ```ts function createFacetedUniqueValues(): (table, columnId) => () => Map; ``` Defined in: [features/column-faceting/createFacetedUniqueValues.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts#L8) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Returns ```ts (table, columnId): () => Map; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### columnId `string` ### Returns ```ts (): Map; ``` #### Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/functions/createFilteredRowModel.md ================================================ --- id: createFilteredRowModel title: createFilteredRowModel --- # Function: createFilteredRowModel() ```ts function createFilteredRowModel(filterFns): (table) => () => RowModel; ``` Defined in: [features/column-filtering/createFilteredRowModel.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts#L22) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Parameters ### filterFns `Record`\\> ## Returns ```ts (table): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createGroupedRowModel.md ================================================ --- id: createGroupedRowModel title: createGroupedRowModel --- # Function: createGroupedRowModel() ```ts function createGroupedRowModel(aggregationFns): (table) => () => RowModel; ``` Defined in: [features/column-grouping/createGroupedRowModel.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts#L22) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Parameters ### aggregationFns `Record`\\> ## Returns ```ts (table): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createPaginatedRowModel.md ================================================ --- id: createPaginatedRowModel title: createPaginatedRowModel --- # Function: createPaginatedRowModel() ```ts function createPaginatedRowModel(): (table) => () => RowModel; ``` Defined in: [features/row-pagination/createPaginatedRowModel.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts#L10) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Returns ```ts (table): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createSortedRowModel.md ================================================ --- id: createSortedRowModel title: createSortedRowModel --- # Function: createSortedRowModel() ```ts function createSortedRowModel(sortFns): (table) => () => RowModel; ``` Defined in: [features/row-sorting/createSortedRowModel.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/createSortedRowModel.ts#L12) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### sortFns `Record`\\> ## Returns ```ts (table): () => RowModel; ``` ### Parameters #### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ### Returns ```ts (): RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/createTableStore.md ================================================ --- id: createTableStore title: createTableStore --- # Function: createTableStore() ```ts function createTableStore(features, initialState): Store>; ``` Defined in: [core/table/constructTable.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L22) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ## Parameters ### features `TFeatures` ### initialState `Partial`\<[`TableState`](../type-aliases/TableState.md)\<`TFeatures`\>\> | `undefined` ## Returns `Store`\<[`TableState`](../type-aliases/TableState.md)\<`TFeatures`\>\> ================================================ FILE: docs/reference/functions/expandRows.md ================================================ --- id: expandRows title: expandRows --- # Function: expandRows() ```ts function expandRows(rowModel): RowModel; ``` Defined in: [features/row-expanding/createExpandedRowModel.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts#L51) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ## Parameters ### rowModel [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/flattenBy.md ================================================ --- id: flattenBy title: flattenBy --- # Function: flattenBy() ```ts function flattenBy(arr, getChildren): TNode[]; ``` Defined in: [utils.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L40) ## Type Parameters ### TNode `TNode` ## Parameters ### arr `TNode`[] ### getChildren (`item`) => `TNode`[] ## Returns `TNode`[] ================================================ FILE: docs/reference/functions/functionalUpdate.md ================================================ --- id: functionalUpdate title: functionalUpdate --- # Function: functionalUpdate() ```ts function functionalUpdate(updater, input): T; ``` Defined in: [utils.ts:6](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L6) ## Type Parameters ### T `T` ## Parameters ### updater [`Updater`](../type-aliases/Updater.md)\<`T`\> ### input `T` ## Returns `T` ================================================ FILE: docs/reference/functions/getDefaultColumnFiltersState.md ================================================ --- id: getDefaultColumnFiltersState title: getDefaultColumnFiltersState --- # Function: getDefaultColumnFiltersState() ```ts function getDefaultColumnFiltersState(): ColumnFiltersState; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L11) ## Returns [`ColumnFiltersState`](../type-aliases/ColumnFiltersState.md) ================================================ FILE: docs/reference/functions/getDefaultColumnOrderState.md ================================================ --- id: getDefaultColumnOrderState title: getDefaultColumnOrderState --- # Function: getDefaultColumnOrderState() ```ts function getDefaultColumnOrderState(): ColumnOrderState; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L10) ## Returns [`ColumnOrderState`](../type-aliases/ColumnOrderState.md) ================================================ FILE: docs/reference/functions/getDefaultColumnPinningState.md ================================================ --- id: getDefaultColumnPinningState title: getDefaultColumnPinningState --- # Function: getDefaultColumnPinningState() ```ts function getDefaultColumnPinningState(): ColumnPinningState; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L22) ## Returns [`ColumnPinningState`](../interfaces/ColumnPinningState.md) ================================================ FILE: docs/reference/functions/getDefaultColumnResizingState.md ================================================ --- id: getDefaultColumnResizingState title: getDefaultColumnResizingState --- # Function: getDefaultColumnResizingState() ```ts function getDefaultColumnResizingState(): columnResizingState; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L15) ## Returns [`columnResizingState`](../interfaces/columnResizingState.md) ================================================ FILE: docs/reference/functions/getDefaultColumnSizingColumnDef.md ================================================ --- id: getDefaultColumnSizingColumnDef title: getDefaultColumnSizingColumnDef --- # Function: getDefaultColumnSizingColumnDef() ```ts function getDefaultColumnSizingColumnDef(): object; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L21) ## Returns `object` ### maxSize ```ts maxSize: number = Number.MAX_SAFE_INTEGER; ``` ### minSize ```ts minSize: number = 20; ``` ### size ```ts size: number = 150; ``` ================================================ FILE: docs/reference/functions/getDefaultColumnSizingState.md ================================================ --- id: getDefaultColumnSizingState title: getDefaultColumnSizingState --- # Function: getDefaultColumnSizingState() ```ts function getDefaultColumnSizingState(): ColumnSizingState; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L17) ## Returns [`ColumnSizingState`](../type-aliases/ColumnSizingState.md) ================================================ FILE: docs/reference/functions/getDefaultColumnVisibilityState.md ================================================ --- id: getDefaultColumnVisibilityState title: getDefaultColumnVisibilityState --- # Function: getDefaultColumnVisibilityState() ```ts function getDefaultColumnVisibilityState(): ColumnVisibilityState; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L10) ## Returns [`ColumnVisibilityState`](../type-aliases/ColumnVisibilityState.md) ================================================ FILE: docs/reference/functions/getDefaultExpandedState.md ================================================ --- id: getDefaultExpandedState title: getDefaultExpandedState --- # Function: getDefaultExpandedState() ```ts function getDefaultExpandedState(): ExpandedState; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L10) ## Returns [`ExpandedState`](../type-aliases/ExpandedState.md) ================================================ FILE: docs/reference/functions/getDefaultGroupingState.md ================================================ --- id: getDefaultGroupingState title: getDefaultGroupingState --- # Function: getDefaultGroupingState() ```ts function getDefaultGroupingState(): GroupingState; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L15) ## Returns [`GroupingState`](../type-aliases/GroupingState.md) ================================================ FILE: docs/reference/functions/getDefaultPaginationState.md ================================================ --- id: getDefaultPaginationState title: getDefaultPaginationState --- # Function: getDefaultPaginationState() ```ts function getDefaultPaginationState(): PaginationState; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L10) ## Returns [`PaginationState`](../interfaces/PaginationState.md) ================================================ FILE: docs/reference/functions/getDefaultRowPinningState.md ================================================ --- id: getDefaultRowPinningState title: getDefaultRowPinningState --- # Function: getDefaultRowPinningState() ```ts function getDefaultRowPinningState(): RowPinningState; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L14) ## Returns [`RowPinningState`](../interfaces/RowPinningState.md) ================================================ FILE: docs/reference/functions/getDefaultRowSelectionState.md ================================================ --- id: getDefaultRowSelectionState title: getDefaultRowSelectionState --- # Function: getDefaultRowSelectionState() ```ts function getDefaultRowSelectionState(): RowSelectionState; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L10) ## Returns [`RowSelectionState`](../type-aliases/RowSelectionState.md) ================================================ FILE: docs/reference/functions/getDefaultSortingState.md ================================================ --- id: getDefaultSortingState title: getDefaultSortingState --- # Function: getDefaultSortingState() ```ts function getDefaultSortingState(): SortingState; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L15) ## Returns [`SortingState`](../type-aliases/SortingState.md) ================================================ FILE: docs/reference/functions/getFunctionNameInfo.md ================================================ --- id: getFunctionNameInfo title: getFunctionNameInfo --- # Function: getFunctionNameInfo() ```ts function getFunctionNameInfo(staticFnName, splitBy): object; ``` Defined in: [utils.ts:280](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L280) Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`. ## Parameters ### staticFnName `string` ### splitBy `"_"` | `"."` ## Returns `object` ### fnKey ```ts fnKey: string; ``` ### fnName ```ts fnName: string; ``` ### parentName ```ts parentName: string; ``` ================================================ FILE: docs/reference/functions/getInitialTableState.md ================================================ --- id: getInitialTableState title: getInitialTableState --- # Function: getInitialTableState() ```ts function getInitialTableState(features, initialState): TableState; ``` Defined in: [core/table/constructTable.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/constructTable.ts#L10) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ## Parameters ### features `TFeatures` ### initialState `Partial`\<[`TableState`](../type-aliases/TableState.md)\<`TFeatures`\>\> | `undefined` ## Returns [`TableState`](../type-aliases/TableState.md)\<`TFeatures`\> ================================================ FILE: docs/reference/functions/getMemoFnMeta.md ================================================ --- id: getMemoFnMeta title: getMemoFnMeta --- # Function: getMemoFnMeta() ```ts function getMemoFnMeta(fn): MemoFnMeta | null; ``` Defined in: [utils.ts:74](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L74) **`Internal`** ## Parameters ### fn `any` ## Returns [`MemoFnMeta`](../type-aliases/MemoFnMeta.md) \| `null` ================================================ FILE: docs/reference/functions/header_getContext.md ================================================ --- id: header_getContext title: header_getContext --- # Function: header\_getContext() ```ts function header_getContext(header): object; ``` Defined in: [core/headers/coreHeadersFeature.utils.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L36) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` ## Parameters ### header [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `object` ### column ```ts column: Column = header.column; ``` ### header ```ts header: Header; ``` ### table ```ts table: Table_Internal = header.column.table; ``` ================================================ FILE: docs/reference/functions/header_getLeafHeaders.md ================================================ --- id: header_getLeafHeaders title: header_getLeafHeaders --- # Function: header\_getLeafHeaders() ```ts function header_getLeafHeaders(header): Header[]; ``` Defined in: [core/headers/coreHeadersFeature.utils.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L17) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` ## Parameters ### header [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\>[] ================================================ FILE: docs/reference/functions/header_getResizeHandler.md ================================================ --- id: header_getResizeHandler title: header_getResizeHandler --- # Function: header\_getResizeHandler() ```ts function header_getResizeHandler(header, _contextDocument?): (event) => void; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L45) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### header [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\> ### \_contextDocument? `Document` ## Returns ```ts (event): void; ``` ### Parameters #### event `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/header_getSize.md ================================================ --- id: header_getSize title: header_getSize --- # Function: header\_getSize() ```ts function header_getSize(header): number; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L98) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### header [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/header_getStart.md ================================================ --- id: header_getStart title: header_getStart --- # Function: header\_getStart() ```ts function header_getStart(header): number; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L118) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### header [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `number` ================================================ FILE: docs/reference/functions/isFunction.md ================================================ --- id: isFunction title: isFunction --- # Function: isFunction() ```ts function isFunction(d): d is T; ``` Defined in: [utils.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L32) ## Type Parameters ### T `T` *extends* `AnyFunction` ## Parameters ### d `any` ## Returns `d is T` ================================================ FILE: docs/reference/functions/isNumberArray.md ================================================ --- id: isNumberArray title: isNumberArray --- # Function: isNumberArray() ```ts function isNumberArray(d): d is number[]; ``` Defined in: [utils.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L36) ## Parameters ### d `any` ## Returns `d is number[]` ================================================ FILE: docs/reference/functions/isRowSelected.md ================================================ --- id: isRowSelected title: isRowSelected --- # Function: isRowSelected() ```ts function isRowSelected(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:418](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L418) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/isSubRowSelected.md ================================================ --- id: isSubRowSelected title: isSubRowSelected --- # Function: isSubRowSelected() ```ts function isSubRowSelected(row): boolean | "some" | "all"; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:425](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L425) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` \| `"some"` \| `"all"` ================================================ FILE: docs/reference/functions/isTouchStartEvent.md ================================================ --- id: isTouchStartEvent title: isTouchStartEvent --- # Function: isTouchStartEvent() ```ts function isTouchStartEvent(e): e is TouchEvent; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:263](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L263) ## Parameters ### e `unknown` ## Returns `e is TouchEvent` ================================================ FILE: docs/reference/functions/makeStateUpdater.md ================================================ --- id: makeStateUpdater title: makeStateUpdater --- # Function: makeStateUpdater() ```ts function makeStateUpdater(key, instance): (updater) => void; ``` Defined in: [utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### K `K` *extends* `string` \| `number` \| `symbol` \| `string` & `object` ## Parameters ### key `K` ### instance [`Table`](../type-aliases/Table.md)\<`TFeatures`, `any`\> ## Returns ```ts (updater): void; ``` ### Parameters #### updater `any` ### Returns `void` ================================================ FILE: docs/reference/functions/memo.md ================================================ --- id: memo title: memo --- # Function: memo() ```ts function memo(__namedParameters): (depArgs?) => TResult; ``` Defined in: [utils.ts:87](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L87) ## Type Parameters ### TDeps `TDeps` *extends* readonly `any`[] ### TDepArgs `TDepArgs` ### TResult `TResult` ## Parameters ### \_\_namedParameters `MemoOptions`\<`TDeps`, `TDepArgs`, `TResult`\> ## Returns ```ts (depArgs?): TResult; ``` ### Parameters #### depArgs? `TDepArgs` ### Returns `TResult` ================================================ FILE: docs/reference/functions/noop.md ================================================ --- id: noop title: noop --- # Function: noop() ```ts function noop(): void; ``` Defined in: [utils.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L12) ## Returns `void` ================================================ FILE: docs/reference/functions/orderColumns.md ================================================ --- id: orderColumns title: orderColumns --- # Function: orderColumns() ```ts function orderColumns(table, leafColumns): Column_Internal[]; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L106) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### leafColumns [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `unknown`\>[] ## Returns [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/passiveEventSupported.md ================================================ --- id: passiveEventSupported title: passiveEventSupported --- # Function: passiveEventSupported() ```ts function passiveEventSupported(): boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:238](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L238) ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getAllCells.md ================================================ --- id: row_getAllCells title: row_getAllCells --- # Function: row\_getAllCells() ```ts function row_getAllCells(row): Cell[]; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L92) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/row_getAllCellsByColumnId.md ================================================ --- id: row_getAllCellsByColumnId title: row_getAllCellsByColumnId --- # Function: row\_getAllCellsByColumnId() ```ts function row_getAllCellsByColumnId(row): Record>; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L101) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `Record`\<`string`, [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>\> ================================================ FILE: docs/reference/functions/row_getAllVisibleCells.md ================================================ --- id: row_getAllVisibleCells title: row_getAllVisibleCells --- # Function: row\_getAllVisibleCells() ```ts function row_getAllVisibleCells(row): Cell[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L68) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/row_getCanExpand.md ================================================ --- id: row_getCanExpand title: row_getCanExpand --- # Function: row\_getCanExpand() ```ts function row_getCanExpand(row): boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:172](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L172) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getCanMultiSelect.md ================================================ --- id: row_getCanMultiSelect title: row_getCanMultiSelect --- # Function: row\_getCanMultiSelect() ```ts function row_getCanMultiSelect(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:319](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L319) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getCanPin.md ================================================ --- id: row_getCanPin title: row_getCanPin --- # Function: row\_getCanPin() ```ts function row_getCanPin(row): boolean; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:119](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L119) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getCanSelect.md ================================================ --- id: row_getCanSelect title: row_getCanSelect --- # Function: row\_getCanSelect() ```ts function row_getCanSelect(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:295](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L295) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getCanSelectSubRows.md ================================================ --- id: row_getCanSelectSubRows title: row_getCanSelectSubRows --- # Function: row\_getCanSelectSubRows() ```ts function row_getCanSelectSubRows(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:307](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L307) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getCenterVisibleCells.md ================================================ --- id: row_getCenterVisibleCells title: row_getCenterVisibleCells --- # Function: row\_getCenterVisibleCells() ```ts function row_getCenterVisibleCells(row): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L118) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/row_getGroupingValue.md ================================================ --- id: row_getGroupingValue title: row_getGroupingValue --- # Function: row\_getGroupingValue() ```ts function row_getGroupingValue(row, columnId): any; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:137](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L137) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row_Core`](../interfaces/Row_Core.md)\<`TFeatures`, `TData`\> & [`UnionToIntersection`](../type-aliases/UnionToIntersection.md)\< \| `"columnFilteringFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnFiltering`](../interfaces/Row_ColumnFiltering.md)\<`TFeatures`, `TData`\> : `never` \| `"columnGroupingFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnGrouping`](../interfaces/Row_ColumnGrouping.md) : `never` \| `"columnPinningFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnPinning`](../interfaces/Row_ColumnPinning.md)\<`TFeatures`, `TData`\> : `never` \| `"columnVisibilityFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnVisibility`](../interfaces/Row_ColumnVisibility.md)\<`TFeatures`, `TData`\> : `never` \| `"rowExpandingFeature"` *extends* keyof `TFeatures` ? [`Row_RowExpanding`](../interfaces/Row_RowExpanding.md) : `never` \| `"rowPinningFeature"` *extends* keyof `TFeatures` ? [`Row_RowPinning`](../interfaces/Row_RowPinning.md) : `never` \| `"rowSelectionFeature"` *extends* keyof `TFeatures` ? [`Row_RowSelection`](../interfaces/Row_RowSelection.md) : `never`\> & [`UnionToIntersection`](../type-aliases/UnionToIntersection.md)\<\{ \[K in string \| number \| symbol\]: TFeatures\[K\] extends TableFeature\ ? "Row" extends keyof FeatureConstructorOptions ? FeatureConstructorOptions\[keyof FeatureConstructorOptions & "Row"\] : never : any \}\[keyof `TFeatures`\]\> & [`Row_Plugins`](../interfaces/Row_Plugins.md)\<`TFeatures`, `TData`\> & `Partial`\<[`Row_ColumnGrouping`](../interfaces/Row_ColumnGrouping.md)\> ### columnId `string` ## Returns `any` ================================================ FILE: docs/reference/functions/row_getIsAllParentsExpanded.md ================================================ --- id: row_getIsAllParentsExpanded title: row_getIsAllParentsExpanded --- # Function: row\_getIsAllParentsExpanded() ```ts function row_getIsAllParentsExpanded(row): boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:182](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L182) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getIsAllSubRowsSelected.md ================================================ --- id: row_getIsAllSubRowsSelected title: row_getIsAllSubRowsSelected --- # Function: row\_getIsAllSubRowsSelected() ```ts function row_getIsAllSubRowsSelected(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:288](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L288) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getIsExpanded.md ================================================ --- id: row_getIsExpanded title: row_getIsExpanded --- # Function: row\_getIsExpanded() ```ts function row_getIsExpanded(row): boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:160](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L160) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getIsGrouped.md ================================================ --- id: row_getIsGrouped title: row_getIsGrouped --- # Function: row\_getIsGrouped() ```ts function row_getIsGrouped(row): boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:130](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L130) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row_Core`](../interfaces/Row_Core.md)\<`TFeatures`, `TData`\> & [`UnionToIntersection`](../type-aliases/UnionToIntersection.md)\< \| `"columnFilteringFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnFiltering`](../interfaces/Row_ColumnFiltering.md)\<`TFeatures`, `TData`\> : `never` \| `"columnGroupingFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnGrouping`](../interfaces/Row_ColumnGrouping.md) : `never` \| `"columnPinningFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnPinning`](../interfaces/Row_ColumnPinning.md)\<`TFeatures`, `TData`\> : `never` \| `"columnVisibilityFeature"` *extends* keyof `TFeatures` ? [`Row_ColumnVisibility`](../interfaces/Row_ColumnVisibility.md)\<`TFeatures`, `TData`\> : `never` \| `"rowExpandingFeature"` *extends* keyof `TFeatures` ? [`Row_RowExpanding`](../interfaces/Row_RowExpanding.md) : `never` \| `"rowPinningFeature"` *extends* keyof `TFeatures` ? [`Row_RowPinning`](../interfaces/Row_RowPinning.md) : `never` \| `"rowSelectionFeature"` *extends* keyof `TFeatures` ? [`Row_RowSelection`](../interfaces/Row_RowSelection.md) : `never`\> & [`UnionToIntersection`](../type-aliases/UnionToIntersection.md)\<\{ \[K in string \| number \| symbol\]: TFeatures\[K\] extends TableFeature\ ? "Row" extends keyof FeatureConstructorOptions ? FeatureConstructorOptions\[keyof FeatureConstructorOptions & "Row"\] : never : any \}\[keyof `TFeatures`\]\> & [`Row_Plugins`](../interfaces/Row_Plugins.md)\<`TFeatures`, `TData`\> & `Partial`\<[`Row_ColumnGrouping`](../interfaces/Row_ColumnGrouping.md)\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getIsPinned.md ================================================ --- id: row_getIsPinned title: row_getIsPinned --- # Function: row\_getIsPinned() ```ts function row_getIsPinned(row): RowPinningPosition; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:130](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L130) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`RowPinningPosition`](../type-aliases/RowPinningPosition.md) ================================================ FILE: docs/reference/functions/row_getIsSelected.md ================================================ --- id: row_getIsSelected title: row_getIsSelected --- # Function: row\_getIsSelected() ```ts function row_getIsSelected(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:274](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L274) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getIsSomeSelected.md ================================================ --- id: row_getIsSomeSelected title: row_getIsSomeSelected --- # Function: row\_getIsSomeSelected() ```ts function row_getIsSomeSelected(row): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:281](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L281) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/row_getLeafRows.md ================================================ --- id: row_getLeafRows title: row_getLeafRows --- # Function: row\_getLeafRows() ```ts function row_getLeafRows(row): Row[]; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L62) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/row_getLeftVisibleCells.md ================================================ --- id: row_getLeftVisibleCells title: row_getLeftVisibleCells --- # Function: row\_getLeftVisibleCells() ```ts function row_getLeftVisibleCells(row): Cell[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:133](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L133) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/row_getParentRow.md ================================================ --- id: row_getParentRow title: row_getParentRow --- # Function: row\_getParentRow() ```ts function row_getParentRow(row): Row | undefined; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L69) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> \| `undefined` ================================================ FILE: docs/reference/functions/row_getParentRows.md ================================================ --- id: row_getParentRows title: row_getParentRows --- # Function: row\_getParentRows() ```ts function row_getParentRows(row): Row[]; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L76) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/row_getPinnedIndex.md ================================================ --- id: row_getPinnedIndex title: row_getPinnedIndex --- # Function: row\_getPinnedIndex() ```ts function row_getPinnedIndex(row): number; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:144](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L144) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `number` ================================================ FILE: docs/reference/functions/row_getRightVisibleCells.md ================================================ --- id: row_getRightVisibleCells title: row_getRightVisibleCells --- # Function: row\_getRightVisibleCells() ```ts function row_getRightVisibleCells(row): any; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:154](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L154) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `any` ================================================ FILE: docs/reference/functions/row_getToggleExpandedHandler.md ================================================ --- id: row_getToggleExpandedHandler title: row_getToggleExpandedHandler --- # Function: row\_getToggleExpandedHandler() ```ts function row_getToggleExpandedHandler(row): () => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:197](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L197) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns ```ts (): void; ``` ### Returns `void` ================================================ FILE: docs/reference/functions/row_getToggleSelectedHandler.md ================================================ --- id: row_getToggleSelectedHandler title: row_getToggleSelectedHandler --- # Function: row\_getToggleSelectedHandler() ```ts function row_getToggleSelectedHandler(row): (e) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:331](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L331) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/row_getUniqueValues.md ================================================ --- id: row_getUniqueValues title: row_getUniqueValues --- # Function: row\_getUniqueValues() ```ts function row_getUniqueValues(row, columnId): unknown; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L28) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### columnId `string` ## Returns `unknown` ================================================ FILE: docs/reference/functions/row_getValue.md ================================================ --- id: row_getValue title: row_getValue --- # Function: row\_getValue() ```ts function row_getValue(row, columnId): unknown; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L9) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### columnId `string` ## Returns `unknown` ================================================ FILE: docs/reference/functions/row_getVisibleCells.md ================================================ --- id: row_getVisibleCells title: row_getVisibleCells --- # Function: row\_getVisibleCells() ```ts function row_getVisibleCells( left, center, right): Cell[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L79) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### left [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ### center [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ### right [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ## Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/row_pin.md ================================================ --- id: row_pin title: row_pin --- # Function: row\_pin() ```ts function row_pin( row, position, includeLeafRows?, includeParentRows?): void; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:160](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L160) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### position [`RowPinningPosition`](../type-aliases/RowPinningPosition.md) ### includeLeafRows? `boolean` ### includeParentRows? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/row_renderValue.md ================================================ --- id: row_renderValue title: row_renderValue --- # Function: row\_renderValue() ```ts function row_renderValue(row, columnId): any; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L55) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### columnId `string` ## Returns `any` ================================================ FILE: docs/reference/functions/row_toggleExpanded.md ================================================ --- id: row_toggleExpanded title: row_toggleExpanded --- # Function: row\_toggleExpanded() ```ts function row_toggleExpanded(row, expanded?): void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:125](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L125) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### expanded? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/row_toggleSelected.md ================================================ --- id: row_toggleSelected title: row_toggleSelected --- # Function: row\_toggleSelected() ```ts function row_toggleSelected( row, value?, opts?): void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:241](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L241) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### value? `boolean` ### opts? #### selectChildren? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/selectRowsFn.md ================================================ --- id: selectRowsFn title: selectRowsFn --- # Function: selectRowsFn() ```ts function selectRowsFn(rowModel): RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:376](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L376) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### rowModel [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/shouldAutoRemoveFilter.md ================================================ --- id: shouldAutoRemoveFilter title: shouldAutoRemoveFilter --- # Function: shouldAutoRemoveFilter() ```ts function shouldAutoRemoveFilter( filterFn?, value?, column?): boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:194](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L194) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* `unknown` = `unknown` ## Parameters ### filterFn? [`FilterFn`](../interfaces/FilterFn.md)\<`TFeatures`, `TData`\> ### value? `any` ### column? [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/tableFeatures.md ================================================ --- id: tableFeatures title: tableFeatures --- # Function: tableFeatures() ```ts function tableFeatures(features): TFeatures; ``` Defined in: [helpers/tableFeatures.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableFeatures.ts#L14) A helper function to help define the features that are to be imported and applied to a table instance. Use this utility to make it easier to have the correct type inference for the features that are being imported. **Note:** It is recommended to use this utility statically outside of a component. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ## Parameters ### features `TFeatures` ## Returns `TFeatures` ## Example ``` import { tableFeatures, columnVisibilityFeature, rowPinningFeature } from '@tanstack/react-table' const _features = tableFeatures({ columnVisibilityFeature, rowPinningFeature }); const table = useTable({ _features, rowModels: {}, columns, data }); ``` ================================================ FILE: docs/reference/functions/tableMemo.md ================================================ --- id: tableMemo title: tableMemo --- # Function: tableMemo() ```ts function tableMemo(__namedParameters): (depArgs?) => TResult; ``` Defined in: [utils.ts:148](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L148) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TDeps `TDeps` *extends* readonly `any`[] ### TDepArgs `TDepArgs` ### TResult `TResult` ## Parameters ### \_\_namedParameters `TableMemoOptions`\<`TFeatures`, `TDeps`, `TDepArgs`, `TResult`\> ## Returns ```ts (depArgs?): TResult; ``` ### Parameters #### depArgs? `TDepArgs` ### Returns `TResult` ================================================ FILE: docs/reference/functions/tableOptions.md ================================================ --- id: tableOptions title: tableOptions --- # Function: tableOptions() ## Call Signature ```ts function tableOptions(options): Omit, "_features" | "columns"> & object; ``` Defined in: [helpers/tableOptions.ts:5](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L5) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"columns"`\> & `object` ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"_features"` \| `"columns"`\> & `object` ## Call Signature ```ts function tableOptions(options): Omit, "_features" | "data"> & object; ``` Defined in: [helpers/tableOptions.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L16) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"data"`\> & `object` ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"_features"` \| `"data"`\> & `object` ## Call Signature ```ts function tableOptions(options): Omit, "_features">; ``` Defined in: [helpers/tableOptions.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L27) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"_features"`\> ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"_features"`\> ## Call Signature ```ts function tableOptions(options): Omit, "_features" | "data" | "columns"> & object; ``` Defined in: [helpers/tableOptions.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L34) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"data"` \| `"columns"`\> & `object` ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"_features"` \| `"data"` \| `"columns"`\> & `object` ## Call Signature ```ts function tableOptions(options): Omit, "data" | "_features">; ``` Defined in: [helpers/tableOptions.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L45) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"data"` \| `"_features"`\> ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"data"` \| `"_features"`\> ## Call Signature ```ts function tableOptions(options): Omit, "columns" | "_features">; ``` Defined in: [helpers/tableOptions.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L52) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"columns"` \| `"_features"`\> ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"columns"` \| `"_features"`\> ## Call Signature ```ts function tableOptions(options): Omit, "data" | "columns" | "_features">; ``` Defined in: [helpers/tableOptions.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L59) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"data"` \| `"columns"` \| `"_features"`\> ### Returns `Omit`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>, `"data"` \| `"columns"` \| `"_features"`\> ## Call Signature ```ts function tableOptions(options): TableOptions; ``` Defined in: [helpers/tableOptions.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableOptions.ts#L69) ### Type Parameters #### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) #### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) = `any` ### Parameters #### options [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ### Returns [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_autoResetExpanded.md ================================================ --- id: table_autoResetExpanded title: table_autoResetExpanded --- # Function: table\_autoResetExpanded() ```ts function table_autoResetExpanded(table): void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_autoResetPageIndex.md ================================================ --- id: table_autoResetPageIndex title: table_autoResetPageIndex --- # Function: table\_autoResetPageIndex() ```ts function table_autoResetPageIndex(table): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L17) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_firstPage.md ================================================ --- id: table_firstPage title: table_firstPage --- # Function: table\_firstPage() ```ts function table_firstPage(table): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:172](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L172) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_getAllColumns.md ================================================ --- id: table_getAllColumns title: table_getAllColumns --- # Function: table\_getAllColumns() ```ts function table_getAllColumns(table): Column[]; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L75) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getAllFlatColumns.md ================================================ --- id: table_getAllFlatColumns title: table_getAllFlatColumns --- # Function: table\_getAllFlatColumns() ```ts function table_getAllFlatColumns(table): Column[]; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L106) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getAllFlatColumnsById.md ================================================ --- id: table_getAllFlatColumnsById title: table_getAllFlatColumnsById --- # Function: table\_getAllFlatColumnsById() ```ts function table_getAllFlatColumnsById(table): Record>; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:115](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L115) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `Record`\<`string`, [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>\> ================================================ FILE: docs/reference/functions/table_getAllLeafColumns.md ================================================ --- id: table_getAllLeafColumns title: table_getAllLeafColumns --- # Function: table\_getAllLeafColumns() ```ts function table_getAllLeafColumns(table): Column[]; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:130](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L130) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getBottomRows.md ================================================ --- id: table_getBottomRows title: table_getBottomRows --- # Function: table\_getBottomRows() ```ts function table_getBottomRows(table): Row[]; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L98) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getCanNextPage.md ================================================ --- id: table_getCanNextPage title: table_getCanNextPage --- # Function: table\_getCanNextPage() ```ts function table_getCanNextPage(table): boolean; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:137](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L137) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getCanPreviousPage.md ================================================ --- id: table_getCanPreviousPage title: table_getCanPreviousPage --- # Function: table\_getCanPreviousPage() ```ts function table_getCanPreviousPage(table): boolean; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:130](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L130) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getCanSomeRowsExpand.md ================================================ --- id: table_getCanSomeRowsExpand title: table_getCanSomeRowsExpand --- # Function: table\_getCanSomeRowsExpand() ```ts function table_getCanSomeRowsExpand(table): boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L55) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getCenterFlatHeaders.md ================================================ --- id: table_getCenterFlatHeaders title: table_getCenterFlatHeaders --- # Function: table\_getCenterFlatHeaders() ```ts function table_getCenterFlatHeaders(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:347](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L347) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getCenterFooterGroups.md ================================================ --- id: table_getCenterFooterGroups title: table_getCenterFooterGroups --- # Function: table\_getCenterFooterGroups() ```ts function table_getCenterFooterGroups(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:301](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L301) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getCenterHeaderGroups.md ================================================ --- id: table_getCenterHeaderGroups title: table_getCenterHeaderGroups --- # Function: table\_getCenterHeaderGroups() ```ts function table_getCenterHeaderGroups(table): HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:253](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L253) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getCenterLeafColumns.md ================================================ --- id: table_getCenterLeafColumns title: table_getCenterLeafColumns --- # Function: table\_getCenterLeafColumns() ```ts function table_getCenterLeafColumns(table): Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:428](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L428) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getCenterLeafHeaders.md ================================================ --- id: table_getCenterLeafHeaders title: table_getCenterLeafHeaders --- # Function: table\_getCenterLeafHeaders() ```ts function table_getCenterLeafHeaders(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:387](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L387) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getCenterRows.md ================================================ --- id: table_getCenterRows title: table_getCenterRows --- # Function: table\_getCenterRows() ```ts function table_getCenterRows(table): Row[]; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:105](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L105) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getCenterTotalSize.md ================================================ --- id: table_getCenterTotalSize title: table_getCenterTotalSize --- # Function: table\_getCenterTotalSize() ```ts function table_getCenterTotalSize(table): any; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:183](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L183) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any` ================================================ FILE: docs/reference/functions/table_getCenterVisibleLeafColumns.md ================================================ --- id: table_getCenterVisibleLeafColumns title: table_getCenterVisibleLeafColumns --- # Function: table\_getCenterVisibleLeafColumns() ```ts function table_getCenterVisibleLeafColumns(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:494](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L494) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getColumn.md ================================================ --- id: table_getColumn title: table_getColumn --- # Function: table\_getColumn() ```ts function table_getColumn(table, columnId): | Column | undefined; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:146](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L146) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### columnId `string` ## Returns \| [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\> \| `undefined` ================================================ FILE: docs/reference/functions/table_getCoreRowModel.md ================================================ --- id: table_getCoreRowModel title: table_getCoreRowModel --- # Function: table\_getCoreRowModel() ```ts function table_getCoreRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L7) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getDefaultColumnDef.md ================================================ --- id: table_getDefaultColumnDef title: table_getDefaultColumnDef --- # Function: table\_getDefaultColumnDef() ```ts function table_getDefaultColumnDef(table): Partial>; ``` Defined in: [core/columns/coreColumnsFeature.utils.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.utils.ts#L46) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `Partial`\<[`ColumnDef`](../type-aliases/ColumnDef.md)\<`TFeatures`, `TData`, `unknown`\>\> ================================================ FILE: docs/reference/functions/table_getExpandedDepth.md ================================================ --- id: table_getExpandedDepth title: table_getExpandedDepth --- # Function: table\_getExpandedDepth() ```ts function table_getExpandedDepth(table): number; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L106) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `number` ================================================ FILE: docs/reference/functions/table_getExpandedRowModel.md ================================================ --- id: table_getExpandedRowModel title: table_getExpandedRowModel --- # Function: table\_getExpandedRowModel() ```ts function table_getExpandedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L96) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getFilteredRowModel.md ================================================ --- id: table_getFilteredRowModel title: table_getFilteredRowModel --- # Function: table\_getFilteredRowModel() ```ts function table_getFilteredRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L27) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getFilteredSelectedRowModel.md ================================================ --- id: table_getFilteredSelectedRowModel title: table_getFilteredSelectedRowModel --- # Function: table\_getFilteredSelectedRowModel() ```ts function table_getFilteredSelectedRowModel(table): RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:111](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L111) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getFlatHeaders.md ================================================ --- id: table_getFlatHeaders title: table_getFlatHeaders --- # Function: table\_getFlatHeaders() ```ts function table_getFlatHeaders(table): Header[]; ``` Defined in: [core/headers/coreHeadersFeature.utils.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L90) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getFooterGroups.md ================================================ --- id: table_getFooterGroups title: table_getFooterGroups --- # Function: table\_getFooterGroups() ```ts function table_getFooterGroups(table): HeaderGroup[]; ``` Defined in: [core/headers/coreHeadersFeature.utils.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L82) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getGlobalAutoFilterFn.md ================================================ --- id: table_getGlobalAutoFilterFn title: table_getGlobalAutoFilterFn --- # Function: table\_getGlobalAutoFilterFn() ```ts function table_getGlobalAutoFilterFn(): FilterFn; ``` Defined in: [features/global-filtering/globalFilteringFeature.utils.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.utils.ts#L23) ## Returns [`FilterFn`](../interfaces/FilterFn.md)\<`any`, `any`\> ================================================ FILE: docs/reference/functions/table_getGlobalFacetedMinMaxValues.md ================================================ --- id: table_getGlobalFacetedMinMaxValues title: table_getGlobalFacetedMinMaxValues --- # Function: table\_getGlobalFacetedMinMaxValues() ```ts function table_getGlobalFacetedMinMaxValues(table): [number, number] | undefined; ``` Defined in: [features/column-faceting/columnFacetingFeature.utils.ts:49](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts#L49) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns \[`number`, `number`\] \| `undefined` ================================================ FILE: docs/reference/functions/table_getGlobalFacetedRowModel.md ================================================ --- id: table_getGlobalFacetedRowModel title: table_getGlobalFacetedRowModel --- # Function: table\_getGlobalFacetedRowModel() ```ts function table_getGlobalFacetedRowModel(table): RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.utils.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts#L59) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getGlobalFacetedUniqueValues.md ================================================ --- id: table_getGlobalFacetedUniqueValues title: table_getGlobalFacetedUniqueValues --- # Function: table\_getGlobalFacetedUniqueValues() ```ts function table_getGlobalFacetedUniqueValues(table): Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.utils.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts#L69) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/functions/table_getGlobalFilterFn.md ================================================ --- id: table_getGlobalFilterFn title: table_getGlobalFilterFn --- # Function: table\_getGlobalFilterFn() ```ts function table_getGlobalFilterFn(table): | FilterFn | undefined; ``` Defined in: [features/global-filtering/globalFilteringFeature.utils.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.utils.ts#L27) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns \| [`FilterFn`](../interfaces/FilterFn.md)\<`TFeatures`, `TData`\> \| `undefined` ================================================ FILE: docs/reference/functions/table_getGroupedRowModel.md ================================================ --- id: table_getGroupedRowModel title: table_getGroupedRowModel --- # Function: table\_getGroupedRowModel() ```ts function table_getGroupedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L50) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getGroupedSelectedRowModel.md ================================================ --- id: table_getGroupedSelectedRowModel title: table_getGroupedSelectedRowModel --- # Function: table\_getGroupedSelectedRowModel() ```ts function table_getGroupedSelectedRowModel(table): RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:128](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L128) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getHeaderGroups.md ================================================ --- id: table_getHeaderGroups title: table_getHeaderGroups --- # Function: table\_getHeaderGroups() ```ts function table_getHeaderGroups(table): HeaderGroup[]; ``` Defined in: [core/headers/coreHeadersFeature.utils.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L48) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getIsAllColumnsVisible.md ================================================ --- id: table_getIsAllColumnsVisible title: table_getIsAllColumnsVisible --- # Function: table\_getIsAllColumnsVisible() ```ts function table_getIsAllColumnsVisible(table): boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:150](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L150) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsAllPageRowsSelected.md ================================================ --- id: table_getIsAllPageRowsSelected title: table_getIsAllPageRowsSelected --- # Function: table\_getIsAllPageRowsSelected() ```ts function table_getIsAllPageRowsSelected(table): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:170](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L170) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsAllRowsExpanded.md ================================================ --- id: table_getIsAllRowsExpanded title: table_getIsAllRowsExpanded --- # Function: table\_getIsAllRowsExpanded() ```ts function table_getIsAllRowsExpanded(table): boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L82) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsAllRowsSelected.md ================================================ --- id: table_getIsAllRowsSelected title: table_getIsAllRowsSelected --- # Function: table\_getIsAllRowsSelected() ```ts function table_getIsAllRowsSelected(table): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L145) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsSomeColumnsPinned.md ================================================ --- id: table_getIsSomeColumnsPinned title: table_getIsSomeColumnsPinned --- # Function: table\_getIsSomeColumnsPinned() ```ts function table_getIsSomeColumnsPinned(table, position?): boolean; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:199](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L199) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsSomeColumnsVisible.md ================================================ --- id: table_getIsSomeColumnsVisible title: table_getIsSomeColumnsVisible --- # Function: table\_getIsSomeColumnsVisible() ```ts function table_getIsSomeColumnsVisible(table): boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:162](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L162) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsSomePageRowsSelected.md ================================================ --- id: table_getIsSomePageRowsSelected title: table_getIsSomePageRowsSelected --- # Function: table\_getIsSomePageRowsSelected() ```ts function table_getIsSomePageRowsSelected(table): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:203](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L203) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsSomeRowsExpanded.md ================================================ --- id: table_getIsSomeRowsExpanded title: table_getIsSomeRowsExpanded --- # Function: table\_getIsSomeRowsExpanded() ```ts function table_getIsSomeRowsExpanded(table): boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:74](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L74) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsSomeRowsPinned.md ================================================ --- id: table_getIsSomeRowsPinned title: table_getIsSomeRowsPinned --- # Function: table\_getIsSomeRowsPinned() ```ts function table_getIsSomeRowsPinned(table, position?): boolean; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L45) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### position? [`RowPinningPosition`](../type-aliases/RowPinningPosition.md) ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getIsSomeRowsSelected.md ================================================ --- id: table_getIsSomeRowsSelected title: table_getIsSomeRowsSelected --- # Function: table\_getIsSomeRowsSelected() ```ts function table_getIsSomeRowsSelected(table): boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:192](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L192) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `boolean` ================================================ FILE: docs/reference/functions/table_getLeafHeaders.md ================================================ --- id: table_getLeafHeaders title: table_getLeafHeaders --- # Function: table\_getLeafHeaders() ```ts function table_getLeafHeaders(table): any[]; ``` Defined in: [core/headers/coreHeadersFeature.utils.ts:102](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts#L102) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getLeftFlatHeaders.md ================================================ --- id: table_getLeftFlatHeaders title: table_getLeftFlatHeaders --- # Function: table\_getLeftFlatHeaders() ```ts function table_getLeftFlatHeaders(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:315](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L315) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getLeftFooterGroups.md ================================================ --- id: table_getLeftFooterGroups title: table_getLeftFooterGroups --- # Function: table\_getLeftFooterGroups() ```ts function table_getLeftFooterGroups(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:277](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L277) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getLeftHeaderGroups.md ================================================ --- id: table_getLeftHeaderGroups title: table_getLeftHeaderGroups --- # Function: table\_getLeftHeaderGroups() ```ts function table_getLeftHeaderGroups(table): HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:213](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L213) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getLeftLeafColumns.md ================================================ --- id: table_getLeftLeafColumns title: table_getLeftLeafColumns --- # Function: table\_getLeftLeafColumns() ```ts function table_getLeftLeafColumns(table): Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:400](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L400) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getLeftLeafHeaders.md ================================================ --- id: table_getLeftLeafHeaders title: table_getLeftLeafHeaders --- # Function: table\_getLeftLeafHeaders() ```ts function table_getLeftLeafHeaders(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:365](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L365) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getLeftTotalSize.md ================================================ --- id: table_getLeftTotalSize title: table_getLeftTotalSize --- # Function: table\_getLeftTotalSize() ```ts function table_getLeftTotalSize(table): any; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:168](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L168) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any` ================================================ FILE: docs/reference/functions/table_getLeftVisibleLeafColumns.md ================================================ --- id: table_getLeftVisibleLeafColumns title: table_getLeftVisibleLeafColumns --- # Function: table\_getLeftVisibleLeafColumns() ```ts function table_getLeftVisibleLeafColumns(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:468](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L468) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getOrderColumnsFn.md ================================================ --- id: table_getOrderColumnsFn title: table_getOrderColumnsFn --- # Function: table\_getOrderColumnsFn() ```ts function table_getOrderColumnsFn(table): (columns) => Column_Internal[]; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L67) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns ```ts (columns): Column_Internal[]; ``` ### Parameters #### columns [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `unknown`\>[] ### Returns [`Column_Internal`](../type-aliases/Column_Internal.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getPageCount.md ================================================ --- id: table_getPageCount title: table_getPageCount --- # Function: table\_getPageCount() ```ts function table_getPageCount(table): number; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:186](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L186) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `number` ================================================ FILE: docs/reference/functions/table_getPageOptions.md ================================================ --- id: table_getPageOptions title: table_getPageOptions --- # Function: table\_getPageOptions() ```ts function table_getPageOptions(table): number[]; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L118) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `number`[] ================================================ FILE: docs/reference/functions/table_getPaginatedRowModel.md ================================================ --- id: table_getPaginatedRowModel title: table_getPaginatedRowModel --- # Function: table\_getPaginatedRowModel() ```ts function table_getPaginatedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:119](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L119) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getPinnedLeafColumns.md ================================================ --- id: table_getPinnedLeafColumns title: table_getPinnedLeafColumns --- # Function: table\_getPinnedLeafColumns() ```ts function table_getPinnedLeafColumns(table, position): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:438](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L438) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getPinnedVisibleLeafColumns.md ================================================ --- id: table_getPinnedVisibleLeafColumns title: table_getPinnedVisibleLeafColumns --- # Function: table\_getPinnedVisibleLeafColumns() ```ts function table_getPinnedVisibleLeafColumns(table, position?): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:507](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L507) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getPreExpandedRowModel.md ================================================ --- id: table_getPreExpandedRowModel title: table_getPreExpandedRowModel --- # Function: table\_getPreExpandedRowModel() ```ts function table_getPreExpandedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L89) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getPreFilteredRowModel.md ================================================ --- id: table_getPreFilteredRowModel title: table_getPreFilteredRowModel --- # Function: table\_getPreFilteredRowModel() ```ts function table_getPreFilteredRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L20) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getPreGroupedRowModel.md ================================================ --- id: table_getPreGroupedRowModel title: table_getPreGroupedRowModel --- # Function: table\_getPreGroupedRowModel() ```ts function table_getPreGroupedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L43) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getPrePaginatedRowModel.md ================================================ --- id: table_getPrePaginatedRowModel title: table_getPrePaginatedRowModel --- # Function: table\_getPrePaginatedRowModel() ```ts function table_getPrePaginatedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L112) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getPreSelectedRowModel.md ================================================ --- id: table_getPreSelectedRowModel title: table_getPreSelectedRowModel --- # Function: table\_getPreSelectedRowModel() ```ts function table_getPreSelectedRowModel(table): RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:87](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L87) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getPreSortedRowModel.md ================================================ --- id: table_getPreSortedRowModel title: table_getPreSortedRowModel --- # Function: table\_getPreSortedRowModel() ```ts function table_getPreSortedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L66) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getRightFlatHeaders.md ================================================ --- id: table_getRightFlatHeaders title: table_getRightFlatHeaders --- # Function: table\_getRightFlatHeaders() ```ts function table_getRightFlatHeaders(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:331](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L331) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getRightFooterGroups.md ================================================ --- id: table_getRightFooterGroups title: table_getRightFooterGroups --- # Function: table\_getRightFooterGroups() ```ts function table_getRightFooterGroups(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:289](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L289) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getRightHeaderGroups.md ================================================ --- id: table_getRightHeaderGroups title: table_getRightHeaderGroups --- # Function: table\_getRightHeaderGroups() ```ts function table_getRightHeaderGroups(table): HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:233](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L233) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getRightLeafColumns.md ================================================ --- id: table_getRightLeafColumns title: table_getRightLeafColumns --- # Function: table\_getRightLeafColumns() ```ts function table_getRightLeafColumns(table): Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:414](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L414) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getRightLeafHeaders.md ================================================ --- id: table_getRightLeafHeaders title: table_getRightLeafHeaders --- # Function: table\_getRightLeafHeaders() ```ts function table_getRightLeafHeaders(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:376](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L376) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getRightTotalSize.md ================================================ --- id: table_getRightTotalSize title: table_getRightTotalSize --- # Function: table\_getRightTotalSize() ```ts function table_getRightTotalSize(table): any; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:198](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L198) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any` ================================================ FILE: docs/reference/functions/table_getRightVisibleLeafColumns.md ================================================ --- id: table_getRightVisibleLeafColumns title: table_getRightVisibleLeafColumns --- # Function: table\_getRightVisibleLeafColumns() ```ts function table_getRightVisibleLeafColumns(table): any[]; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:481](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L481) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `any`[] ================================================ FILE: docs/reference/functions/table_getRow.md ================================================ --- id: table_getRow title: table_getRow --- # Function: table\_getRow() ```ts function table_getRow( table, rowId, searchAll?): Row; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:129](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L129) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### rowId `string` ### searchAll? `boolean` ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getRowCount.md ================================================ --- id: table_getRowCount title: table_getRowCount --- # Function: table\_getRowCount() ```ts function table_getRowCount(table): number; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:199](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L199) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `number` ================================================ FILE: docs/reference/functions/table_getRowId.md ================================================ --- id: table_getRowId title: table_getRowId --- # Function: table\_getRowId() ```ts function table_getRowId( originalRow, table, index, parent?): string; ``` Defined in: [core/rows/coreRowsFeature.utils.ts:114](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L114) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### originalRow `TData` ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### index `number` ### parent? [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ## Returns `string` ================================================ FILE: docs/reference/functions/table_getRowModel.md ================================================ --- id: table_getRowModel title: table_getRowModel --- # Function: table\_getRowModel() ```ts function table_getRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:135](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L135) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getSelectedRowModel.md ================================================ --- id: table_getSelectedRowModel title: table_getSelectedRowModel --- # Function: table\_getSelectedRowModel() ```ts function table_getSelectedRowModel(table): RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:94](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L94) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getSortedRowModel.md ================================================ --- id: table_getSortedRowModel title: table_getSortedRowModel --- # Function: table\_getSortedRowModel() ```ts function table_getSortedRowModel(table): RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.utils.ts:73](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts#L73) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_getToggleAllColumnsVisibilityHandler.md ================================================ --- id: table_getToggleAllColumnsVisibilityHandler title: table_getToggleAllColumnsVisibilityHandler --- # Function: table\_getToggleAllColumnsVisibilityHandler() ```ts function table_getToggleAllColumnsVisibilityHandler(table): (e) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L173) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/table_getToggleAllPageRowsSelectedHandler.md ================================================ --- id: table_getToggleAllPageRowsSelectedHandler title: table_getToggleAllPageRowsSelectedHandler --- # Function: table\_getToggleAllPageRowsSelectedHandler() ```ts function table_getToggleAllPageRowsSelectedHandler(table): (e) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:227](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L227) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/table_getToggleAllRowsExpandedHandler.md ================================================ --- id: table_getToggleAllRowsExpandedHandler title: table_getToggleAllRowsExpandedHandler --- # Function: table\_getToggleAllRowsExpandedHandler() ```ts function table_getToggleAllRowsExpandedHandler(table): (e) => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L64) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/table_getToggleAllRowsSelectedHandler.md ================================================ --- id: table_getToggleAllRowsSelectedHandler title: table_getToggleAllRowsSelectedHandler --- # Function: table\_getToggleAllRowsSelectedHandler() ```ts function table_getToggleAllRowsSelectedHandler(table): (e) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:215](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L215) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns ```ts (e): void; ``` ### Parameters #### e `unknown` ### Returns `void` ================================================ FILE: docs/reference/functions/table_getTopRows.md ================================================ --- id: table_getTopRows title: table_getTopRows --- # Function: table\_getTopRows() ```ts function table_getTopRows(table): Row[]; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:91](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L91) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] ================================================ FILE: docs/reference/functions/table_getTotalSize.md ================================================ --- id: table_getTotalSize title: table_getTotalSize --- # Function: table\_getTotalSize() ```ts function table_getTotalSize(table): number; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:157](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L157) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `number` ================================================ FILE: docs/reference/functions/table_getVisibleFlatColumns.md ================================================ --- id: table_getVisibleFlatColumns title: table_getVisibleFlatColumns --- # Function: table\_getVisibleFlatColumns() ```ts function table_getVisibleFlatColumns(table): Column[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L90) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_getVisibleLeafColumns.md ================================================ --- id: table_getVisibleLeafColumns title: table_getVisibleLeafColumns --- # Function: table\_getVisibleLeafColumns() ```ts function table_getVisibleLeafColumns(table): Column[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L101) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/functions/table_lastPage.md ================================================ --- id: table_lastPage title: table_lastPage --- # Function: table\_lastPage() ```ts function table_lastPage(table): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:179](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L179) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_mergeOptions.md ================================================ --- id: table_mergeOptions title: table_mergeOptions --- # Function: table\_mergeOptions() ```ts function table_mergeOptions(table, newOptions): TableOptions; ``` Defined in: [core/table/coreTablesFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### newOptions [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ## Returns [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/functions/table_nextPage.md ================================================ --- id: table_nextPage title: table_nextPage --- # Function: table\_nextPage() ```ts function table_nextPage(table): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L163) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_previousPage.md ================================================ --- id: table_previousPage title: table_previousPage --- # Function: table\_previousPage() ```ts function table_previousPage(table): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L156) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_reset.md ================================================ --- id: table_reset title: table_reset --- # Function: table\_reset() ```ts function table_reset(table): void; ``` Defined in: [core/table/coreTablesFeature.utils.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L7) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetColumnFilters.md ================================================ --- id: table_resetColumnFilters title: table_resetColumnFilters --- # Function: table\_resetColumnFilters() ```ts function table_resetColumnFilters(table, defaultState?): void; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:184](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L184) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetColumnOrder.md ================================================ --- id: table_resetColumnOrder title: table_resetColumnOrder --- # Function: table\_resetColumnOrder() ```ts function table_resetColumnOrder(table, defaultState?): void; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L57) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetColumnPinning.md ================================================ --- id: table_resetColumnPinning title: table_resetColumnPinning --- # Function: table\_resetColumnPinning() ```ts function table_resetColumnPinning(table, defaultState?): void; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L187) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetColumnSizing.md ================================================ --- id: table_resetColumnSizing title: table_resetColumnSizing --- # Function: table\_resetColumnSizing() ```ts function table_resetColumnSizing(table, defaultState?): void; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:147](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L147) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetColumnVisibility.md ================================================ --- id: table_resetColumnVisibility title: table_resetColumnVisibility --- # Function: table\_resetColumnVisibility() ```ts function table_resetColumnVisibility(table, defaultState?): void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L122) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetExpanded.md ================================================ --- id: table_resetExpanded title: table_resetExpanded --- # Function: table\_resetExpanded() ```ts function table_resetExpanded(table, defaultState?): void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L45) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetGlobalFilter.md ================================================ --- id: table_resetGlobalFilter title: table_resetGlobalFilter --- # Function: table\_resetGlobalFilter() ```ts function table_resetGlobalFilter(table, defaultState?): void; ``` Defined in: [features/global-filtering/globalFilteringFeature.utils.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.utils.ts#L52) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetGrouping.md ================================================ --- id: table_resetGrouping title: table_resetGrouping --- # Function: table\_resetGrouping() ```ts function table_resetGrouping(table, defaultState?): void; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L120) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetHeaderSizeInfo.md ================================================ --- id: table_resetHeaderSizeInfo title: table_resetHeaderSizeInfo --- # Function: table\_resetHeaderSizeInfo() ```ts function table_resetHeaderSizeInfo(table, defaultState?): void; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:226](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L226) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetPageIndex.md ================================================ --- id: table_resetPageIndex title: table_resetPageIndex --- # Function: table\_resetPageIndex() ```ts function table_resetPageIndex(table, defaultState?): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L77) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetPageSize.md ================================================ --- id: table_resetPageSize title: table_resetPageSize --- # Function: table\_resetPageSize() ```ts function table_resetPageSize(table, defaultState?): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L89) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetPagination.md ================================================ --- id: table_resetPagination title: table_resetPagination --- # Function: table\_resetPagination() ```ts function table_resetPagination(table, defaultState?): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L43) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetRowPinning.md ================================================ --- id: table_resetRowPinning title: table_resetRowPinning --- # Function: table\_resetRowPinning() ```ts function table_resetRowPinning(table, defaultState?): void; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L31) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetRowSelection.md ================================================ --- id: table_resetRowSelection title: table_resetRowSelection --- # Function: table\_resetRowSelection() ```ts function table_resetRowSelection(table, defaultState?): void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L24) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_resetSorting.md ================================================ --- id: table_resetSorting title: table_resetSorting --- # Function: table\_resetSorting() ```ts function table_resetSorting(table, defaultState?): void; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L26) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### defaultState? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_setColumnFilters.md ================================================ --- id: table_setColumnFilters title: table_setColumnFilters --- # Function: table\_setColumnFilters() ```ts function table_setColumnFilters(table, updater): void; ``` Defined in: [features/column-filtering/columnFilteringFeature.utils.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts#L156) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnFiltersState`](../type-aliases/ColumnFiltersState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setColumnOrder.md ================================================ --- id: table_setColumnOrder title: table_setColumnOrder --- # Function: table\_setColumnOrder() ```ts function table_setColumnOrder(table, updater): void; ``` Defined in: [features/column-ordering/columnOrderingFeature.utils.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts#L50) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnOrderState`](../type-aliases/ColumnOrderState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setColumnPinning.md ================================================ --- id: table_setColumnPinning title: table_setColumnPinning --- # Function: table\_setColumnPinning() ```ts function table_setColumnPinning(table, updater): void; ``` Defined in: [features/column-pinning/columnPinningFeature.utils.ts:177](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts#L177) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnPinningState`](../interfaces/ColumnPinningState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setColumnResizing.md ================================================ --- id: table_setColumnResizing title: table_setColumnResizing --- # Function: table\_setColumnResizing() ```ts function table_setColumnResizing(table, updater): void; ``` Defined in: [features/column-resizing/columnResizingFeature.utils.ts:216](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts#L216) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`columnResizingState`](../interfaces/columnResizingState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setColumnSizing.md ================================================ --- id: table_setColumnSizing title: table_setColumnSizing --- # Function: table\_setColumnSizing() ```ts function table_setColumnSizing(table, updater): void; ``` Defined in: [features/column-sizing/columnSizingFeature.utils.ts:137](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts#L137) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnSizingState`](../type-aliases/ColumnSizingState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setColumnVisibility.md ================================================ --- id: table_setColumnVisibility title: table_setColumnVisibility --- # Function: table\_setColumnVisibility() ```ts function table_setColumnVisibility(table, updater): void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L112) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnVisibilityState`](../type-aliases/ColumnVisibilityState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setExpanded.md ================================================ --- id: table_setExpanded title: table_setExpanded --- # Function: table\_setExpanded() ```ts function table_setExpanded(table, updater): void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L27) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`ExpandedState`](../type-aliases/ExpandedState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setGlobalFilter.md ================================================ --- id: table_setGlobalFilter title: table_setGlobalFilter --- # Function: table\_setGlobalFilter() ```ts function table_setGlobalFilter(table, updater): void; ``` Defined in: [features/global-filtering/globalFilteringFeature.utils.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.utils.ts#L45) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater `any` ## Returns `void` ================================================ FILE: docs/reference/functions/table_setGrouping.md ================================================ --- id: table_setGrouping title: table_setGrouping --- # Function: table\_setGrouping() ```ts function table_setGrouping(table, updater): void; ``` Defined in: [features/column-grouping/columnGroupingFeature.utils.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts#L113) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`GroupingState`](../type-aliases/GroupingState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setOptions.md ================================================ --- id: table_setOptions title: table_setOptions --- # Function: table\_setOptions() ```ts function table_setOptions(table, updater): void; ``` Defined in: [core/table/coreTablesFeature.utils.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.utils.ts#L31) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setPageIndex.md ================================================ --- id: table_setPageIndex title: table_setPageIndex --- # Function: table\_setPageIndex() ```ts function table_setPageIndex(table, updater): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L55) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<`number`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setPageSize.md ================================================ --- id: table_setPageSize title: table_setPageSize --- # Function: table\_setPageSize() ```ts function table_setPageSize(table, updater): void; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L101) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<`number`\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setPagination.md ================================================ --- id: table_setPagination title: table_setPagination --- # Function: table\_setPagination() ```ts function table_setPagination(table, updater): void | undefined; ``` Defined in: [features/row-pagination/rowPaginationFeature.utils.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts#L30) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`PaginationState`](../interfaces/PaginationState.md)\> ## Returns `void` \| `undefined` ================================================ FILE: docs/reference/functions/table_setRowPinning.md ================================================ --- id: table_setRowPinning title: table_setRowPinning --- # Function: table\_setRowPinning() ```ts function table_setRowPinning(table, updater): void; ``` Defined in: [features/row-pinning/rowPinningFeature.utils.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts#L21) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`RowPinningState`](../interfaces/RowPinningState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setRowSelection.md ================================================ --- id: table_setRowSelection title: table_setRowSelection --- # Function: table\_setRowSelection() ```ts function table_setRowSelection(table, updater): void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L14) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`RowSelectionState`](../type-aliases/RowSelectionState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_setSorting.md ================================================ --- id: table_setSorting title: table_setSorting --- # Function: table\_setSorting() ```ts function table_setSorting(table, updater): void; ``` Defined in: [features/row-sorting/rowSortingFeature.utils.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts#L19) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### updater [`Updater`](../type-aliases/Updater.md)\<[`SortingState`](../type-aliases/SortingState.md)\> ## Returns `void` ================================================ FILE: docs/reference/functions/table_toggleAllColumnsVisible.md ================================================ --- id: table_toggleAllColumnsVisible title: table_toggleAllColumnsVisible --- # Function: table\_toggleAllColumnsVisible() ```ts function table_toggleAllColumnsVisible(table, value?): void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.utils.ts:132](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts#L132) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### value? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_toggleAllPageRowsSelected.md ================================================ --- id: table_toggleAllPageRowsSelected title: table_toggleAllPageRowsSelected --- # Function: table\_toggleAllPageRowsSelected() ```ts function table_toggleAllPageRowsSelected(table, value?): void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L67) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### value? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_toggleAllRowsExpanded.md ================================================ --- id: table_toggleAllRowsExpanded title: table_toggleAllRowsExpanded --- # Function: table\_toggleAllRowsExpanded() ```ts function table_toggleAllRowsExpanded(table, expanded?): void; ``` Defined in: [features/row-expanding/rowExpandingFeature.utils.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts#L34) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### expanded? `boolean` ## Returns `void` ================================================ FILE: docs/reference/functions/table_toggleAllRowsSelected.md ================================================ --- id: table_toggleAllRowsSelected title: table_toggleAllRowsSelected --- # Function: table\_toggleAllRowsSelected() ```ts function table_toggleAllRowsSelected(table, value?): void; ``` Defined in: [features/row-selection/rowSelectionFeature.utils.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts#L36) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Parameters ### table [`Table_Internal`](../type-aliases/Table_Internal.md)\<`TFeatures`, `TData`\> ### value? `boolean` ## Returns `void` ================================================ FILE: docs/reference/index.md ================================================ --- id: "@tanstack/table-core" title: "@tanstack/table-core" --- # @tanstack/table-core ## Namespaces - [filterFn\_arrIncludes](@tanstack/namespaces/filterFn_arrIncludes/index.md) - [filterFn\_arrIncludesAll](@tanstack/namespaces/filterFn_arrIncludesAll/index.md) - [filterFn\_arrIncludesSome](@tanstack/namespaces/filterFn_arrIncludesSome/index.md) - [filterFn\_equals](@tanstack/namespaces/filterFn_equals/index.md) - [filterFn\_equalsString](@tanstack/namespaces/filterFn_equalsString/index.md) - [filterFn\_equalsStringSensitive](@tanstack/namespaces/filterFn_equalsStringSensitive/index.md) - [filterFn\_greaterThan](@tanstack/namespaces/filterFn_greaterThan/index.md) - [filterFn\_greaterThanOrEqualTo](@tanstack/namespaces/filterFn_greaterThanOrEqualTo/index.md) - [filterFn\_includesString](@tanstack/namespaces/filterFn_includesString/index.md) - [filterFn\_includesStringSensitive](@tanstack/namespaces/filterFn_includesStringSensitive/index.md) - [filterFn\_inNumberRange](@tanstack/namespaces/filterFn_inNumberRange/index.md) - [filterFn\_lessThan](@tanstack/namespaces/filterFn_lessThan/index.md) - [filterFn\_lessThanOrEqualTo](@tanstack/namespaces/filterFn_lessThanOrEqualTo/index.md) - [filterFn\_weakEquals](@tanstack/namespaces/filterFn_weakEquals/index.md) ## Interfaces - [AggregationFns](interfaces/AggregationFns.md) - [API](interfaces/API.md) - [CachedRowModel\_Core](interfaces/CachedRowModel_Core.md) - [CachedRowModel\_Expanded](interfaces/CachedRowModel_Expanded.md) - [CachedRowModel\_Faceted](interfaces/CachedRowModel_Faceted.md) - [CachedRowModel\_Filtered](interfaces/CachedRowModel_Filtered.md) - [CachedRowModel\_Grouped](interfaces/CachedRowModel_Grouped.md) - [CachedRowModel\_Paginated](interfaces/CachedRowModel_Paginated.md) - [CachedRowModel\_Plugins](interfaces/CachedRowModel_Plugins.md) - [CachedRowModel\_Sorted](interfaces/CachedRowModel_Sorted.md) - [CachedRowModels\_Plugins](interfaces/CachedRowModels_Plugins.md) - [Cell\_Cell](interfaces/Cell_Cell.md) - [Cell\_ColumnGrouping](interfaces/Cell_ColumnGrouping.md) - [Cell\_Core](interfaces/Cell_Core.md) - [Cell\_CoreProperties](interfaces/Cell_CoreProperties.md) - [Cell\_Plugins](interfaces/Cell_Plugins.md) - [CellContext](interfaces/CellContext.md) - [Column\_Column](interfaces/Column_Column.md) - [Column\_ColumnFaceting](interfaces/Column_ColumnFaceting.md) - [Column\_ColumnFiltering](interfaces/Column_ColumnFiltering.md) - [Column\_ColumnGrouping](interfaces/Column_ColumnGrouping.md) - [Column\_ColumnOrdering](interfaces/Column_ColumnOrdering.md) - [Column\_ColumnPinning](interfaces/Column_ColumnPinning.md) - [Column\_ColumnResizing](interfaces/Column_ColumnResizing.md) - [Column\_ColumnSizing](interfaces/Column_ColumnSizing.md) - [Column\_ColumnVisibility](interfaces/Column_ColumnVisibility.md) - [Column\_Core](interfaces/Column_Core.md) - [Column\_CoreProperties](interfaces/Column_CoreProperties.md) - [Column\_GlobalFiltering](interfaces/Column_GlobalFiltering.md) - [Column\_Plugins](interfaces/Column_Plugins.md) - [Column\_RowSorting](interfaces/Column_RowSorting.md) - [ColumnDef\_ColumnFiltering](interfaces/ColumnDef_ColumnFiltering.md) - [ColumnDef\_ColumnGrouping](interfaces/ColumnDef_ColumnGrouping.md) - [ColumnDef\_ColumnPinning](interfaces/ColumnDef_ColumnPinning.md) - [ColumnDef\_ColumnResizing](interfaces/ColumnDef_ColumnResizing.md) - [ColumnDef\_ColumnSizing](interfaces/ColumnDef_ColumnSizing.md) - [ColumnDef\_ColumnVisibility](interfaces/ColumnDef_ColumnVisibility.md) - [ColumnDef\_GlobalFiltering](interfaces/ColumnDef_GlobalFiltering.md) - [ColumnDef\_Plugins](interfaces/ColumnDef_Plugins.md) - [ColumnDef\_RowSorting](interfaces/ColumnDef_RowSorting.md) - [ColumnDefaultOptions](interfaces/ColumnDefaultOptions.md) - [ColumnFilter](interfaces/ColumnFilter.md) - [ColumnMeta](interfaces/ColumnMeta.md) - [ColumnOrderDefaultOptions](interfaces/ColumnOrderDefaultOptions.md) - [ColumnPinningDefaultOptions](interfaces/ColumnPinningDefaultOptions.md) - [ColumnPinningState](interfaces/ColumnPinningState.md) - [columnResizingState](interfaces/columnResizingState.md) - [ColumnSort](interfaces/ColumnSort.md) - [CoreFeatures](interfaces/CoreFeatures.md) - [CreateRowModel\_Core](interfaces/CreateRowModel_Core.md) - [CreateRowModel\_Expanded](interfaces/CreateRowModel_Expanded.md) - [CreateRowModel\_Faceted](interfaces/CreateRowModel_Faceted.md) - [CreateRowModel\_Filtered](interfaces/CreateRowModel_Filtered.md) - [CreateRowModel\_Grouped](interfaces/CreateRowModel_Grouped.md) - [CreateRowModel\_Paginated](interfaces/CreateRowModel_Paginated.md) - [CreateRowModel\_Plugins](interfaces/CreateRowModel_Plugins.md) - [CreateRowModel\_Sorted](interfaces/CreateRowModel_Sorted.md) - [CreateRowModels\_Plugins](interfaces/CreateRowModels_Plugins.md) - [FilterFn](interfaces/FilterFn.md) - [FilterFns](interfaces/FilterFns.md) - [FilterMeta](interfaces/FilterMeta.md) - [Header\_ColumnResizing](interfaces/Header_ColumnResizing.md) - [Header\_ColumnSizing](interfaces/Header_ColumnSizing.md) - [Header\_Core](interfaces/Header_Core.md) - [Header\_CoreProperties](interfaces/Header_CoreProperties.md) - [Header\_Header](interfaces/Header_Header.md) - [Header\_Plugins](interfaces/Header_Plugins.md) - [HeaderContext](interfaces/HeaderContext.md) - [HeaderGroup\_Core](interfaces/HeaderGroup_Core.md) - [HeaderGroup\_Header](interfaces/HeaderGroup_Header.md) - [HeaderGroup\_Plugins](interfaces/HeaderGroup_Plugins.md) - [IdIdentifier](interfaces/IdIdentifier.md) - [PaginationDefaultOptions](interfaces/PaginationDefaultOptions.md) - [PaginationState](interfaces/PaginationState.md) - [Plugins](interfaces/Plugins.md) - [PrototypeAPI](interfaces/PrototypeAPI.md) - [ResolvedColumnFilter](interfaces/ResolvedColumnFilter.md) - [Row\_ColumnFiltering](interfaces/Row_ColumnFiltering.md) - [Row\_ColumnGrouping](interfaces/Row_ColumnGrouping.md) - [Row\_ColumnPinning](interfaces/Row_ColumnPinning.md) - [Row\_ColumnVisibility](interfaces/Row_ColumnVisibility.md) - [Row\_Core](interfaces/Row_Core.md) - [Row\_CoreProperties](interfaces/Row_CoreProperties.md) - [Row\_Plugins](interfaces/Row_Plugins.md) - [Row\_Row](interfaces/Row_Row.md) - [Row\_RowExpanding](interfaces/Row_RowExpanding.md) - [Row\_RowPinning](interfaces/Row_RowPinning.md) - [Row\_RowSelection](interfaces/Row_RowSelection.md) - [RowModel](interfaces/RowModel.md) - [RowModelFns\_ColumnFiltering](interfaces/RowModelFns_ColumnFiltering.md) - [RowModelFns\_ColumnGrouping](interfaces/RowModelFns_ColumnGrouping.md) - [RowModelFns\_Core](interfaces/RowModelFns_Core.md) - [RowModelFns\_Plugins](interfaces/RowModelFns_Plugins.md) - [RowModelFns\_RowSorting](interfaces/RowModelFns_RowSorting.md) - [RowPinningDefaultOptions](interfaces/RowPinningDefaultOptions.md) - [RowPinningState](interfaces/RowPinningState.md) - [SortFn](interfaces/SortFn.md) - [SortFns](interfaces/SortFns.md) - [StockFeatures](interfaces/StockFeatures.md) - [StringHeaderIdentifier](interfaces/StringHeaderIdentifier.md) - [Table\_ColumnFaceting](interfaces/Table_ColumnFaceting.md) - [Table\_ColumnFiltering](interfaces/Table_ColumnFiltering.md) - [Table\_ColumnGrouping](interfaces/Table_ColumnGrouping.md) - [Table\_ColumnOrdering](interfaces/Table_ColumnOrdering.md) - [Table\_ColumnPinning](interfaces/Table_ColumnPinning.md) - [Table\_ColumnResizing](interfaces/Table_ColumnResizing.md) - [Table\_Columns](interfaces/Table_Columns.md) - [Table\_ColumnSizing](interfaces/Table_ColumnSizing.md) - [Table\_ColumnVisibility](interfaces/Table_ColumnVisibility.md) - [Table\_CoreProperties](interfaces/Table_CoreProperties.md) - [Table\_GlobalFiltering](interfaces/Table_GlobalFiltering.md) - [Table\_Headers](interfaces/Table_Headers.md) - [Table\_Plugins](interfaces/Table_Plugins.md) - [Table\_RowExpanding](interfaces/Table_RowExpanding.md) - [Table\_RowModels\_Core](interfaces/Table_RowModels_Core.md) - [Table\_RowModels\_Expanded](interfaces/Table_RowModels_Expanded.md) - [Table\_RowModels\_Faceted](interfaces/Table_RowModels_Faceted.md) - [Table\_RowModels\_Filtered](interfaces/Table_RowModels_Filtered.md) - [Table\_RowModels\_Grouped](interfaces/Table_RowModels_Grouped.md) - [Table\_RowModels\_Paginated](interfaces/Table_RowModels_Paginated.md) - [Table\_RowModels\_Sorted](interfaces/Table_RowModels_Sorted.md) - [Table\_RowPagination](interfaces/Table_RowPagination.md) - [Table\_RowPinning](interfaces/Table_RowPinning.md) - [Table\_Rows](interfaces/Table_Rows.md) - [Table\_RowSelection](interfaces/Table_RowSelection.md) - [Table\_RowSorting](interfaces/Table_RowSorting.md) - [Table\_Table](interfaces/Table_Table.md) - [TableFeature](interfaces/TableFeature.md) - [TableFeatures](interfaces/TableFeatures.md) - [TableMeta](interfaces/TableMeta.md) - [TableOptions\_Cell](interfaces/TableOptions_Cell.md) - [TableOptions\_ColumnFiltering](interfaces/TableOptions_ColumnFiltering.md) - [TableOptions\_ColumnGrouping](interfaces/TableOptions_ColumnGrouping.md) - [TableOptions\_ColumnOrdering](interfaces/TableOptions_ColumnOrdering.md) - [TableOptions\_ColumnPinning](interfaces/TableOptions_ColumnPinning.md) - [TableOptions\_ColumnResizing](interfaces/TableOptions_ColumnResizing.md) - [TableOptions\_Columns](interfaces/TableOptions_Columns.md) - [TableOptions\_ColumnSizing](interfaces/TableOptions_ColumnSizing.md) - [TableOptions\_ColumnVisibility](interfaces/TableOptions_ColumnVisibility.md) - [TableOptions\_Core](interfaces/TableOptions_Core.md) - [TableOptions\_GlobalFiltering](interfaces/TableOptions_GlobalFiltering.md) - [TableOptions\_Plugins](interfaces/TableOptions_Plugins.md) - [TableOptions\_RowExpanding](interfaces/TableOptions_RowExpanding.md) - [TableOptions\_RowPagination](interfaces/TableOptions_RowPagination.md) - [TableOptions\_RowPinning](interfaces/TableOptions_RowPinning.md) - [TableOptions\_Rows](interfaces/TableOptions_Rows.md) - [TableOptions\_RowSelection](interfaces/TableOptions_RowSelection.md) - [TableOptions\_RowSorting](interfaces/TableOptions_RowSorting.md) - [TableOptions\_Table](interfaces/TableOptions_Table.md) - [TableState\_ColumnFiltering](interfaces/TableState_ColumnFiltering.md) - [TableState\_ColumnGrouping](interfaces/TableState_ColumnGrouping.md) - [TableState\_ColumnOrdering](interfaces/TableState_ColumnOrdering.md) - [TableState\_ColumnPinning](interfaces/TableState_ColumnPinning.md) - [TableState\_ColumnResizing](interfaces/TableState_ColumnResizing.md) - [TableState\_ColumnSizing](interfaces/TableState_ColumnSizing.md) - [TableState\_ColumnVisibility](interfaces/TableState_ColumnVisibility.md) - [TableState\_GlobalFiltering](interfaces/TableState_GlobalFiltering.md) - [TableState\_Plugins](interfaces/TableState_Plugins.md) - [TableState\_RowExpanding](interfaces/TableState_RowExpanding.md) - [TableState\_RowPagination](interfaces/TableState_RowPagination.md) - [TableState\_RowPinning](interfaces/TableState_RowPinning.md) - [TableState\_RowSelection](interfaces/TableState_RowSelection.md) - [TableState\_RowSorting](interfaces/TableState_RowSorting.md) ## Type Aliases - [AccessorColumnDef](type-aliases/AccessorColumnDef.md) - [AccessorFn](type-aliases/AccessorFn.md) - [AccessorFnColumnDef](type-aliases/AccessorFnColumnDef.md) - [AccessorFnColumnDefBase](type-aliases/AccessorFnColumnDefBase.md) - [AccessorKeyColumnDef](type-aliases/AccessorKeyColumnDef.md) - [AccessorKeyColumnDefBase](type-aliases/AccessorKeyColumnDefBase.md) - [AggregationFn](type-aliases/AggregationFn.md) - [AggregationFnOption](type-aliases/AggregationFnOption.md) - [APIObject](type-aliases/APIObject.md) - [AssignCellPrototype](type-aliases/AssignCellPrototype.md) - [AssignColumnPrototype](type-aliases/AssignColumnPrototype.md) - [AssignHeaderPrototype](type-aliases/AssignHeaderPrototype.md) - [AssignRowPrototype](type-aliases/AssignRowPrototype.md) - [BuiltInAggregationFn](type-aliases/BuiltInAggregationFn.md) - [BuiltInFilterFn](type-aliases/BuiltInFilterFn.md) - [BuiltInSortFn](type-aliases/BuiltInSortFn.md) - [CachedRowModel\_All](type-aliases/CachedRowModel_All.md) - [CachedRowModels](type-aliases/CachedRowModels.md) - [Cell](type-aliases/Cell.md) - [CellData](type-aliases/CellData.md) - [Column](type-aliases/Column.md) - [Column\_Internal](type-aliases/Column_Internal.md) - [ColumnDef](type-aliases/ColumnDef.md) - [ColumnDefBase](type-aliases/ColumnDefBase.md) - [ColumnDefBase\_All](type-aliases/ColumnDefBase_All.md) - [ColumnDefResolved](type-aliases/ColumnDefResolved.md) - [ColumnDefTemplate](type-aliases/ColumnDefTemplate.md) - [ColumnFilterAutoRemoveTestFn](type-aliases/ColumnFilterAutoRemoveTestFn.md) - [ColumnFiltersState](type-aliases/ColumnFiltersState.md) - [ColumnHelper](type-aliases/ColumnHelper.md) - [ColumnOrderState](type-aliases/ColumnOrderState.md) - [ColumnPinningPosition](type-aliases/ColumnPinningPosition.md) - [ColumnResizeDirection](type-aliases/ColumnResizeDirection.md) - [ColumnResizeMode](type-aliases/ColumnResizeMode.md) - [ColumnResizingDefaultOptions](type-aliases/ColumnResizingDefaultOptions.md) - [ColumnSizingDefaultOptions](type-aliases/ColumnSizingDefaultOptions.md) - [ColumnSizingState](type-aliases/ColumnSizingState.md) - [ColumnVisibilityState](type-aliases/ColumnVisibilityState.md) - [ConstructTableAPIs](type-aliases/ConstructTableAPIs.md) - [CreateRowModels](type-aliases/CreateRowModels.md) - [CreateRowModels\_All](type-aliases/CreateRowModels_All.md) - [CustomAggregationFns](type-aliases/CustomAggregationFns.md) - [CustomFilterFns](type-aliases/CustomFilterFns.md) - [CustomSortFns](type-aliases/CustomSortFns.md) - [DebugOptions](type-aliases/DebugOptions.md) - [DeepKeys](type-aliases/DeepKeys.md) - [DeepValue](type-aliases/DeepValue.md) - [DisplayColumnDef](type-aliases/DisplayColumnDef.md) - [ExpandedState](type-aliases/ExpandedState.md) - [ExpandedStateList](type-aliases/ExpandedStateList.md) - [ExtractFeatureTypes](type-aliases/ExtractFeatureTypes.md) - [FilterFnOption](type-aliases/FilterFnOption.md) - [GetDefaultColumnDef](type-aliases/GetDefaultColumnDef.md) - [GetDefaultStateSelector](type-aliases/GetDefaultStateSelector.md) - [GetDefaultTableOptions](type-aliases/GetDefaultTableOptions.md) - [GetInitialState](type-aliases/GetInitialState.md) - [Getter](type-aliases/Getter.md) - [GroupColumnDef](type-aliases/GroupColumnDef.md) - [GroupingColumnMode](type-aliases/GroupingColumnMode.md) - [GroupingState](type-aliases/GroupingState.md) - [Header](type-aliases/Header.md) - [HeaderGroup](type-aliases/HeaderGroup.md) - [IdentifiedColumnDef](type-aliases/IdentifiedColumnDef.md) - [InitRowInstanceData](type-aliases/InitRowInstanceData.md) - [MemoFnMeta](type-aliases/MemoFnMeta.md) - [NoInfer](type-aliases/NoInfer.md) - [OnChangeFn](type-aliases/OnChangeFn.md) - [PartialKeys](type-aliases/PartialKeys.md) - [Prettify](type-aliases/Prettify.md) - [PrototypeAPIObject](type-aliases/PrototypeAPIObject.md) - [RequiredKeys](type-aliases/RequiredKeys.md) - [Row](type-aliases/Row.md) - [RowData](type-aliases/RowData.md) - [RowModelFns](type-aliases/RowModelFns.md) - [RowModelFns\_All](type-aliases/RowModelFns_All.md) - [RowPinningPosition](type-aliases/RowPinningPosition.md) - [RowSelectionState](type-aliases/RowSelectionState.md) - [SortDirection](type-aliases/SortDirection.md) - [SortFnOption](type-aliases/SortFnOption.md) - [SortingState](type-aliases/SortingState.md) - [StringOrTemplateHeader](type-aliases/StringOrTemplateHeader.md) - [Table](type-aliases/Table.md) - [Table\_Core](type-aliases/Table_Core.md) - [Table\_Internal](type-aliases/Table_Internal.md) - [Table\_RowModels](type-aliases/Table_RowModels.md) - [TableHelper\_Core](type-aliases/TableHelper_Core.md) - [TableHelperOptions](type-aliases/TableHelperOptions.md) - [TableOptions](type-aliases/TableOptions.md) - [TableOptions\_All](type-aliases/TableOptions_All.md) - [TableState](type-aliases/TableState.md) - [TableState\_All](type-aliases/TableState_All.md) - [TransformFilterValueFn](type-aliases/TransformFilterValueFn.md) - [UnionToIntersection](type-aliases/UnionToIntersection.md) - [Updater](type-aliases/Updater.md) - [VisibilityDefaultOptions](type-aliases/VisibilityDefaultOptions.md) ## Variables - [$internalMemoFnMeta](variables/$internalMemoFnMeta.md) - [aggregationFn\_count](variables/aggregationFn_count.md) - [aggregationFn\_extent](variables/aggregationFn_extent.md) - [aggregationFn\_max](variables/aggregationFn_max.md) - [aggregationFn\_mean](variables/aggregationFn_mean.md) - [aggregationFn\_median](variables/aggregationFn_median.md) - [aggregationFn\_min](variables/aggregationFn_min.md) - [aggregationFn\_sum](variables/aggregationFn_sum.md) - [aggregationFn\_unique](variables/aggregationFn_unique.md) - [aggregationFn\_uniqueCount](variables/aggregationFn_uniqueCount.md) - [aggregationFns](variables/aggregationFns.md) - [columnFacetingFeature](variables/columnFacetingFeature.md) - [columnFilteringFeature](variables/columnFilteringFeature.md) - [columnGroupingFeature](variables/columnGroupingFeature.md) - [columnOrderingFeature](variables/columnOrderingFeature.md) - [columnPinningFeature](variables/columnPinningFeature.md) - [columnResizingFeature](variables/columnResizingFeature.md) - [columnSizingFeature](variables/columnSizingFeature.md) - [columnVisibilityFeature](variables/columnVisibilityFeature.md) - [coreCellsFeature](variables/coreCellsFeature.md) - [coreColumnsFeature](variables/coreColumnsFeature.md) - [coreFeatures](variables/coreFeatures.md) - [coreHeadersFeature](variables/coreHeadersFeature.md) - [coreRowModelsFeature](variables/coreRowModelsFeature.md) - [coreRowsFeature](variables/coreRowsFeature.md) - [coreTablesFeature](variables/coreTablesFeature.md) - [filterFn\_arrHas](variables/filterFn_arrHas.md) - [filterFn\_arrIncludes](variables/filterFn_arrIncludes.md) - [filterFn\_arrIncludesAll](variables/filterFn_arrIncludesAll.md) - [filterFn\_arrIncludesSome](variables/filterFn_arrIncludesSome.md) - [filterFn\_equals](variables/filterFn_equals.md) - [filterFn\_equalsString](variables/filterFn_equalsString.md) - [filterFn\_equalsStringSensitive](variables/filterFn_equalsStringSensitive.md) - [filterFn\_greaterThan](variables/filterFn_greaterThan.md) - [filterFn\_greaterThanOrEqualTo](variables/filterFn_greaterThanOrEqualTo.md) - [filterFn\_includesString](variables/filterFn_includesString.md) - [filterFn\_includesStringSensitive](variables/filterFn_includesStringSensitive.md) - [filterFn\_inNumberRange](variables/filterFn_inNumberRange.md) - [filterFn\_lessThan](variables/filterFn_lessThan.md) - [filterFn\_lessThanOrEqualTo](variables/filterFn_lessThanOrEqualTo.md) - [filterFn\_weakEquals](variables/filterFn_weakEquals.md) - [filterFns](variables/filterFns.md) - [globalFilteringFeature](variables/globalFilteringFeature.md) - [reSplitAlphaNumeric](variables/reSplitAlphaNumeric.md) - [rowExpandingFeature](variables/rowExpandingFeature.md) - [rowPaginationFeature](variables/rowPaginationFeature.md) - [rowPinningFeature](variables/rowPinningFeature.md) - [rowSelectionFeature](variables/rowSelectionFeature.md) - [rowSortingFeature](variables/rowSortingFeature.md) - [sortFn\_alphanumeric](variables/sortFn_alphanumeric.md) - [sortFn\_alphanumericCaseSensitive](variables/sortFn_alphanumericCaseSensitive.md) - [sortFn\_basic](variables/sortFn_basic.md) - [sortFn\_datetime](variables/sortFn_datetime.md) - [sortFn\_text](variables/sortFn_text.md) - [sortFn\_textCaseSensitive](variables/sortFn_textCaseSensitive.md) - [sortFns](variables/sortFns.md) - [stockFeatures](variables/stockFeatures.md) ## Functions - [assignPrototypeAPIs](functions/assignPrototypeAPIs.md) - [assignTableAPIs](functions/assignTableAPIs.md) - [buildHeaderGroups](functions/buildHeaderGroups.md) - [callMemoOrStaticFn](functions/callMemoOrStaticFn.md) - [cell\_getContext](functions/cell_getContext.md) - [cell\_getIsAggregated](functions/cell_getIsAggregated.md) - [cell\_getIsGrouped](functions/cell_getIsGrouped.md) - [cell\_getIsPlaceholder](functions/cell_getIsPlaceholder.md) - [cell\_getValue](functions/cell_getValue.md) - [cell\_renderValue](functions/cell_renderValue.md) - [column\_clearSorting](functions/column_clearSorting.md) - [column\_getAfter](functions/column_getAfter.md) - [column\_getAggregationFn](functions/column_getAggregationFn.md) - [column\_getAutoAggregationFn](functions/column_getAutoAggregationFn.md) - [column\_getAutoFilterFn](functions/column_getAutoFilterFn.md) - [column\_getAutoSortDir](functions/column_getAutoSortDir.md) - [column\_getAutoSortFn](functions/column_getAutoSortFn.md) - [column\_getCanFilter](functions/column_getCanFilter.md) - [column\_getCanGlobalFilter](functions/column_getCanGlobalFilter.md) - [column\_getCanGroup](functions/column_getCanGroup.md) - [column\_getCanHide](functions/column_getCanHide.md) - [column\_getCanMultiSort](functions/column_getCanMultiSort.md) - [column\_getCanPin](functions/column_getCanPin.md) - [column\_getCanResize](functions/column_getCanResize.md) - [column\_getCanSort](functions/column_getCanSort.md) - [column\_getFacetedMinMaxValues](functions/column_getFacetedMinMaxValues.md) - [column\_getFacetedRowModel](functions/column_getFacetedRowModel.md) - [column\_getFacetedUniqueValues](functions/column_getFacetedUniqueValues.md) - [column\_getFilterFn](functions/column_getFilterFn.md) - [column\_getFilterIndex](functions/column_getFilterIndex.md) - [column\_getFilterValue](functions/column_getFilterValue.md) - [column\_getFirstSortDir](functions/column_getFirstSortDir.md) - [column\_getFlatColumns](functions/column_getFlatColumns.md) - [column\_getGroupedIndex](functions/column_getGroupedIndex.md) - [column\_getIndex](functions/column_getIndex.md) - [column\_getIsFiltered](functions/column_getIsFiltered.md) - [column\_getIsFirstColumn](functions/column_getIsFirstColumn.md) - [column\_getIsGrouped](functions/column_getIsGrouped.md) - [column\_getIsLastColumn](functions/column_getIsLastColumn.md) - [column\_getIsPinned](functions/column_getIsPinned.md) - [column\_getIsResizing](functions/column_getIsResizing.md) - [column\_getIsSorted](functions/column_getIsSorted.md) - [column\_getIsVisible](functions/column_getIsVisible.md) - [column\_getLeafColumns](functions/column_getLeafColumns.md) - [column\_getNextSortingOrder](functions/column_getNextSortingOrder.md) - [column\_getPinnedIndex](functions/column_getPinnedIndex.md) - [column\_getSize](functions/column_getSize.md) - [column\_getSortFn](functions/column_getSortFn.md) - [column\_getSortIndex](functions/column_getSortIndex.md) - [column\_getStart](functions/column_getStart.md) - [column\_getToggleGroupingHandler](functions/column_getToggleGroupingHandler.md) - [column\_getToggleSortingHandler](functions/column_getToggleSortingHandler.md) - [column\_getToggleVisibilityHandler](functions/column_getToggleVisibilityHandler.md) - [column\_pin](functions/column_pin.md) - [column\_resetSize](functions/column_resetSize.md) - [column\_setFilterValue](functions/column_setFilterValue.md) - [column\_toggleGrouping](functions/column_toggleGrouping.md) - [column\_toggleSorting](functions/column_toggleSorting.md) - [column\_toggleVisibility](functions/column_toggleVisibility.md) - [constructCell](functions/constructCell.md) - [constructColumn](functions/constructColumn.md) - [constructColumnFacetingFeature](functions/constructColumnFacetingFeature.md) - [constructColumnFilteringFeature](functions/constructColumnFilteringFeature.md) - [constructColumnGroupingFeature](functions/constructColumnGroupingFeature.md) - [constructColumnOrderingFeature](functions/constructColumnOrderingFeature.md) - [constructColumnPinningFeature](functions/constructColumnPinningFeature.md) - [constructColumnResizingFeature](functions/constructColumnResizingFeature.md) - [constructColumnSizingFeature](functions/constructColumnSizingFeature.md) - [constructColumnVisibilityFeature](functions/constructColumnVisibilityFeature.md) - [constructCoreCellsFeature](functions/constructCoreCellsFeature.md) - [constructCoreColumnsFeature](functions/constructCoreColumnsFeature.md) - [constructCoreHeadersFeature](functions/constructCoreHeadersFeature.md) - [constructCoreRowModelsFeature](functions/constructCoreRowModelsFeature.md) - [constructCoreRowsFeature](functions/constructCoreRowsFeature.md) - [constructCoreTablesFeature](functions/constructCoreTablesFeature.md) - [constructGlobalFilteringFeature](functions/constructGlobalFilteringFeature.md) - [constructHeader](functions/constructHeader.md) - [constructRow](functions/constructRow.md) - [constructRowExpandingFeature](functions/constructRowExpandingFeature.md) - [constructRowPaginationFeature](functions/constructRowPaginationFeature.md) - [constructRowPinningFeature](functions/constructRowPinningFeature.md) - [constructRowSelectionFeature](functions/constructRowSelectionFeature.md) - [constructRowSortingFeature](functions/constructRowSortingFeature.md) - [constructTable](functions/constructTable.md) - [constructTableHelper](functions/constructTableHelper.md) - [createColumnHelper](functions/createColumnHelper.md) - [createCoreRowModel](functions/createCoreRowModel.md) - [createExpandedRowModel](functions/createExpandedRowModel.md) - [createFacetedMinMaxValues](functions/createFacetedMinMaxValues.md) - [createFacetedRowModel](functions/createFacetedRowModel.md) - [createFacetedUniqueValues](functions/createFacetedUniqueValues.md) - [createFilteredRowModel](functions/createFilteredRowModel.md) - [createGroupedRowModel](functions/createGroupedRowModel.md) - [createPaginatedRowModel](functions/createPaginatedRowModel.md) - [createSortedRowModel](functions/createSortedRowModel.md) - [createTableStore](functions/createTableStore.md) - [expandRows](functions/expandRows.md) - [flattenBy](functions/flattenBy.md) - [functionalUpdate](functions/functionalUpdate.md) - [getDefaultColumnFiltersState](functions/getDefaultColumnFiltersState.md) - [getDefaultColumnOrderState](functions/getDefaultColumnOrderState.md) - [getDefaultColumnPinningState](functions/getDefaultColumnPinningState.md) - [getDefaultColumnResizingState](functions/getDefaultColumnResizingState.md) - [getDefaultColumnSizingColumnDef](functions/getDefaultColumnSizingColumnDef.md) - [getDefaultColumnSizingState](functions/getDefaultColumnSizingState.md) - [getDefaultColumnVisibilityState](functions/getDefaultColumnVisibilityState.md) - [getDefaultExpandedState](functions/getDefaultExpandedState.md) - [getDefaultGroupingState](functions/getDefaultGroupingState.md) - [getDefaultPaginationState](functions/getDefaultPaginationState.md) - [getDefaultRowPinningState](functions/getDefaultRowPinningState.md) - [getDefaultRowSelectionState](functions/getDefaultRowSelectionState.md) - [getDefaultSortingState](functions/getDefaultSortingState.md) - [getFunctionNameInfo](functions/getFunctionNameInfo.md) - [getInitialTableState](functions/getInitialTableState.md) - [getMemoFnMeta](functions/getMemoFnMeta.md) - [header\_getContext](functions/header_getContext.md) - [header\_getLeafHeaders](functions/header_getLeafHeaders.md) - [header\_getResizeHandler](functions/header_getResizeHandler.md) - [header\_getSize](functions/header_getSize.md) - [header\_getStart](functions/header_getStart.md) - [isFunction](functions/isFunction.md) - [isNumberArray](functions/isNumberArray.md) - [isRowSelected](functions/isRowSelected.md) - [isSubRowSelected](functions/isSubRowSelected.md) - [isTouchStartEvent](functions/isTouchStartEvent.md) - [makeStateUpdater](functions/makeStateUpdater.md) - [memo](functions/memo.md) - [noop](functions/noop.md) - [orderColumns](functions/orderColumns.md) - [passiveEventSupported](functions/passiveEventSupported.md) - [row\_getAllCells](functions/row_getAllCells.md) - [row\_getAllCellsByColumnId](functions/row_getAllCellsByColumnId.md) - [row\_getAllVisibleCells](functions/row_getAllVisibleCells.md) - [row\_getCanExpand](functions/row_getCanExpand.md) - [row\_getCanMultiSelect](functions/row_getCanMultiSelect.md) - [row\_getCanPin](functions/row_getCanPin.md) - [row\_getCanSelect](functions/row_getCanSelect.md) - [row\_getCanSelectSubRows](functions/row_getCanSelectSubRows.md) - [row\_getCenterVisibleCells](functions/row_getCenterVisibleCells.md) - [row\_getGroupingValue](functions/row_getGroupingValue.md) - [row\_getIsAllParentsExpanded](functions/row_getIsAllParentsExpanded.md) - [row\_getIsAllSubRowsSelected](functions/row_getIsAllSubRowsSelected.md) - [row\_getIsExpanded](functions/row_getIsExpanded.md) - [row\_getIsGrouped](functions/row_getIsGrouped.md) - [row\_getIsPinned](functions/row_getIsPinned.md) - [row\_getIsSelected](functions/row_getIsSelected.md) - [row\_getIsSomeSelected](functions/row_getIsSomeSelected.md) - [row\_getLeafRows](functions/row_getLeafRows.md) - [row\_getLeftVisibleCells](functions/row_getLeftVisibleCells.md) - [row\_getParentRow](functions/row_getParentRow.md) - [row\_getParentRows](functions/row_getParentRows.md) - [row\_getPinnedIndex](functions/row_getPinnedIndex.md) - [row\_getRightVisibleCells](functions/row_getRightVisibleCells.md) - [row\_getToggleExpandedHandler](functions/row_getToggleExpandedHandler.md) - [row\_getToggleSelectedHandler](functions/row_getToggleSelectedHandler.md) - [row\_getUniqueValues](functions/row_getUniqueValues.md) - [row\_getValue](functions/row_getValue.md) - [row\_getVisibleCells](functions/row_getVisibleCells.md) - [row\_pin](functions/row_pin.md) - [row\_renderValue](functions/row_renderValue.md) - [row\_toggleExpanded](functions/row_toggleExpanded.md) - [row\_toggleSelected](functions/row_toggleSelected.md) - [selectRowsFn](functions/selectRowsFn.md) - [shouldAutoRemoveFilter](functions/shouldAutoRemoveFilter.md) - [table\_autoResetExpanded](functions/table_autoResetExpanded.md) - [table\_autoResetPageIndex](functions/table_autoResetPageIndex.md) - [table\_firstPage](functions/table_firstPage.md) - [table\_getAllColumns](functions/table_getAllColumns.md) - [table\_getAllFlatColumns](functions/table_getAllFlatColumns.md) - [table\_getAllFlatColumnsById](functions/table_getAllFlatColumnsById.md) - [table\_getAllLeafColumns](functions/table_getAllLeafColumns.md) - [table\_getBottomRows](functions/table_getBottomRows.md) - [table\_getCanNextPage](functions/table_getCanNextPage.md) - [table\_getCanPreviousPage](functions/table_getCanPreviousPage.md) - [table\_getCanSomeRowsExpand](functions/table_getCanSomeRowsExpand.md) - [table\_getCenterFlatHeaders](functions/table_getCenterFlatHeaders.md) - [table\_getCenterFooterGroups](functions/table_getCenterFooterGroups.md) - [table\_getCenterHeaderGroups](functions/table_getCenterHeaderGroups.md) - [table\_getCenterLeafColumns](functions/table_getCenterLeafColumns.md) - [table\_getCenterLeafHeaders](functions/table_getCenterLeafHeaders.md) - [table\_getCenterRows](functions/table_getCenterRows.md) - [table\_getCenterTotalSize](functions/table_getCenterTotalSize.md) - [table\_getCenterVisibleLeafColumns](functions/table_getCenterVisibleLeafColumns.md) - [table\_getColumn](functions/table_getColumn.md) - [table\_getCoreRowModel](functions/table_getCoreRowModel.md) - [table\_getDefaultColumnDef](functions/table_getDefaultColumnDef.md) - [table\_getExpandedDepth](functions/table_getExpandedDepth.md) - [table\_getExpandedRowModel](functions/table_getExpandedRowModel.md) - [table\_getFilteredRowModel](functions/table_getFilteredRowModel.md) - [table\_getFilteredSelectedRowModel](functions/table_getFilteredSelectedRowModel.md) - [table\_getFlatHeaders](functions/table_getFlatHeaders.md) - [table\_getFooterGroups](functions/table_getFooterGroups.md) - [table\_getGlobalAutoFilterFn](functions/table_getGlobalAutoFilterFn.md) - [table\_getGlobalFacetedMinMaxValues](functions/table_getGlobalFacetedMinMaxValues.md) - [table\_getGlobalFacetedRowModel](functions/table_getGlobalFacetedRowModel.md) - [table\_getGlobalFacetedUniqueValues](functions/table_getGlobalFacetedUniqueValues.md) - [table\_getGlobalFilterFn](functions/table_getGlobalFilterFn.md) - [table\_getGroupedRowModel](functions/table_getGroupedRowModel.md) - [table\_getGroupedSelectedRowModel](functions/table_getGroupedSelectedRowModel.md) - [table\_getHeaderGroups](functions/table_getHeaderGroups.md) - [table\_getIsAllColumnsVisible](functions/table_getIsAllColumnsVisible.md) - [table\_getIsAllPageRowsSelected](functions/table_getIsAllPageRowsSelected.md) - [table\_getIsAllRowsExpanded](functions/table_getIsAllRowsExpanded.md) - [table\_getIsAllRowsSelected](functions/table_getIsAllRowsSelected.md) - [table\_getIsSomeColumnsPinned](functions/table_getIsSomeColumnsPinned.md) - [table\_getIsSomeColumnsVisible](functions/table_getIsSomeColumnsVisible.md) - [table\_getIsSomePageRowsSelected](functions/table_getIsSomePageRowsSelected.md) - [table\_getIsSomeRowsExpanded](functions/table_getIsSomeRowsExpanded.md) - [table\_getIsSomeRowsPinned](functions/table_getIsSomeRowsPinned.md) - [table\_getIsSomeRowsSelected](functions/table_getIsSomeRowsSelected.md) - [table\_getLeafHeaders](functions/table_getLeafHeaders.md) - [table\_getLeftFlatHeaders](functions/table_getLeftFlatHeaders.md) - [table\_getLeftFooterGroups](functions/table_getLeftFooterGroups.md) - [table\_getLeftHeaderGroups](functions/table_getLeftHeaderGroups.md) - [table\_getLeftLeafColumns](functions/table_getLeftLeafColumns.md) - [table\_getLeftLeafHeaders](functions/table_getLeftLeafHeaders.md) - [table\_getLeftTotalSize](functions/table_getLeftTotalSize.md) - [table\_getLeftVisibleLeafColumns](functions/table_getLeftVisibleLeafColumns.md) - [table\_getOrderColumnsFn](functions/table_getOrderColumnsFn.md) - [table\_getPageCount](functions/table_getPageCount.md) - [table\_getPageOptions](functions/table_getPageOptions.md) - [table\_getPaginatedRowModel](functions/table_getPaginatedRowModel.md) - [table\_getPinnedLeafColumns](functions/table_getPinnedLeafColumns.md) - [table\_getPinnedVisibleLeafColumns](functions/table_getPinnedVisibleLeafColumns.md) - [table\_getPreExpandedRowModel](functions/table_getPreExpandedRowModel.md) - [table\_getPreFilteredRowModel](functions/table_getPreFilteredRowModel.md) - [table\_getPreGroupedRowModel](functions/table_getPreGroupedRowModel.md) - [table\_getPrePaginatedRowModel](functions/table_getPrePaginatedRowModel.md) - [table\_getPreSelectedRowModel](functions/table_getPreSelectedRowModel.md) - [table\_getPreSortedRowModel](functions/table_getPreSortedRowModel.md) - [table\_getRightFlatHeaders](functions/table_getRightFlatHeaders.md) - [table\_getRightFooterGroups](functions/table_getRightFooterGroups.md) - [table\_getRightHeaderGroups](functions/table_getRightHeaderGroups.md) - [table\_getRightLeafColumns](functions/table_getRightLeafColumns.md) - [table\_getRightLeafHeaders](functions/table_getRightLeafHeaders.md) - [table\_getRightTotalSize](functions/table_getRightTotalSize.md) - [table\_getRightVisibleLeafColumns](functions/table_getRightVisibleLeafColumns.md) - [table\_getRow](functions/table_getRow.md) - [table\_getRowCount](functions/table_getRowCount.md) - [table\_getRowId](functions/table_getRowId.md) - [table\_getRowModel](functions/table_getRowModel.md) - [table\_getSelectedRowModel](functions/table_getSelectedRowModel.md) - [table\_getSortedRowModel](functions/table_getSortedRowModel.md) - [table\_getToggleAllColumnsVisibilityHandler](functions/table_getToggleAllColumnsVisibilityHandler.md) - [table\_getToggleAllPageRowsSelectedHandler](functions/table_getToggleAllPageRowsSelectedHandler.md) - [table\_getToggleAllRowsExpandedHandler](functions/table_getToggleAllRowsExpandedHandler.md) - [table\_getToggleAllRowsSelectedHandler](functions/table_getToggleAllRowsSelectedHandler.md) - [table\_getTopRows](functions/table_getTopRows.md) - [table\_getTotalSize](functions/table_getTotalSize.md) - [table\_getVisibleFlatColumns](functions/table_getVisibleFlatColumns.md) - [table\_getVisibleLeafColumns](functions/table_getVisibleLeafColumns.md) - [table\_lastPage](functions/table_lastPage.md) - [table\_mergeOptions](functions/table_mergeOptions.md) - [table\_nextPage](functions/table_nextPage.md) - [table\_previousPage](functions/table_previousPage.md) - [table\_reset](functions/table_reset.md) - [table\_resetColumnFilters](functions/table_resetColumnFilters.md) - [table\_resetColumnOrder](functions/table_resetColumnOrder.md) - [table\_resetColumnPinning](functions/table_resetColumnPinning.md) - [table\_resetColumnSizing](functions/table_resetColumnSizing.md) - [table\_resetColumnVisibility](functions/table_resetColumnVisibility.md) - [table\_resetExpanded](functions/table_resetExpanded.md) - [table\_resetGlobalFilter](functions/table_resetGlobalFilter.md) - [table\_resetGrouping](functions/table_resetGrouping.md) - [table\_resetHeaderSizeInfo](functions/table_resetHeaderSizeInfo.md) - [table\_resetPageIndex](functions/table_resetPageIndex.md) - [table\_resetPageSize](functions/table_resetPageSize.md) - [table\_resetPagination](functions/table_resetPagination.md) - [table\_resetRowPinning](functions/table_resetRowPinning.md) - [table\_resetRowSelection](functions/table_resetRowSelection.md) - [table\_resetSorting](functions/table_resetSorting.md) - [table\_setColumnFilters](functions/table_setColumnFilters.md) - [table\_setColumnOrder](functions/table_setColumnOrder.md) - [table\_setColumnPinning](functions/table_setColumnPinning.md) - [table\_setColumnResizing](functions/table_setColumnResizing.md) - [table\_setColumnSizing](functions/table_setColumnSizing.md) - [table\_setColumnVisibility](functions/table_setColumnVisibility.md) - [table\_setExpanded](functions/table_setExpanded.md) - [table\_setGlobalFilter](functions/table_setGlobalFilter.md) - [table\_setGrouping](functions/table_setGrouping.md) - [table\_setOptions](functions/table_setOptions.md) - [table\_setPageIndex](functions/table_setPageIndex.md) - [table\_setPageSize](functions/table_setPageSize.md) - [table\_setPagination](functions/table_setPagination.md) - [table\_setRowPinning](functions/table_setRowPinning.md) - [table\_setRowSelection](functions/table_setRowSelection.md) - [table\_setSorting](functions/table_setSorting.md) - [table\_toggleAllColumnsVisible](functions/table_toggleAllColumnsVisible.md) - [table\_toggleAllPageRowsSelected](functions/table_toggleAllPageRowsSelected.md) - [table\_toggleAllRowsExpanded](functions/table_toggleAllRowsExpanded.md) - [table\_toggleAllRowsSelected](functions/table_toggleAllRowsSelected.md) - [tableFeatures](functions/tableFeatures.md) - [tableMemo](functions/tableMemo.md) - [tableOptions](functions/tableOptions.md) ================================================ FILE: docs/reference/interfaces/API.md ================================================ --- id: API title: API --- # Interface: API\ Defined in: [utils.ts:267](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L267) ## Type Parameters ### TDeps `TDeps` *extends* `ReadonlyArray`\<`any`\> ### TDepArgs `TDepArgs` ## Properties ### fn() ```ts fn: (...args) => any; ``` Defined in: [utils.ts:268](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L268) #### Parameters ##### args ...`any` #### Returns `any` *** ### memoDeps()? ```ts optional memoDeps: (depArgs?) => any[] | undefined; ``` Defined in: [utils.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L269) #### Parameters ##### depArgs? `any` #### Returns `any`[] \| `undefined` ================================================ FILE: docs/reference/interfaces/AggregationFns.md ================================================ --- id: AggregationFns title: AggregationFns --- # Interface: AggregationFns Defined in: [features/column-grouping/columnGroupingFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L28) ================================================ FILE: docs/reference/interfaces/CachedRowModel_Core.md ================================================ --- id: CachedRowModel_Core title: CachedRowModel_Core --- # Interface: CachedRowModel\_Core\ Defined in: [core/row-models/coreRowModelsFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L37) ## Extends - [`CachedRowModel_Plugins`](CachedRowModel_Plugins.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### coreRowModel() ```ts coreRowModel: () => RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L41) #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CachedRowModel_Expanded.md ================================================ --- id: CachedRowModel_Expanded title: CachedRowModel_Expanded --- # Interface: CachedRowModel\_Expanded\ Defined in: [features/row-expanding/rowExpandingFeature.types.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L136) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### expandedRowModel() ```ts expandedRowModel: () => RowModel; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L140) #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CachedRowModel_Faceted.md ================================================ --- id: CachedRowModel_Faceted title: CachedRowModel_Faceted --- # Interface: CachedRowModel\_Faceted\ Defined in: [features/column-faceting/columnFacetingFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L72) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### facetedMinMaxValues()? ```ts optional facetedMinMaxValues: (columnId) => [number, number]; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L77) #### Parameters ##### columnId `string` #### Returns \[`number`, `number`\] *** ### facetedRowModel()? ```ts optional facetedRowModel: (columnId) => () => RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L76) #### Parameters ##### columnId `string` #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### facetedUniqueValues()? ```ts optional facetedUniqueValues: (columnId) => Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L78) #### Parameters ##### columnId `string` #### Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/interfaces/CachedRowModel_Filtered.md ================================================ --- id: CachedRowModel_Filtered title: CachedRowModel_Filtered --- # Interface: CachedRowModel\_Filtered\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:214](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L214) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### filteredRowModel() ```ts filteredRowModel: () => RowModel; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:218](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L218) #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CachedRowModel_Grouped.md ================================================ --- id: CachedRowModel_Grouped title: CachedRowModel_Grouped --- # Interface: CachedRowModel\_Grouped\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:213](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L213) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### groupedRowModel() ```ts groupedRowModel: () => RowModel; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:217](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L217) #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CachedRowModel_Paginated.md ================================================ --- id: CachedRowModel_Paginated title: CachedRowModel_Paginated --- # Interface: CachedRowModel\_Paginated\ Defined in: [features/row-pagination/rowPaginationFeature.types.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L136) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### paginatedRowModel() ```ts paginatedRowModel: () => RowModel; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L140) #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CachedRowModel_Plugins.md ================================================ --- id: CachedRowModel_Plugins title: CachedRowModel_Plugins --- # Interface: CachedRowModel\_Plugins Defined in: [core/row-models/coreRowModelsFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L35) ## Extended by - [`CachedRowModel_Core`](CachedRowModel_Core.md) ================================================ FILE: docs/reference/interfaces/CachedRowModel_Sorted.md ================================================ --- id: CachedRowModel_Sorted title: CachedRowModel_Sorted --- # Interface: CachedRowModel\_Sorted\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:224](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L224) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### sortedRowModel() ```ts sortedRowModel: () => RowModel; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:228](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L228) #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CachedRowModels_Plugins.md ================================================ --- id: CachedRowModels_Plugins title: CachedRowModels_Plugins --- # Interface: CachedRowModels\_Plugins\ Defined in: [types/RowModel.ts:87](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModel.ts#L87) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/CellContext.md ================================================ --- id: CellContext title: CellContext --- # Interface: CellContext\ Defined in: [core/cells/coreCellsFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L8) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### cell ```ts cell: Cell; ``` Defined in: [core/cells/coreCellsFeature.types.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L13) *** ### column ```ts column: Column; ``` Defined in: [core/cells/coreCellsFeature.types.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L14) *** ### getValue ```ts getValue: Getter; ``` Defined in: [core/cells/coreCellsFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L15) *** ### renderValue ```ts renderValue: Getter; ``` Defined in: [core/cells/coreCellsFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L16) *** ### row ```ts row: Row; ``` Defined in: [core/cells/coreCellsFeature.types.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L17) *** ### table ```ts table: Table; ``` Defined in: [core/cells/coreCellsFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L18) ================================================ FILE: docs/reference/interfaces/Cell_Cell.md ================================================ --- id: Cell_Cell title: Cell_Cell --- # Interface: Cell\_Cell\ Defined in: [core/cells/coreCellsFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L44) ## Extends - [`Cell_CoreProperties`](Cell_CoreProperties.md)\<`TFeatures`, `TData`, `TValue`\> ## Extended by - [`Cell_Core`](Cell_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### column ```ts column: Column; ``` Defined in: [core/cells/coreCellsFeature.types.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L29) The associated Column object for the cell. #### Inherited from [`Cell_CoreProperties`](Cell_CoreProperties.md).[`column`](Cell_CoreProperties.md#column) *** ### getContext() ```ts getContext: () => CellContext; ``` Defined in: [core/cells/coreCellsFeature.types.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L52) Returns the rendering context (or props) for cell-based components like cells and aggregated cells. Use these props with your framework's `flexRender` utility to render these using the template of your choice: #### Returns [`CellContext`](CellContext.md)\<`TFeatures`, `TData`, `TValue`\> *** ### getValue ```ts getValue: Getter; ``` Defined in: [core/cells/coreCellsFeature.types.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L56) Returns the value for the cell, accessed via the associated column's accessor key or accessor function. *** ### id ```ts id: string; ``` Defined in: [core/cells/coreCellsFeature.types.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L33) The unique ID for the cell across the entire table. #### Inherited from [`Cell_CoreProperties`](Cell_CoreProperties.md).[`id`](Cell_CoreProperties.md#id) *** ### renderValue ```ts renderValue: Getter; ``` Defined in: [core/cells/coreCellsFeature.types.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L60) Renders the value for a cell the same as `getValue`, but will return the `renderFallbackValue` if no value is found. *** ### row ```ts row: Row; ``` Defined in: [core/cells/coreCellsFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L37) The associated Row object for the cell. #### Inherited from [`Cell_CoreProperties`](Cell_CoreProperties.md).[`row`](Cell_CoreProperties.md#row) *** ### table ```ts table: Table_Internal; ``` Defined in: [core/cells/coreCellsFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L41) Reference to the parent table instance. #### Inherited from [`Cell_CoreProperties`](Cell_CoreProperties.md).[`table`](Cell_CoreProperties.md#table) ================================================ FILE: docs/reference/interfaces/Cell_ColumnGrouping.md ================================================ --- id: Cell_ColumnGrouping title: Cell_ColumnGrouping --- # Interface: Cell\_ColumnGrouping Defined in: [features/column-grouping/columnGroupingFeature.types.ts:132](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L132) ## Properties ### getIsAggregated() ```ts getIsAggregated: () => boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L136) Returns whether or not the cell is currently aggregated. #### Returns `boolean` *** ### getIsGrouped() ```ts getIsGrouped: () => boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L140) Returns whether or not the cell is currently grouped. #### Returns `boolean` *** ### getIsPlaceholder() ```ts getIsPlaceholder: () => boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:144](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L144) Returns whether or not the cell is currently a placeholder cell. #### Returns `boolean` ================================================ FILE: docs/reference/interfaces/Cell_Core.md ================================================ --- id: Cell_Core title: Cell_Core --- # Interface: Cell\_Core\ Defined in: [types/Cell.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Cell.ts#L16) ## Extends - [`Cell_Cell`](Cell_Cell.md)\<`TFeatures`, `TData`, `TValue`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### column ```ts column: Column; ``` Defined in: [core/cells/coreCellsFeature.types.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L29) The associated Column object for the cell. #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`column`](Cell_Cell.md#column) *** ### getContext() ```ts getContext: () => CellContext; ``` Defined in: [core/cells/coreCellsFeature.types.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L52) Returns the rendering context (or props) for cell-based components like cells and aggregated cells. Use these props with your framework's `flexRender` utility to render these using the template of your choice: #### Returns [`CellContext`](CellContext.md)\<`TFeatures`, `TData`, `TValue`\> #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`getContext`](Cell_Cell.md#getcontext) *** ### getValue ```ts getValue: Getter; ``` Defined in: [core/cells/coreCellsFeature.types.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L56) Returns the value for the cell, accessed via the associated column's accessor key or accessor function. #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`getValue`](Cell_Cell.md#getvalue) *** ### id ```ts id: string; ``` Defined in: [core/cells/coreCellsFeature.types.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L33) The unique ID for the cell across the entire table. #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`id`](Cell_Cell.md#id) *** ### renderValue ```ts renderValue: Getter; ``` Defined in: [core/cells/coreCellsFeature.types.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L60) Renders the value for a cell the same as `getValue`, but will return the `renderFallbackValue` if no value is found. #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`renderValue`](Cell_Cell.md#rendervalue) *** ### row ```ts row: Row; ``` Defined in: [core/cells/coreCellsFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L37) The associated Row object for the cell. #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`row`](Cell_Cell.md#row) *** ### table ```ts table: Table_Internal; ``` Defined in: [core/cells/coreCellsFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L41) Reference to the parent table instance. #### Inherited from [`Cell_Cell`](Cell_Cell.md).[`table`](Cell_Cell.md#table) ================================================ FILE: docs/reference/interfaces/Cell_CoreProperties.md ================================================ --- id: Cell_CoreProperties title: Cell_CoreProperties --- # Interface: Cell\_CoreProperties\ Defined in: [core/cells/coreCellsFeature.types.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L21) ## Extended by - [`Cell_Cell`](Cell_Cell.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### column ```ts column: Column; ``` Defined in: [core/cells/coreCellsFeature.types.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L29) The associated Column object for the cell. *** ### id ```ts id: string; ``` Defined in: [core/cells/coreCellsFeature.types.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L33) The unique ID for the cell across the entire table. *** ### row ```ts row: Row; ``` Defined in: [core/cells/coreCellsFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L37) The associated Row object for the cell. *** ### table ```ts table: Table_Internal; ``` Defined in: [core/cells/coreCellsFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L41) Reference to the parent table instance. ================================================ FILE: docs/reference/interfaces/Cell_Plugins.md ================================================ --- id: Cell_Plugins title: Cell_Plugins --- # Interface: Cell\_Plugins\ Defined in: [types/Cell.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Cell.ts#L10) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ================================================ FILE: docs/reference/interfaces/ColumnDef_ColumnFiltering.md ================================================ --- id: ColumnDef_ColumnFiltering title: ColumnDef_ColumnFiltering --- # Interface: ColumnDef\_ColumnFiltering\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L81) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### enableColumnFilter? ```ts optional enableColumnFilter: boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L88) Enables/disables the **column** filter for this column. *** ### filterFn? ```ts optional filterFn: FilterFnOption; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L92) The filter function to use with this column. Can be the name of a built-in filter function or a custom filter function. ================================================ FILE: docs/reference/interfaces/ColumnDef_ColumnGrouping.md ================================================ --- id: ColumnDef_ColumnGrouping title: ColumnDef_ColumnGrouping --- # Interface: ColumnDef\_ColumnGrouping\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:53](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L53) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### aggregatedCell? ```ts optional aggregatedCell: ColumnDefTemplate["getContext"]>>; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L61) The cell to display each row for the column if the cell is an aggregate. If a function is passed, it will be passed a props object with the context of the cell and should return the property type for your adapter (the exact type depends on the adapter being used). *** ### aggregationFn? ```ts optional aggregationFn: AggregationFnOption; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L67) The resolved aggregation function for the column. *** ### enableGrouping? ```ts optional enableGrouping: boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L71) Enables/disables grouping for this column. *** ### getGroupingValue()? ```ts optional getGroupingValue: (row) => any; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L75) Specify a value to be used for grouping rows on this column. If this option is not specified, the value derived from `accessorKey` / `accessorFn` will be used instead. #### Parameters ##### row `TData` #### Returns `any` ================================================ FILE: docs/reference/interfaces/ColumnDef_ColumnPinning.md ================================================ --- id: ColumnDef_ColumnPinning title: ColumnDef_ColumnPinning --- # Interface: ColumnDef\_ColumnPinning Defined in: [features/column-pinning/columnPinningFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L34) ## Properties ### enablePinning? ```ts optional enablePinning: boolean; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L38) Enables/disables column pinning for this column. Defaults to `true`. ================================================ FILE: docs/reference/interfaces/ColumnDef_ColumnResizing.md ================================================ --- id: ColumnDef_ColumnResizing title: ColumnDef_ColumnResizing --- # Interface: ColumnDef\_ColumnResizing Defined in: [features/column-resizing/columnResizingFeature.types.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L55) ## Properties ### enableResizing? ```ts optional enableResizing: boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L59) Enables or disables column resizing for the column. ================================================ FILE: docs/reference/interfaces/ColumnDef_ColumnSizing.md ================================================ --- id: ColumnDef_ColumnSizing title: ColumnDef_ColumnSizing --- # Interface: ColumnDef\_ColumnSizing Defined in: [features/column-sizing/columnSizingFeature.types.ts:49](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L49) ## Properties ### maxSize? ```ts optional maxSize: number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:53](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L53) The maximum allowed size for the column *** ### minSize? ```ts optional minSize: number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L57) The minimum allowed size for the column *** ### size? ```ts optional size: number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L61) The desired size for the column ================================================ FILE: docs/reference/interfaces/ColumnDef_ColumnVisibility.md ================================================ --- id: ColumnDef_ColumnVisibility title: ColumnDef_ColumnVisibility --- # Interface: ColumnDef\_ColumnVisibility Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L66) ## Properties ### enableHiding? ```ts optional enableHiding: boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:70](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L70) Enables/disables column hiding for this column. Defaults to `true`. ================================================ FILE: docs/reference/interfaces/ColumnDef_GlobalFiltering.md ================================================ --- id: ColumnDef_GlobalFiltering title: ColumnDef_GlobalFiltering --- # Interface: ColumnDef\_GlobalFiltering Defined in: [features/global-filtering/globalFilteringFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L18) ## Properties ### enableGlobalFilter? ```ts optional enableGlobalFilter: boolean; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L22) Enables/disables the **global** filter for this column. ================================================ FILE: docs/reference/interfaces/ColumnDef_Plugins.md ================================================ --- id: ColumnDef_Plugins title: ColumnDef_Plugins --- # Interface: ColumnDef\_Plugins\ Defined in: [types/ColumnDef.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L18) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ================================================ FILE: docs/reference/interfaces/ColumnDef_RowSorting.md ================================================ --- id: ColumnDef_RowSorting title: ColumnDef_RowSorting --- # Interface: ColumnDef\_RowSorting\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L51) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### enableMultiSort? ```ts optional enableMultiSort: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L58) Enables/Disables multi-sorting for this column. *** ### enableSorting? ```ts optional enableSorting: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L62) Enables/Disables sorting for this column. *** ### invertSorting? ```ts optional invertSorting: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L66) Inverts the order of the sorting for this column. This is useful for values that have an inverted best/worst scale where lower numbers are better, eg. a ranking (1st, 2nd, 3rd) or golf-like scoring *** ### sortDescFirst? ```ts optional sortDescFirst: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:70](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L70) Set to `true` for sorting toggles on this column to start in the descending direction. *** ### sortFn? ```ts optional sortFn: SortFnOption; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L76) The sorting function to use with this column. - A `string` referencing a built-in sorting function - A custom sorting function *** ### sortUndefined? ```ts optional sortUndefined: false | 1 | -1 | "first" | "last"; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:86](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L86) The priority of undefined values when sorting this column. - `false` - Undefined values will be considered tied and need to be sorted by the next column filter or original index (whichever applies) - `-1` - Undefined values will be sorted with higher priority (ascending) (if ascending, undefined will appear on the beginning of the list) - `1` - Undefined values will be sorted with lower priority (descending) (if ascending, undefined will appear on the end of the list) ================================================ FILE: docs/reference/interfaces/ColumnDefaultOptions.md ================================================ --- id: ColumnDefaultOptions title: ColumnDefaultOptions --- # Interface: ColumnDefaultOptions Defined in: [features/column-grouping/columnGroupingFeature.types.ts:147](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L147) ## Properties ### enableGrouping ```ts enableGrouping: boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:148](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L148) *** ### onGroupingChange ```ts onGroupingChange: OnChangeFn; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L149) ================================================ FILE: docs/reference/interfaces/ColumnFilter.md ================================================ --- id: ColumnFilter title: ColumnFilter --- # Interface: ColumnFilter Defined in: [features/column-filtering/columnFilteringFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L24) ## Properties ### id ```ts id: string; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L25) *** ### value ```ts value: unknown; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L26) ================================================ FILE: docs/reference/interfaces/ColumnMeta.md ================================================ --- id: ColumnMeta title: ColumnMeta --- # Interface: ColumnMeta\ Defined in: [types/ColumnDef.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L24) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ================================================ FILE: docs/reference/interfaces/ColumnOrderDefaultOptions.md ================================================ --- id: ColumnOrderDefaultOptions title: ColumnOrderDefaultOptions --- # Interface: ColumnOrderDefaultOptions Defined in: [features/column-ordering/columnOrderingFeature.types.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L33) ## Properties ### onColumnOrderChange ```ts onColumnOrderChange: OnChangeFn; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L34) ================================================ FILE: docs/reference/interfaces/ColumnPinningDefaultOptions.md ================================================ --- id: ColumnPinningDefaultOptions title: ColumnPinningDefaultOptions --- # Interface: ColumnPinningDefaultOptions Defined in: [features/column-pinning/columnPinningFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L30) ## Properties ### onColumnPinningChange ```ts onColumnPinningChange: OnChangeFn; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L31) ================================================ FILE: docs/reference/interfaces/ColumnPinningState.md ================================================ --- id: ColumnPinningState title: ColumnPinningState --- # Interface: ColumnPinningState Defined in: [features/column-pinning/columnPinningFeature.types.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L10) ## Properties ### left ```ts left: string[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L11) *** ### right ```ts right: string[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L12) ================================================ FILE: docs/reference/interfaces/ColumnSort.md ================================================ --- id: ColumnSort title: ColumnSort --- # Interface: ColumnSort Defined in: [features/row-sorting/rowSortingFeature.types.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L10) ## Properties ### desc ```ts desc: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L11) *** ### id ```ts id: string; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L12) ================================================ FILE: docs/reference/interfaces/Column_Column.md ================================================ --- id: Column_Column title: Column_Column --- # Interface: Column\_Column\ Defined in: [core/columns/coreColumnsFeature.types.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L45) ## Extends - [`Column_CoreProperties`](Column_CoreProperties.md)\<`TFeatures`, `TData`, `TValue`\> ## Extended by - [`Column_Core`](Column_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### accessorFn? ```ts optional accessorFn: AccessorFn; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L15) The resolved accessor function to use when extracting the value for the column from each row. Will only be defined if the column def has a valid accessor key or function defined. #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`accessorFn`](Column_CoreProperties.md#accessorfn) *** ### columnDef ```ts columnDef: ColumnDef; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L19) The original column def used to create the column. #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`columnDef`](Column_CoreProperties.md#columndef) *** ### columns ```ts columns: Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L23) The child column (if the column is a group column). Will be an empty array if the column is not a group column. #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`columns`](Column_CoreProperties.md#columns) *** ### depth ```ts depth: number; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L27) The depth of the column (if grouped) relative to the root column def array. #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`depth`](Column_CoreProperties.md#depth) *** ### getFlatColumns() ```ts getFlatColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:53](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L53) Returns the flattened array of this column and all child/grand-child columns for this column. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] *** ### getLeafColumns() ```ts getLeafColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L57) Returns an array of all leaf-node columns for this column. If a column has no children, it is considered the only leaf-node column. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] *** ### id ```ts id: string; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L34) The resolved unique identifier for the column resolved in this priority: - A manual `id` property from the column def - The accessor key from the column def - The header string from the column def #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`id`](Column_CoreProperties.md#id) *** ### parent? ```ts optional parent: Column; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L38) The parent column for this column. Will be undefined if this is a root column. #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`parent`](Column_CoreProperties.md#parent) *** ### table ```ts table: Table_Internal; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L42) Reference to the parent table instance. #### Inherited from [`Column_CoreProperties`](Column_CoreProperties.md).[`table`](Column_CoreProperties.md#table) ================================================ FILE: docs/reference/interfaces/Column_ColumnFaceting.md ================================================ --- id: Column_ColumnFaceting title: Column_ColumnFaceting --- # Interface: Column\_ColumnFaceting\ Defined in: [features/column-faceting/columnFacetingFeature.types.ts:6](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L6) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getFacetedMinMaxValues() ```ts getFacetedMinMaxValues: () => [number, number] | undefined; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L13) A function that **computes and returns** a min/max tuple derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. #### Returns \[`number`, `number`\] \| `undefined` *** ### getFacetedRowModel() ```ts getFacetedRowModel: () => RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L17) A function that **computes and returns** a row model with all other column filters applied, excluding its own filter. Useful for displaying faceted result counts. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getFacetedUniqueValues() ```ts getFacetedUniqueValues: () => Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L21) Returns a `Map` of unique values and their occurrences derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. #### Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/interfaces/Column_ColumnFiltering.md ================================================ --- id: Column_ColumnFiltering title: Column_ColumnFiltering --- # Interface: Column\_ColumnFiltering\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:95](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L95) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getAutoFilterFn() ```ts getAutoFilterFn: () => FilterFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:102](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L102) Returns an automatically calculated filter function for the column based off of the columns first known value. #### Returns [`FilterFn`](FilterFn.md)\<`TFeatures`, `TData`\> *** ### getCanFilter() ```ts getCanFilter: () => boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L106) Returns whether or not the column can be **column** filtered. #### Returns `boolean` *** ### getFilterFn() ```ts getFilterFn: () => FilterFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:110](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L110) Returns the filter function (either user-defined or automatic, depending on configuration) for the columnId specified. #### Returns [`FilterFn`](FilterFn.md)\<`TFeatures`, `TData`\> *** ### getFilterIndex() ```ts getFilterIndex: () => number; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:114](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L114) Returns the index (including `-1`) of the column filter in the table's `state.columnFilters` array. #### Returns `number` *** ### getFilterValue() ```ts getFilterValue: () => unknown; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L118) Returns the current filter value for the column. #### Returns `unknown` *** ### getIsFiltered() ```ts getIsFiltered: () => boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L122) Returns whether or not the column is currently filtered. #### Returns `boolean` *** ### setFilterValue() ```ts setFilterValue: (updater) => void; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:126](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L126) A function that sets the current filter value for the column. You can pass it a value or an updater function for immutability-safe operations on existing values. #### Parameters ##### updater `any` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Column_ColumnGrouping.md ================================================ --- id: Column_ColumnGrouping title: Column_ColumnGrouping --- # Interface: Column\_ColumnGrouping\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L78) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getAggregationFn() ```ts getAggregationFn: () => | AggregationFn | undefined; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L85) Returns the aggregation function for the column. #### Returns \| [`AggregationFn`](../type-aliases/AggregationFn.md)\<`TFeatures`, `TData`\> \| `undefined` *** ### getAutoAggregationFn() ```ts getAutoAggregationFn: () => | AggregationFn | undefined; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L89) Returns the automatically inferred aggregation function for the column. #### Returns \| [`AggregationFn`](../type-aliases/AggregationFn.md)\<`TFeatures`, `TData`\> \| `undefined` *** ### getCanGroup() ```ts getCanGroup: () => boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:93](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L93) Returns whether or not the column can be grouped. #### Returns `boolean` *** ### getGroupedIndex() ```ts getGroupedIndex: () => number; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L97) Returns the index of the column in the grouping state. #### Returns `number` *** ### getIsGrouped() ```ts getIsGrouped: () => boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L101) Returns whether or not the column is currently grouped. #### Returns `boolean` *** ### getToggleGroupingHandler() ```ts getToggleGroupingHandler: () => () => void; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:105](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L105) Returns a function that toggles the grouping state of the column. This is useful for passing to the `onClick` prop of a button. #### Returns ```ts (): void; ``` ##### Returns `void` *** ### toggleGrouping() ```ts toggleGrouping: () => void; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L109) Toggles the grouping state of the column. #### Returns `void` ================================================ FILE: docs/reference/interfaces/Column_ColumnOrdering.md ================================================ --- id: Column_ColumnOrdering title: Column_ColumnOrdering --- # Interface: Column\_ColumnOrdering Defined in: [features/column-ordering/columnOrderingFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L18) ## Properties ### getIndex() ```ts getIndex: (position?) => number; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L22) Returns the index of the column in the order of the visible columns. Optionally pass a `position` parameter to get the index of the column in a sub-section of the table #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns `number` *** ### getIsFirstColumn() ```ts getIsFirstColumn: (position?) => boolean; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L26) Returns `true` if the column is the first column in the order of the visible columns. Optionally pass a `position` parameter to check if the column is the first in a sub-section of the table. #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns `boolean` *** ### getIsLastColumn() ```ts getIsLastColumn: (position?) => boolean; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L30) Returns `true` if the column is the last column in the order of the visible columns. Optionally pass a `position` parameter to check if the column is the last in a sub-section of the table. #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns `boolean` ================================================ FILE: docs/reference/interfaces/Column_ColumnPinning.md ================================================ --- id: Column_ColumnPinning title: Column_ColumnPinning --- # Interface: Column\_ColumnPinning Defined in: [features/column-pinning/columnPinningFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L41) ## Properties ### getCanPin() ```ts getCanPin: () => boolean; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L45) Returns whether or not the column can be pinned. #### Returns `boolean` *** ### getIsPinned() ```ts getIsPinned: () => ColumnPinningPosition; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:49](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L49) Returns the pinned position of the column. (`'left'`, `'right'` or `false`) #### Returns [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) *** ### getPinnedIndex() ```ts getPinnedIndex: () => number; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:53](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L53) Returns the numeric pinned index of the column within a pinned column group. #### Returns `number` *** ### pin() ```ts pin: (position) => void; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L57) Pins a column to the `'left'` or `'right'`, or unpins the column to the center if `false` is passed. #### Parameters ##### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) #### Returns `void` ================================================ FILE: docs/reference/interfaces/Column_ColumnResizing.md ================================================ --- id: Column_ColumnResizing title: Column_ColumnResizing --- # Interface: Column\_ColumnResizing Defined in: [features/column-resizing/columnResizingFeature.types.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L62) ## Properties ### getCanResize() ```ts getCanResize: () => boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L66) Returns `true` if the column can be resized. #### Returns `boolean` *** ### getIsResizing() ```ts getIsResizing: () => boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:70](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L70) Returns `true` if the column is currently being resized. #### Returns `boolean` ================================================ FILE: docs/reference/interfaces/Column_ColumnSizing.md ================================================ --- id: Column_ColumnSizing title: Column_ColumnSizing --- # Interface: Column\_ColumnSizing Defined in: [features/column-sizing/columnSizingFeature.types.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L64) ## Properties ### getAfter() ```ts getAfter: (position?) => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L68) Returns the offset measurement along the row-axis (usually the x-axis for standard tables) for the header. This is effectively a sum of the offset measurements of all succeeding (right) headers in relation to the current column. #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns `number` *** ### getSize() ```ts getSize: () => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L72) Returns the current size of the column. #### Returns `number` *** ### getStart() ```ts getStart: (position?) => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L76) Returns the offset measurement along the row-axis (usually the x-axis for standard tables) for the header. This is effectively a sum of the offset measurements of all preceding (left) headers in relation to the current column. #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns `number` *** ### resetSize() ```ts resetSize: () => void; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L80) Resets the column to its initial size. #### Returns `void` ================================================ FILE: docs/reference/interfaces/Column_ColumnVisibility.md ================================================ --- id: Column_ColumnVisibility title: Column_ColumnVisibility --- # Interface: Column\_ColumnVisibility Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L84) ## Properties ### getCanHide() ```ts getCanHide: () => boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L88) Returns whether the column can be hidden #### Returns `boolean` *** ### getIsVisible() ```ts getIsVisible: () => boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L92) Returns whether the column is visible #### Returns `boolean` *** ### getToggleVisibilityHandler() ```ts getToggleVisibilityHandler: () => (event) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L96) Returns a function that can be used to toggle the column visibility. This function can be used to bind to an event handler to a checkbox. #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` *** ### toggleVisibility() ```ts toggleVisibility: (value?) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L100) Toggles the visibility of the column. #### Parameters ##### value? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Column_Core.md ================================================ --- id: Column_Core title: Column_Core --- # Interface: Column\_Core\ Defined in: [types/Column.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Column.ts#L26) ## Extends - [`Column_Column`](Column_Column.md)\<`TFeatures`, `TData`, `TValue`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` = `unknown` ## Properties ### accessorFn? ```ts optional accessorFn: AccessorFn; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L15) The resolved accessor function to use when extracting the value for the column from each row. Will only be defined if the column def has a valid accessor key or function defined. #### Inherited from [`Column_Column`](Column_Column.md).[`accessorFn`](Column_Column.md#accessorfn) *** ### columnDef ```ts columnDef: ColumnDef; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L19) The original column def used to create the column. #### Inherited from [`Column_Column`](Column_Column.md).[`columnDef`](Column_Column.md#columndef) *** ### columns ```ts columns: Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L23) The child column (if the column is a group column). Will be an empty array if the column is not a group column. #### Inherited from [`Column_Column`](Column_Column.md).[`columns`](Column_Column.md#columns) *** ### depth ```ts depth: number; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L27) The depth of the column (if grouped) relative to the root column def array. #### Inherited from [`Column_Column`](Column_Column.md).[`depth`](Column_Column.md#depth) *** ### getFlatColumns() ```ts getFlatColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:53](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L53) Returns the flattened array of this column and all child/grand-child columns for this column. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] #### Inherited from [`Column_Column`](Column_Column.md).[`getFlatColumns`](Column_Column.md#getflatcolumns) *** ### getLeafColumns() ```ts getLeafColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L57) Returns an array of all leaf-node columns for this column. If a column has no children, it is considered the only leaf-node column. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\>[] #### Inherited from [`Column_Column`](Column_Column.md).[`getLeafColumns`](Column_Column.md#getleafcolumns) *** ### id ```ts id: string; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L34) The resolved unique identifier for the column resolved in this priority: - A manual `id` property from the column def - The accessor key from the column def - The header string from the column def #### Inherited from [`Column_Column`](Column_Column.md).[`id`](Column_Column.md#id) *** ### parent? ```ts optional parent: Column; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L38) The parent column for this column. Will be undefined if this is a root column. #### Inherited from [`Column_Column`](Column_Column.md).[`parent`](Column_Column.md#parent) *** ### table ```ts table: Table_Internal; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L42) Reference to the parent table instance. #### Inherited from [`Column_Column`](Column_Column.md).[`table`](Column_Column.md#table) ================================================ FILE: docs/reference/interfaces/Column_CoreProperties.md ================================================ --- id: Column_CoreProperties title: Column_CoreProperties --- # Interface: Column\_CoreProperties\ Defined in: [core/columns/coreColumnsFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L7) ## Extended by - [`Column_Column`](Column_Column.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### accessorFn? ```ts optional accessorFn: AccessorFn; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L15) The resolved accessor function to use when extracting the value for the column from each row. Will only be defined if the column def has a valid accessor key or function defined. *** ### columnDef ```ts columnDef: ColumnDef; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L19) The original column def used to create the column. *** ### columns ```ts columns: Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L23) The child column (if the column is a group column). Will be an empty array if the column is not a group column. *** ### depth ```ts depth: number; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L27) The depth of the column (if grouped) relative to the root column def array. *** ### id ```ts id: string; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L34) The resolved unique identifier for the column resolved in this priority: - A manual `id` property from the column def - The accessor key from the column def - The header string from the column def *** ### parent? ```ts optional parent: Column; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L38) The parent column for this column. Will be undefined if this is a root column. *** ### table ```ts table: Table_Internal; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L42) Reference to the parent table instance. ================================================ FILE: docs/reference/interfaces/Column_GlobalFiltering.md ================================================ --- id: Column_GlobalFiltering title: Column_GlobalFiltering --- # Interface: Column\_GlobalFiltering Defined in: [features/global-filtering/globalFilteringFeature.types.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L25) ## Properties ### getCanGlobalFilter() ```ts getCanGlobalFilter: () => boolean; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L29) Returns whether or not the column can be **globally** filtered. Set to `false` to disable a column from being scanned during global filtering. #### Returns `boolean` ================================================ FILE: docs/reference/interfaces/Column_Plugins.md ================================================ --- id: Column_Plugins title: Column_Plugins --- # Interface: Column\_Plugins\ Defined in: [types/Column.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Column.ts#L20) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` = `unknown` ================================================ FILE: docs/reference/interfaces/Column_RowSorting.md ================================================ --- id: Column_RowSorting title: Column_RowSorting --- # Interface: Column\_RowSorting\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L89) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### clearSorting() ```ts clearSorting: () => void; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L96) Removes this column from the table's sorting state #### Returns `void` *** ### getAutoSortDir() ```ts getAutoSortDir: () => SortDirection; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L100) Returns a sort direction automatically inferred based on the columns values. #### Returns [`SortDirection`](../type-aliases/SortDirection.md) *** ### getAutoSortFn() ```ts getAutoSortFn: () => SortFn; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:104](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L104) Returns a sorting function automatically inferred based on the columns values. #### Returns [`SortFn`](SortFn.md)\<`TFeatures`, `TData`\> *** ### getCanMultiSort() ```ts getCanMultiSort: () => boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L108) Returns whether this column can be multi-sorted. #### Returns `boolean` *** ### getCanSort() ```ts getCanSort: () => boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L112) Returns whether this column can be sorted. #### Returns `boolean` *** ### getFirstSortDir() ```ts getFirstSortDir: () => SortDirection; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:116](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L116) Returns the first direction that should be used when sorting this column. #### Returns [`SortDirection`](../type-aliases/SortDirection.md) *** ### getIsSorted() ```ts getIsSorted: () => false | SortDirection; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L120) Returns the current sort direction of this column. #### Returns `false` \| [`SortDirection`](../type-aliases/SortDirection.md) *** ### getNextSortingOrder() ```ts getNextSortingOrder: () => false | SortDirection; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:124](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L124) Returns the next sorting order. #### Returns `false` \| [`SortDirection`](../type-aliases/SortDirection.md) *** ### getSortFn() ```ts getSortFn: () => SortFn; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:132](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L132) Returns the resolved sorting function to be used for this column #### Returns [`SortFn`](SortFn.md)\<`TFeatures`, `TData`\> *** ### getSortIndex() ```ts getSortIndex: () => number; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:128](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L128) Returns the index position of this column's sorting within the sorting state #### Returns `number` *** ### getToggleSortingHandler() ```ts getToggleSortingHandler: () => (event) => void | undefined; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L136) Returns a function that can be used to toggle this column's sorting state. This is useful for attaching a click handler to the column header. #### Returns (`event`) => `void` \| `undefined` *** ### toggleSorting() ```ts toggleSorting: (desc?, isMulti?) => void; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L140) Toggles this columns sorting state. If `desc` is provided, it will force the sort direction to that value. If `isMulti` is provided, it will additivity multi-sort the column (or toggle it if it is already sorted). #### Parameters ##### desc? `boolean` ##### isMulti? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/CoreFeatures.md ================================================ --- id: CoreFeatures title: CoreFeatures --- # Interface: CoreFeatures Defined in: [core/coreFeatures.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L8) ## Properties ### coreCellsFeature ```ts coreCellsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L9) *** ### coreColumnsFeature ```ts coreColumnsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L10) *** ### coreHeadersFeature ```ts coreHeadersFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L11) *** ### coreRowModelsFeature ```ts coreRowModelsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L12) *** ### coreRowsFeature ```ts coreRowsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L13) *** ### coreTablesFeature ```ts coreTablesFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L14) ================================================ FILE: docs/reference/interfaces/CreateRowModel_Core.md ================================================ --- id: CreateRowModel_Core title: CreateRowModel_Core --- # Interface: CreateRowModel\_Core\ Defined in: [core/row-models/coreRowModelsFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L23) ## Extends - [`CreateRowModel_Plugins`](CreateRowModel_Plugins.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### coreRowModel()? ```ts optional coreRowModel: (table) => () => RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L30) This required option is a factory for a function that computes and returns the core row model for the table. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CreateRowModel_Expanded.md ================================================ --- id: CreateRowModel_Expanded title: CreateRowModel_Expanded --- # Interface: CreateRowModel\_Expanded\ Defined in: [features/row-expanding/rowExpandingFeature.types.ts:124](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L124) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### expandedRowModel()? ```ts optional expandedRowModel: (table) => () => RowModel; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:131](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L131) This function is responsible for returning the expanded row model. If this function is not provided, the table will not expand rows. You can use the default exported `getExpandedRowModel` function to get the expanded row model or implement your own. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CreateRowModel_Faceted.md ================================================ --- id: CreateRowModel_Faceted title: CreateRowModel_Faceted --- # Interface: CreateRowModel\_Faceted\ Defined in: [features/column-faceting/columnFacetingFeature.types.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L45) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### facetedMinMaxValues()? ```ts optional facetedMinMaxValues: (table, columnId) => () => [number, number] | undefined; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L52) This function is used to retrieve the faceted min/max values. If using server-side faceting, this function is not required. To use client-side faceting, pass the exported `getFacetedMinMaxValues()` from your adapter to your table or implement your own. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ##### columnId `string` #### Returns ```ts (): [number, number] | undefined; ``` ##### Returns \[`number`, `number`\] \| `undefined` *** ### facetedRowModel()? ```ts optional facetedRowModel: (table, columnId) => () => RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L59) This function is used to retrieve the faceted row model. If using server-side faceting, this function is not required. To use client-side faceting, pass the exported `getFacetedRowModel()` from your adapter to your table or implement your own. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ##### columnId `string` #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### facetedUniqueValues()? ```ts optional facetedUniqueValues: (table, columnId) => () => Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L66) This function is used to retrieve the faceted unique values. If using server-side faceting, this function is not required. To use client-side faceting, pass the exported `getFacetedUniqueValues()` from your adapter to your table or implement your own. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> ##### columnId `string` #### Returns ```ts (): Map; ``` ##### Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/interfaces/CreateRowModel_Filtered.md ================================================ --- id: CreateRowModel_Filtered title: CreateRowModel_Filtered --- # Interface: CreateRowModel\_Filtered\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:200](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L200) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### filteredRowModel()? ```ts optional filteredRowModel: (table) => () => RowModel; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:209](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L209) If provided, this function is called **once** per table and should return a **new function** which will calculate and return the row model for the table when it's filtered. - For server-side filtering, this function is unnecessary and can be ignored since the server should already return the filtered row model. - For client-side filtering, this function is required. A default implementation is provided via any table adapter's `{ getFilteredRowModel }` export. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CreateRowModel_Grouped.md ================================================ --- id: CreateRowModel_Grouped title: CreateRowModel_Grouped --- # Interface: CreateRowModel\_Grouped\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:201](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L201) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### groupedRowModel()? ```ts optional groupedRowModel: (table) => () => RowModel; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:208](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L208) Returns the row model after grouping has taken place, but no further. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CreateRowModel_Paginated.md ================================================ --- id: CreateRowModel_Paginated title: CreateRowModel_Paginated --- # Interface: CreateRowModel\_Paginated\ Defined in: [features/row-pagination/rowPaginationFeature.types.ts:123](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L123) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### paginatedRowModel()? ```ts optional paginatedRowModel: (table) => () => RowModel; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:131](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L131) Returns the row model after pagination has taken place, but no further. Pagination columns are automatically reordered by default to the start of the columns list. If you would rather remove them or leave them as-is, set the appropriate mode here. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CreateRowModel_Plugins.md ================================================ --- id: CreateRowModel_Plugins title: CreateRowModel_Plugins --- # Interface: CreateRowModel\_Plugins Defined in: [core/row-models/coreRowModelsFeature.types.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L21) ## Extended by - [`CreateRowModel_Core`](CreateRowModel_Core.md) ================================================ FILE: docs/reference/interfaces/CreateRowModel_Sorted.md ================================================ --- id: CreateRowModel_Sorted title: CreateRowModel_Sorted --- # Interface: CreateRowModel\_Sorted\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:212](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L212) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### sortedRowModel()? ```ts optional sortedRowModel: (table) => () => RowModel; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:219](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L219) This function is used to retrieve the sorted row model. If using server-side sorting, this function is not required. To use client-side sorting, pass the exported `getSortedRowModel()` from your adapter to your table or implement your own. #### Parameters ##### table [`Table`](../type-aliases/Table.md)\<`TFeatures`, `TData`\> #### Returns ```ts (): RowModel; ``` ##### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/CreateRowModels_Plugins.md ================================================ --- id: CreateRowModels_Plugins title: CreateRowModels_Plugins --- # Interface: CreateRowModels\_Plugins\ Defined in: [types/RowModel.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModel.ts#L37) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/FilterFn.md ================================================ --- id: FilterFn title: FilterFn --- # Interface: FilterFn()\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L45) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ```ts FilterFn( row, columnId, filterValue, addMeta?): boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:49](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L49) ## Parameters ### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### columnId `string` ### filterValue `any` ### addMeta? (`meta`) => `void` ## Returns `boolean` ## Properties ### autoRemove? ```ts optional autoRemove: ColumnFilterAutoRemoveTestFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L55) *** ### resolveFilterValue? ```ts optional resolveFilterValue: TransformFilterValueFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L56) ================================================ FILE: docs/reference/interfaces/FilterFns.md ================================================ --- id: FilterFns title: FilterFns --- # Interface: FilterFns Defined in: [features/column-filtering/columnFilteringFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L16) ================================================ FILE: docs/reference/interfaces/FilterMeta.md ================================================ --- id: FilterMeta title: FilterMeta --- # Interface: FilterMeta Defined in: [features/column-filtering/columnFilteringFeature.types.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L14) ================================================ FILE: docs/reference/interfaces/HeaderContext.md ================================================ --- id: HeaderContext title: HeaderContext --- # Interface: HeaderContext\ Defined in: [core/headers/coreHeadersFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L30) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### column ```ts column: Column; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L38) An instance of a column. *** ### header ```ts header: Header; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L42) An instance of a header. *** ### table ```ts table: Table; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L46) The table instance. ================================================ FILE: docs/reference/interfaces/HeaderGroup_Core.md ================================================ --- id: HeaderGroup_Core title: HeaderGroup_Core --- # Interface: HeaderGroup\_Core\ Defined in: [types/HeaderGroup.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/HeaderGroup.ts#L14) ## Extends - [`HeaderGroup_Header`](HeaderGroup_Header.md)\<`TFeatures`, `TData`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### depth ```ts depth: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L120) #### Inherited from [`HeaderGroup_Header`](HeaderGroup_Header.md).[`depth`](HeaderGroup_Header.md#depth) *** ### headers ```ts headers: Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L121) #### Inherited from [`HeaderGroup_Header`](HeaderGroup_Header.md).[`headers`](HeaderGroup_Header.md#headers) *** ### id ```ts id: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L122) #### Inherited from [`HeaderGroup_Header`](HeaderGroup_Header.md).[`id`](HeaderGroup_Header.md#id) ================================================ FILE: docs/reference/interfaces/HeaderGroup_Header.md ================================================ --- id: HeaderGroup_Header title: HeaderGroup_Header --- # Interface: HeaderGroup\_Header\ Defined in: [core/headers/coreHeadersFeature.types.ts:115](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L115) ## Extended by - [`HeaderGroup_Core`](HeaderGroup_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### depth ```ts depth: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L120) *** ### headers ```ts headers: Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L121) *** ### id ```ts id: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L122) ================================================ FILE: docs/reference/interfaces/HeaderGroup_Plugins.md ================================================ --- id: HeaderGroup_Plugins title: HeaderGroup_Plugins --- # Interface: HeaderGroup\_Plugins\ Defined in: [types/HeaderGroup.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/HeaderGroup.ts#L9) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/Header_ColumnResizing.md ================================================ --- id: Header_ColumnResizing title: Header_ColumnResizing --- # Interface: Header\_ColumnResizing Defined in: [features/column-resizing/columnResizingFeature.types.ts:73](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L73) ## Properties ### getResizeHandler() ```ts getResizeHandler: (context?) => (event) => void; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L80) Returns an event handler function that can be used to resize the header. It can be used as an: - `onMouseDown` handler - `onTouchStart` handler The dragging and release events are automatically handled for you. #### Parameters ##### context? `Document` #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` ================================================ FILE: docs/reference/interfaces/Header_ColumnSizing.md ================================================ --- id: Header_ColumnSizing title: Header_ColumnSizing --- # Interface: Header\_ColumnSizing Defined in: [features/column-sizing/columnSizingFeature.types.ts:83](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L83) ## Properties ### getSize() ```ts getSize: () => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:87](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L87) Returns the current size of the header. #### Returns `number` *** ### getStart() ```ts getStart: (position?) => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:91](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L91) Returns the offset measurement along the row-axis (usually the x-axis for standard tables) for the header. This is effectively a sum of the offset measurements of all preceding headers. #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) #### Returns `number` ================================================ FILE: docs/reference/interfaces/Header_Core.md ================================================ --- id: Header_Core title: Header_Core --- # Interface: Header\_Core\ Defined in: [types/Header.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Header.ts#L17) ## Extends - [`Header_Header`](Header_Header.md)\<`TFeatures`, `TData`, `TValue`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### colSpan ```ts colSpan: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L57) The col-span for the header. #### Inherited from [`Header_Header`](Header_Header.md).[`colSpan`](Header_Header.md#colspan) *** ### column ```ts column: Column; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L61) The header's associated column object. #### Inherited from [`Header_Header`](Header_Header.md).[`column`](Header_Header.md#column) *** ### depth ```ts depth: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:65](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L65) The depth of the header, zero-indexed based. #### Inherited from [`Header_Header`](Header_Header.md).[`depth`](Header_Header.md#depth) *** ### getContext() ```ts getContext: () => HeaderContext; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L108) Returns the rendering context (or props) for column-based components like headers, footers and filters. #### Returns [`HeaderContext`](HeaderContext.md)\<`TFeatures`, `TData`, `TValue`\> #### Inherited from [`Header_Header`](Header_Header.md).[`getContext`](Header_Header.md#getcontext) *** ### getLeafHeaders() ```ts getLeafHeaders: () => Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L112) Returns the leaf headers hierarchically nested under this header. #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\>[] #### Inherited from [`Header_Header`](Header_Header.md).[`getLeafHeaders`](Header_Header.md#getleafheaders) *** ### headerGroup ```ts headerGroup: | HeaderGroup | null; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L69) The header's associated header group object. #### Inherited from [`Header_Header`](Header_Header.md).[`headerGroup`](Header_Header.md#headergroup) *** ### id ```ts id: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:73](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L73) The unique identifier for the header. #### Inherited from [`Header_Header`](Header_Header.md).[`id`](Header_Header.md#id) *** ### index ```ts index: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L77) The index for the header within the header group. #### Inherited from [`Header_Header`](Header_Header.md).[`index`](Header_Header.md#index) *** ### isPlaceholder ```ts isPlaceholder: boolean; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L81) A boolean denoting if the header is a placeholder header. #### Inherited from [`Header_Header`](Header_Header.md).[`isPlaceholder`](Header_Header.md#isplaceholder) *** ### placeholderId? ```ts optional placeholderId: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L85) If the header is a placeholder header, this will be a unique header ID that does not conflict with any other headers across the table. #### Inherited from [`Header_Header`](Header_Header.md).[`placeholderId`](Header_Header.md#placeholderid) *** ### rowSpan ```ts rowSpan: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L89) The row-span for the header. #### Inherited from [`Header_Header`](Header_Header.md).[`rowSpan`](Header_Header.md#rowspan) *** ### subHeaders ```ts subHeaders: Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:93](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L93) The header's hierarchical sub/child headers. Will be empty if the header's associated column is a leaf-column. #### Inherited from [`Header_Header`](Header_Header.md).[`subHeaders`](Header_Header.md#subheaders) *** ### table ```ts table: Table; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L97) Reference to the parent table instance. #### Inherited from [`Header_Header`](Header_Header.md).[`table`](Header_Header.md#table) ================================================ FILE: docs/reference/interfaces/Header_CoreProperties.md ================================================ --- id: Header_CoreProperties title: Header_CoreProperties --- # Interface: Header\_CoreProperties\ Defined in: [core/headers/coreHeadersFeature.types.ts:49](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L49) ## Extended by - [`Header_Header`](Header_Header.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### colSpan ```ts colSpan: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L57) The col-span for the header. *** ### column ```ts column: Column; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L61) The header's associated column object. *** ### depth ```ts depth: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:65](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L65) The depth of the header, zero-indexed based. *** ### headerGroup ```ts headerGroup: | HeaderGroup | null; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L69) The header's associated header group object. *** ### id ```ts id: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:73](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L73) The unique identifier for the header. *** ### index ```ts index: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L77) The index for the header within the header group. *** ### isPlaceholder ```ts isPlaceholder: boolean; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L81) A boolean denoting if the header is a placeholder header. *** ### placeholderId? ```ts optional placeholderId: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L85) If the header is a placeholder header, this will be a unique header ID that does not conflict with any other headers across the table. *** ### rowSpan ```ts rowSpan: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L89) The row-span for the header. *** ### subHeaders ```ts subHeaders: Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:93](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L93) The header's hierarchical sub/child headers. Will be empty if the header's associated column is a leaf-column. *** ### table ```ts table: Table; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L97) Reference to the parent table instance. ================================================ FILE: docs/reference/interfaces/Header_Header.md ================================================ --- id: Header_Header title: Header_Header --- # Interface: Header\_Header\ Defined in: [core/headers/coreHeadersFeature.types.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L100) ## Extends - [`Header_CoreProperties`](Header_CoreProperties.md)\<`TFeatures`, `TData`, `TValue`\> ## Extended by - [`Header_Core`](Header_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### colSpan ```ts colSpan: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L57) The col-span for the header. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`colSpan`](Header_CoreProperties.md#colspan) *** ### column ```ts column: Column; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L61) The header's associated column object. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`column`](Header_CoreProperties.md#column) *** ### depth ```ts depth: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:65](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L65) The depth of the header, zero-indexed based. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`depth`](Header_CoreProperties.md#depth) *** ### getContext() ```ts getContext: () => HeaderContext; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L108) Returns the rendering context (or props) for column-based components like headers, footers and filters. #### Returns [`HeaderContext`](HeaderContext.md)\<`TFeatures`, `TData`, `TValue`\> *** ### getLeafHeaders() ```ts getLeafHeaders: () => Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L112) Returns the leaf headers hierarchically nested under this header. #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `TValue`\>[] *** ### headerGroup ```ts headerGroup: | HeaderGroup | null; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L69) The header's associated header group object. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`headerGroup`](Header_CoreProperties.md#headergroup) *** ### id ```ts id: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:73](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L73) The unique identifier for the header. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`id`](Header_CoreProperties.md#id) *** ### index ```ts index: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L77) The index for the header within the header group. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`index`](Header_CoreProperties.md#index) *** ### isPlaceholder ```ts isPlaceholder: boolean; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L81) A boolean denoting if the header is a placeholder header. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`isPlaceholder`](Header_CoreProperties.md#isplaceholder) *** ### placeholderId? ```ts optional placeholderId: string; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L85) If the header is a placeholder header, this will be a unique header ID that does not conflict with any other headers across the table. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`placeholderId`](Header_CoreProperties.md#placeholderid) *** ### rowSpan ```ts rowSpan: number; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L89) The row-span for the header. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`rowSpan`](Header_CoreProperties.md#rowspan) *** ### subHeaders ```ts subHeaders: Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:93](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L93) The header's hierarchical sub/child headers. Will be empty if the header's associated column is a leaf-column. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`subHeaders`](Header_CoreProperties.md#subheaders) *** ### table ```ts table: Table; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L97) Reference to the parent table instance. #### Inherited from [`Header_CoreProperties`](Header_CoreProperties.md).[`table`](Header_CoreProperties.md#table) ================================================ FILE: docs/reference/interfaces/Header_Plugins.md ================================================ --- id: Header_Plugins title: Header_Plugins --- # Interface: Header\_Plugins\ Defined in: [types/Header.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Header.ts#L11) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ================================================ FILE: docs/reference/interfaces/IdIdentifier.md ================================================ --- id: IdIdentifier title: IdIdentifier --- # Interface: IdIdentifier\ Defined in: [types/ColumnDef.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L50) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### header? ```ts optional header: ColumnDefTemplate>; ``` Defined in: [types/ColumnDef.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L56) *** ### id ```ts id: string; ``` Defined in: [types/ColumnDef.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L55) ================================================ FILE: docs/reference/interfaces/PaginationDefaultOptions.md ================================================ --- id: PaginationDefaultOptions title: PaginationDefaultOptions --- # Interface: PaginationDefaultOptions Defined in: [features/row-pagination/rowPaginationFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L38) ## Properties ### onPaginationChange ```ts onPaginationChange: OnChangeFn; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L39) ================================================ FILE: docs/reference/interfaces/PaginationState.md ================================================ --- id: PaginationState title: PaginationState --- # Interface: PaginationState Defined in: [features/row-pagination/rowPaginationFeature.types.ts:6](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L6) ## Properties ### pageIndex ```ts pageIndex: number; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L7) *** ### pageSize ```ts pageSize: number; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L8) ================================================ FILE: docs/reference/interfaces/Plugins.md ================================================ --- id: Plugins title: Plugins --- # Interface: Plugins Defined in: [types/TableFeatures.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L40) ================================================ FILE: docs/reference/interfaces/PrototypeAPI.md ================================================ --- id: PrototypeAPI title: PrototypeAPI --- # Interface: PrototypeAPI\ Defined in: [utils.ts:322](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L322) ## Type Parameters ### TDeps `TDeps` *extends* `ReadonlyArray`\<`any`\> ### TDepArgs `TDepArgs` ## Properties ### fn() ```ts fn: (self, ...args) => any; ``` Defined in: [utils.ts:323](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L323) #### Parameters ##### self `any` ##### args ...`any` #### Returns `any` *** ### memoDeps()? ```ts optional memoDeps: (self, depArgs?) => any[] | undefined; ``` Defined in: [utils.ts:324](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L324) #### Parameters ##### self `any` ##### depArgs? `any` #### Returns `any`[] \| `undefined` ================================================ FILE: docs/reference/interfaces/ResolvedColumnFilter.md ================================================ --- id: ResolvedColumnFilter title: ResolvedColumnFilter --- # Interface: ResolvedColumnFilter\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L29) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### filterFn ```ts filterFn: FilterFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L33) *** ### id ```ts id: string; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L34) *** ### resolvedValue ```ts resolvedValue: unknown; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L35) ================================================ FILE: docs/reference/interfaces/RowModel.md ================================================ --- id: RowModel title: RowModel --- # Interface: RowModel\ Defined in: [core/row-models/coreRowModelsFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L12) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### flatRows ```ts flatRows: Row[]; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L17) *** ### rows ```ts rows: Row[]; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L16) *** ### rowsById ```ts rowsById: Record>; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L18) ================================================ FILE: docs/reference/interfaces/RowModelFns_ColumnFiltering.md ================================================ --- id: RowModelFns_ColumnFiltering title: RowModelFns_ColumnFiltering --- # Interface: RowModelFns\_ColumnFiltering\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L38) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### filterFns ```ts filterFns: Record>; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L42) ================================================ FILE: docs/reference/interfaces/RowModelFns_ColumnGrouping.md ================================================ --- id: RowModelFns_ColumnGrouping title: RowModelFns_ColumnGrouping --- # Interface: RowModelFns\_ColumnGrouping\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L21) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### aggregationFns ```ts aggregationFns: Record>; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L25) ================================================ FILE: docs/reference/interfaces/RowModelFns_Core.md ================================================ --- id: RowModelFns_Core title: RowModelFns_Core --- # Interface: RowModelFns\_Core Defined in: [types/RowModelFns.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModelFns.ts#L16) ================================================ FILE: docs/reference/interfaces/RowModelFns_Plugins.md ================================================ --- id: RowModelFns_Plugins title: RowModelFns_Plugins --- # Interface: RowModelFns\_Plugins\ Defined in: [types/RowModelFns.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModelFns.ts#L11) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/RowModelFns_RowSorting.md ================================================ --- id: RowModelFns_RowSorting title: RowModelFns_RowSorting --- # Interface: RowModelFns\_RowSorting\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L21) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### sortFns ```ts sortFns: Record>; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L25) ================================================ FILE: docs/reference/interfaces/RowPinningDefaultOptions.md ================================================ --- id: RowPinningDefaultOptions title: RowPinningDefaultOptions --- # Interface: RowPinningDefaultOptions Defined in: [features/row-pinning/rowPinningFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L34) ## Properties ### onRowPinningChange ```ts onRowPinningChange: OnChangeFn; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L35) ================================================ FILE: docs/reference/interfaces/RowPinningState.md ================================================ --- id: RowPinningState title: RowPinningState --- # Interface: RowPinningState Defined in: [features/row-pinning/rowPinningFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L7) ## Properties ### bottom ```ts bottom: string[]; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L8) *** ### top ```ts top: string[]; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L9) ================================================ FILE: docs/reference/interfaces/Row_ColumnFiltering.md ================================================ --- id: Row_ColumnFiltering title: Row_ColumnFiltering --- # Interface: Row\_ColumnFiltering\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:129](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L129) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### columnFilters ```ts columnFilters: Record; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L136) The column filters map for the row. This object tracks whether a row is passing/failing specific filters by their column ID. *** ### columnFiltersMeta ```ts columnFiltersMeta: Record; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L140) The column filters meta map for the row. This object tracks any filter meta for a row as optionally provided during the filtering process. ================================================ FILE: docs/reference/interfaces/Row_ColumnGrouping.md ================================================ --- id: Row_ColumnGrouping title: Row_ColumnGrouping --- # Interface: Row\_ColumnGrouping Defined in: [features/column-grouping/columnGroupingFeature.types.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L112) ## Properties ### \_groupingValuesCache ```ts _groupingValuesCache: Record; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L113) *** ### getGroupingValue() ```ts getGroupingValue: (columnId) => unknown; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L117) Returns the grouping value for any row and column (including leaf rows). #### Parameters ##### columnId `string` #### Returns `unknown` *** ### getIsGrouped() ```ts getIsGrouped: () => boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L121) Returns whether or not the row is currently grouped. #### Returns `boolean` *** ### groupingColumnId? ```ts optional groupingColumnId: string; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:125](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L125) If this row is grouped, this is the id of the column that this row is grouped by. *** ### groupingValue? ```ts optional groupingValue: unknown; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:129](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L129) If this row is grouped, this is the unique/shared value for the `groupingColumnId` for all of the rows in this group. ================================================ FILE: docs/reference/interfaces/Row_ColumnPinning.md ================================================ --- id: Row_ColumnPinning title: Row_ColumnPinning --- # Interface: Row\_ColumnPinning\ Defined in: [features/column-pinning/columnPinningFeature.types.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L60) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getCenterVisibleCells() ```ts getCenterVisibleCells: () => Cell[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L67) Returns all center pinned (unpinned) leaf cells in the row. #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getLeftVisibleCells() ```ts getLeftVisibleCells: () => Cell[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L71) Returns all left pinned leaf cells in the row. #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getRightVisibleCells() ```ts getRightVisibleCells: () => Cell[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L75) Returns all right pinned leaf cells in the row. #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/interfaces/Row_ColumnVisibility.md ================================================ --- id: Row_ColumnVisibility title: Row_ColumnVisibility --- # Interface: Row\_ColumnVisibility\ Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:73](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L73) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getAllVisibleCells() ```ts getAllVisibleCells: () => Cell[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L77) #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getVisibleCells() ```ts getVisibleCells: () => Cell[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L81) Returns an array of cells that account for column visibility for the row. #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/interfaces/Row_Core.md ================================================ --- id: Row_Core title: Row_Core --- # Interface: Row\_Core\ Defined in: [types/Row.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Row.ts#L21) ## Extends - [`Row_Row`](Row_Row.md)\<`TFeatures`, `TData`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_uniqueValuesCache ```ts _uniqueValuesCache: Record; ``` Defined in: [core/rows/coreRowsFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L11) #### Inherited from [`Row_Row`](Row_Row.md).[`_uniqueValuesCache`](Row_Row.md#_uniquevaluescache) *** ### \_valuesCache ```ts _valuesCache: Record; ``` Defined in: [core/rows/coreRowsFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L12) #### Inherited from [`Row_Row`](Row_Row.md).[`_valuesCache`](Row_Row.md#_valuescache) *** ### depth ```ts depth: number; ``` Defined in: [core/rows/coreRowsFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L16) The depth of the row (if nested or grouped) relative to the root row array. #### Inherited from [`Row_Row`](Row_Row.md).[`depth`](Row_Row.md#depth) *** ### getAllCells() ```ts getAllCells: () => Cell[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L55) Returns all of the cells for the row. #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] #### Inherited from [`Row_Row`](Row_Row.md).[`getAllCells`](Row_Row.md#getallcells) *** ### getAllCellsByColumnId() ```ts getAllCellsByColumnId: () => Record>; ``` Defined in: [core/rows/coreRowsFeature.types.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L51) #### Returns `Record`\<`string`, [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>\> #### Inherited from [`Row_Row`](Row_Row.md).[`getAllCellsByColumnId`](Row_Row.md#getallcellsbycolumnid) *** ### getLeafRows() ```ts getLeafRows: () => Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L59) Returns the leaf rows for the row, not including any parent rows. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] #### Inherited from [`Row_Row`](Row_Row.md).[`getLeafRows`](Row_Row.md#getleafrows) *** ### getParentRow() ```ts getParentRow: () => Row | undefined; ``` Defined in: [core/rows/coreRowsFeature.types.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L63) Returns the parent row for the row, if it exists. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> \| `undefined` #### Inherited from [`Row_Row`](Row_Row.md).[`getParentRow`](Row_Row.md#getparentrow) *** ### getParentRows() ```ts getParentRows: () => Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L67) Returns the parent rows for the row, all the way up to a root row. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] #### Inherited from [`Row_Row`](Row_Row.md).[`getParentRows`](Row_Row.md#getparentrows) *** ### getUniqueValues() ```ts getUniqueValues: (columnId) => TValue[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L71) Returns a unique array of values from the row for a given columnId. #### Type Parameters ##### TValue `TValue` #### Parameters ##### columnId `string` #### Returns `TValue`[] #### Inherited from [`Row_Row`](Row_Row.md).[`getUniqueValues`](Row_Row.md#getuniquevalues) *** ### getValue() ```ts getValue: (columnId) => TValue; ``` Defined in: [core/rows/coreRowsFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L75) Returns the value from the row for a given columnId. #### Type Parameters ##### TValue `TValue` #### Parameters ##### columnId `string` #### Returns `TValue` #### Inherited from [`Row_Row`](Row_Row.md).[`getValue`](Row_Row.md#getvalue) *** ### id ```ts id: string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L20) The resolved unique identifier for the row resolved via the `options.getRowId` option. Defaults to the row's index (or relative index if it is a subRow). #### Inherited from [`Row_Row`](Row_Row.md).[`id`](Row_Row.md#id) *** ### index ```ts index: number; ``` Defined in: [core/rows/coreRowsFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L24) The index of the row within its parent array (or the root data array). #### Inherited from [`Row_Row`](Row_Row.md).[`index`](Row_Row.md#index) *** ### original ```ts original: TData; ``` Defined in: [core/rows/coreRowsFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L28) The original row object provided to the table. If the row is a grouped row, the original row object will be the first original in the group. #### Inherited from [`Row_Row`](Row_Row.md).[`original`](Row_Row.md#original) *** ### originalSubRows? ```ts optional originalSubRows: readonly TData[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L32) An array of the original subRows as returned by the `options.getSubRows` option. #### Inherited from [`Row_Row`](Row_Row.md).[`originalSubRows`](Row_Row.md#originalsubrows) *** ### parentId? ```ts optional parentId: string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L36) If nested, this row's parent row id. #### Inherited from [`Row_Row`](Row_Row.md).[`parentId`](Row_Row.md#parentid) *** ### renderValue() ```ts renderValue: (columnId) => TValue; ``` Defined in: [core/rows/coreRowsFeature.types.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L79) Renders the value for the row in a given columnId the same as `getValue`, but will return the `renderFallbackValue` if no value is found. #### Type Parameters ##### TValue `TValue` #### Parameters ##### columnId `string` #### Returns `TValue` #### Inherited from [`Row_Row`](Row_Row.md).[`renderValue`](Row_Row.md#rendervalue) *** ### subRows ```ts subRows: Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L40) An array of subRows for the row as returned and created by the `options.getSubRows` option. #### Inherited from [`Row_Row`](Row_Row.md).[`subRows`](Row_Row.md#subrows) *** ### table ```ts table: Table_Internal; ``` Defined in: [core/rows/coreRowsFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L44) Reference to the parent table instance. #### Inherited from [`Row_Row`](Row_Row.md).[`table`](Row_Row.md#table) ================================================ FILE: docs/reference/interfaces/Row_CoreProperties.md ================================================ --- id: Row_CoreProperties title: Row_CoreProperties --- # Interface: Row\_CoreProperties\ Defined in: [core/rows/coreRowsFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L7) ## Extended by - [`Row_Row`](Row_Row.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_uniqueValuesCache ```ts _uniqueValuesCache: Record; ``` Defined in: [core/rows/coreRowsFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L11) *** ### \_valuesCache ```ts _valuesCache: Record; ``` Defined in: [core/rows/coreRowsFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L12) *** ### depth ```ts depth: number; ``` Defined in: [core/rows/coreRowsFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L16) The depth of the row (if nested or grouped) relative to the root row array. *** ### id ```ts id: string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L20) The resolved unique identifier for the row resolved via the `options.getRowId` option. Defaults to the row's index (or relative index if it is a subRow). *** ### index ```ts index: number; ``` Defined in: [core/rows/coreRowsFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L24) The index of the row within its parent array (or the root data array). *** ### original ```ts original: TData; ``` Defined in: [core/rows/coreRowsFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L28) The original row object provided to the table. If the row is a grouped row, the original row object will be the first original in the group. *** ### originalSubRows? ```ts optional originalSubRows: readonly TData[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L32) An array of the original subRows as returned by the `options.getSubRows` option. *** ### parentId? ```ts optional parentId: string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L36) If nested, this row's parent row id. *** ### subRows ```ts subRows: Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L40) An array of subRows for the row as returned and created by the `options.getSubRows` option. *** ### table ```ts table: Table_Internal; ``` Defined in: [core/rows/coreRowsFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L44) Reference to the parent table instance. ================================================ FILE: docs/reference/interfaces/Row_Plugins.md ================================================ --- id: Row_Plugins title: Row_Plugins --- # Interface: Row\_Plugins\ Defined in: [types/Row.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Row.ts#L16) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/Row_Row.md ================================================ --- id: Row_Row title: Row_Row --- # Interface: Row\_Row\ Defined in: [core/rows/coreRowsFeature.types.ts:47](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L47) ## Extends - [`Row_CoreProperties`](Row_CoreProperties.md)\<`TFeatures`, `TData`\> ## Extended by - [`Row_Core`](Row_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_uniqueValuesCache ```ts _uniqueValuesCache: Record; ``` Defined in: [core/rows/coreRowsFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L11) #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`_uniqueValuesCache`](Row_CoreProperties.md#_uniquevaluescache) *** ### \_valuesCache ```ts _valuesCache: Record; ``` Defined in: [core/rows/coreRowsFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L12) #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`_valuesCache`](Row_CoreProperties.md#_valuescache) *** ### depth ```ts depth: number; ``` Defined in: [core/rows/coreRowsFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L16) The depth of the row (if nested or grouped) relative to the root row array. #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`depth`](Row_CoreProperties.md#depth) *** ### getAllCells() ```ts getAllCells: () => Cell[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L55) Returns all of the cells for the row. #### Returns [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getAllCellsByColumnId() ```ts getAllCellsByColumnId: () => Record>; ``` Defined in: [core/rows/coreRowsFeature.types.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L51) #### Returns `Record`\<`string`, [`Cell`](../type-aliases/Cell.md)\<`TFeatures`, `TData`, `unknown`\>\> *** ### getLeafRows() ```ts getLeafRows: () => Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L59) Returns the leaf rows for the row, not including any parent rows. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] *** ### getParentRow() ```ts getParentRow: () => Row | undefined; ``` Defined in: [core/rows/coreRowsFeature.types.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L63) Returns the parent row for the row, if it exists. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> \| `undefined` *** ### getParentRows() ```ts getParentRows: () => Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L67) Returns the parent rows for the row, all the way up to a root row. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] *** ### getUniqueValues() ```ts getUniqueValues: (columnId) => TValue[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L71) Returns a unique array of values from the row for a given columnId. #### Type Parameters ##### TValue `TValue` #### Parameters ##### columnId `string` #### Returns `TValue`[] *** ### getValue() ```ts getValue: (columnId) => TValue; ``` Defined in: [core/rows/coreRowsFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L75) Returns the value from the row for a given columnId. #### Type Parameters ##### TValue `TValue` #### Parameters ##### columnId `string` #### Returns `TValue` *** ### id ```ts id: string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L20) The resolved unique identifier for the row resolved via the `options.getRowId` option. Defaults to the row's index (or relative index if it is a subRow). #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`id`](Row_CoreProperties.md#id) *** ### index ```ts index: number; ``` Defined in: [core/rows/coreRowsFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L24) The index of the row within its parent array (or the root data array). #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`index`](Row_CoreProperties.md#index) *** ### original ```ts original: TData; ``` Defined in: [core/rows/coreRowsFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L28) The original row object provided to the table. If the row is a grouped row, the original row object will be the first original in the group. #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`original`](Row_CoreProperties.md#original) *** ### originalSubRows? ```ts optional originalSubRows: readonly TData[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L32) An array of the original subRows as returned by the `options.getSubRows` option. #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`originalSubRows`](Row_CoreProperties.md#originalsubrows) *** ### parentId? ```ts optional parentId: string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L36) If nested, this row's parent row id. #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`parentId`](Row_CoreProperties.md#parentid) *** ### renderValue() ```ts renderValue: (columnId) => TValue; ``` Defined in: [core/rows/coreRowsFeature.types.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L79) Renders the value for the row in a given columnId the same as `getValue`, but will return the `renderFallbackValue` if no value is found. #### Type Parameters ##### TValue `TValue` #### Parameters ##### columnId `string` #### Returns `TValue` *** ### subRows ```ts subRows: Row[]; ``` Defined in: [core/rows/coreRowsFeature.types.ts:40](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L40) An array of subRows for the row as returned and created by the `options.getSubRows` option. #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`subRows`](Row_CoreProperties.md#subrows) *** ### table ```ts table: Table_Internal; ``` Defined in: [core/rows/coreRowsFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L44) Reference to the parent table instance. #### Inherited from [`Row_CoreProperties`](Row_CoreProperties.md).[`table`](Row_CoreProperties.md#table) ================================================ FILE: docs/reference/interfaces/Row_RowExpanding.md ================================================ --- id: Row_RowExpanding title: Row_RowExpanding --- # Interface: Row\_RowExpanding Defined in: [features/row-expanding/rowExpandingFeature.types.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L14) ## Properties ### getCanExpand() ```ts getCanExpand: () => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L18) Returns whether the row can be expanded. #### Returns `boolean` *** ### getIsAllParentsExpanded() ```ts getIsAllParentsExpanded: () => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L22) Returns whether all parent rows of the row are expanded. #### Returns `boolean` *** ### getIsExpanded() ```ts getIsExpanded: () => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L26) Returns whether the row is expanded. #### Returns `boolean` *** ### getToggleExpandedHandler() ```ts getToggleExpandedHandler: () => () => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L30) Returns a function that can be used to toggle the expanded state of the row. This function can be used to bind to an event handler to a button. #### Returns ```ts (): void; ``` ##### Returns `void` *** ### toggleExpanded() ```ts toggleExpanded: (expanded?) => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L34) Toggles the expanded state (or sets it if `expanded` is provided) for the row. #### Parameters ##### expanded? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Row_RowPinning.md ================================================ --- id: Row_RowPinning title: Row_RowPinning --- # Interface: Row\_RowPinning Defined in: [features/row-pinning/rowPinningFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L38) ## Properties ### getCanPin() ```ts getCanPin: () => boolean; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L42) Returns whether or not the row can be pinned. #### Returns `boolean` *** ### getIsPinned() ```ts getIsPinned: () => RowPinningPosition; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L46) Returns the pinned position of the row. (`'top'`, `'bottom'` or `false`) #### Returns [`RowPinningPosition`](../type-aliases/RowPinningPosition.md) *** ### getPinnedIndex() ```ts getPinnedIndex: () => number; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L50) Returns the numeric pinned index of the row within a pinned row group. #### Returns `number` *** ### pin() ```ts pin: (position, includeLeafRows?, includeParentRows?) => void; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L54) Pins a row to the `'top'` or `'bottom'`, or unpins the row to the center if `false` is passed. #### Parameters ##### position [`RowPinningPosition`](../type-aliases/RowPinningPosition.md) ##### includeLeafRows? `boolean` ##### includeParentRows? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Row_RowSelection.md ================================================ --- id: Row_RowSelection title: Row_RowSelection --- # Interface: Row\_RowSelection Defined in: [features/row-selection/rowSelectionFeature.types.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L48) ## Properties ### getCanMultiSelect() ```ts getCanMultiSelect: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L52) Returns whether or not the row can multi-select. #### Returns `boolean` *** ### getCanSelect() ```ts getCanSelect: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L56) Returns whether or not the row can be selected. #### Returns `boolean` *** ### getCanSelectSubRows() ```ts getCanSelectSubRows: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L60) Returns whether or not the row can select sub rows automatically when the parent row is selected. #### Returns `boolean` *** ### getIsAllSubRowsSelected() ```ts getIsAllSubRowsSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L64) Returns whether or not all of the row's sub rows are selected. #### Returns `boolean` *** ### getIsSelected() ```ts getIsSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L68) Returns whether or not the row is selected. #### Returns `boolean` *** ### getIsSomeSelected() ```ts getIsSomeSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L72) Returns whether or not some of the row's sub rows are selected. #### Returns `boolean` *** ### getToggleSelectedHandler() ```ts getToggleSelectedHandler: () => (event) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L76) Returns a handler that can be used to toggle the row. #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` *** ### toggleSelected() ```ts toggleSelected: (value?, opts?) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L80) Selects/deselects the row. #### Parameters ##### value? `boolean` ##### opts? ###### selectChildren? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/SortFn.md ================================================ --- id: SortFn title: SortFn --- # Interface: SortFn()\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L30) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ```ts SortFn( rowA, rowB, columnId): number; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L34) ## Parameters ### rowA [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### rowB [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> ### columnId `string` ## Returns `number` ================================================ FILE: docs/reference/interfaces/SortFns.md ================================================ --- id: SortFns title: SortFns --- # Interface: SortFns Defined in: [features/row-sorting/rowSortingFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L28) ================================================ FILE: docs/reference/interfaces/StockFeatures.md ================================================ --- id: StockFeatures title: StockFeatures --- # Interface: StockFeatures Defined in: [features/stockFeatures.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L16) ## Properties ### columnFacetingFeature ```ts columnFacetingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L17) *** ### columnFilteringFeature ```ts columnFilteringFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L18) *** ### columnGroupingFeature ```ts columnGroupingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L19) *** ### columnOrderingFeature ```ts columnOrderingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L20) *** ### columnPinningFeature ```ts columnPinningFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L21) *** ### columnResizingFeature ```ts columnResizingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L22) *** ### columnSizingFeature ```ts columnSizingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L23) *** ### columnVisibilityFeature ```ts columnVisibilityFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L24) *** ### globalFilteringFeature ```ts globalFilteringFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L25) *** ### rowExpandingFeature ```ts rowExpandingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L26) *** ### rowPaginationFeature ```ts rowPaginationFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L27) *** ### rowPinningFeature ```ts rowPinningFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L28) *** ### rowSelectionFeature ```ts rowSelectionFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L29) *** ### rowSortingFeature ```ts rowSortingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L30) ================================================ FILE: docs/reference/interfaces/StringHeaderIdentifier.md ================================================ --- id: StringHeaderIdentifier title: StringHeaderIdentifier --- # Interface: StringHeaderIdentifier Defined in: [types/ColumnDef.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L45) ## Properties ### header ```ts header: string; ``` Defined in: [types/ColumnDef.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L46) *** ### id? ```ts optional id: string; ``` Defined in: [types/ColumnDef.ts:47](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L47) ================================================ FILE: docs/reference/interfaces/TableFeature.md ================================================ --- id: TableFeature title: TableFeature --- # Interface: TableFeature\ Defined in: [types/TableFeatures.ts:116](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L116) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Properties ### assignCellPrototype? ```ts optional assignCellPrototype: AssignCellPrototype; ``` Defined in: [types/TableFeatures.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L121) Assigns Cell APIs to the cell prototype for memory-efficient method sharing. This is called once per table to build a shared prototype for all cells. *** ### assignColumnPrototype? ```ts optional assignColumnPrototype: AssignColumnPrototype; ``` Defined in: [types/TableFeatures.ts:126](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L126) Assigns Column APIs to the column prototype for memory-efficient method sharing. This is called once per table to build a shared prototype for all columns. *** ### assignHeaderPrototype? ```ts optional assignHeaderPrototype: AssignHeaderPrototype; ``` Defined in: [types/TableFeatures.ts:131](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L131) Assigns Header APIs to the header prototype for memory-efficient method sharing. This is called once per table to build a shared prototype for all headers. *** ### assignRowPrototype? ```ts optional assignRowPrototype: AssignRowPrototype; ``` Defined in: [types/TableFeatures.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L136) Assigns Row APIs to the row prototype for memory-efficient method sharing. This is called once per table to build a shared prototype for all rows. *** ### constructTableAPIs? ```ts optional constructTableAPIs: ConstructTableAPIs; ``` Defined in: [types/TableFeatures.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L141) Assigns Table APIs to the table instance. Unlike row/cell/column/header, the table is a singleton so methods are assigned directly. *** ### getDefaultColumnDef? ```ts optional getDefaultColumnDef: GetDefaultColumnDef; ``` Defined in: [types/TableFeatures.ts:142](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L142) *** ### getDefaultTableOptions? ```ts optional getDefaultTableOptions: GetDefaultTableOptions; ``` Defined in: [types/TableFeatures.ts:143](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L143) *** ### getInitialState? ```ts optional getInitialState: GetInitialState; ``` Defined in: [types/TableFeatures.ts:144](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L144) *** ### initRowInstanceData? ```ts optional initRowInstanceData: InitRowInstanceData; ``` Defined in: [types/TableFeatures.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L149) Initializes instance-specific data on each row (e.g., caches). Methods should be assigned via assignRowPrototype instead. ================================================ FILE: docs/reference/interfaces/TableFeatures.md ================================================ --- id: TableFeatures title: TableFeatures --- # Interface: TableFeatures Defined in: [types/TableFeatures.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L42) ## Extends - `Partial`\<[`CoreFeatures`](CoreFeatures.md)\>.`Partial`\<[`StockFeatures`](StockFeatures.md)\>.`Partial`\<[`Plugins`](Plugins.md)\> ## Properties ### columnFacetingFeature? ```ts optional columnFacetingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L17) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnFacetingFeature`](StockFeatures.md#columnfacetingfeature) *** ### columnFilteringFeature? ```ts optional columnFilteringFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L18) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnFilteringFeature`](StockFeatures.md#columnfilteringfeature) *** ### columnGroupingFeature? ```ts optional columnGroupingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L19) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnGroupingFeature`](StockFeatures.md#columngroupingfeature) *** ### columnOrderingFeature? ```ts optional columnOrderingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L20) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnOrderingFeature`](StockFeatures.md#columnorderingfeature) *** ### columnPinningFeature? ```ts optional columnPinningFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L21) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnPinningFeature`](StockFeatures.md#columnpinningfeature) *** ### columnResizingFeature? ```ts optional columnResizingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L22) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnResizingFeature`](StockFeatures.md#columnresizingfeature) *** ### columnSizingFeature? ```ts optional columnSizingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L23) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnSizingFeature`](StockFeatures.md#columnsizingfeature) *** ### columnVisibilityFeature? ```ts optional columnVisibilityFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L24) #### Inherited from [`StockFeatures`](StockFeatures.md).[`columnVisibilityFeature`](StockFeatures.md#columnvisibilityfeature) *** ### coreCellsFeature? ```ts optional coreCellsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L9) #### Inherited from [`CoreFeatures`](CoreFeatures.md).[`coreCellsFeature`](CoreFeatures.md#corecellsfeature) *** ### coreColumnsFeature? ```ts optional coreColumnsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L10) #### Inherited from [`CoreFeatures`](CoreFeatures.md).[`coreColumnsFeature`](CoreFeatures.md#corecolumnsfeature) *** ### coreHeadersFeature? ```ts optional coreHeadersFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L11) #### Inherited from [`CoreFeatures`](CoreFeatures.md).[`coreHeadersFeature`](CoreFeatures.md#coreheadersfeature) *** ### coreRowModelsFeature? ```ts optional coreRowModelsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L12) #### Inherited from [`CoreFeatures`](CoreFeatures.md).[`coreRowModelsFeature`](CoreFeatures.md#corerowmodelsfeature) *** ### coreRowsFeature? ```ts optional coreRowsFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L13) #### Inherited from [`CoreFeatures`](CoreFeatures.md).[`coreRowsFeature`](CoreFeatures.md#corerowsfeature) *** ### coreTablesFeature? ```ts optional coreTablesFeature: TableFeature>; ``` Defined in: [core/coreFeatures.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L14) #### Inherited from [`CoreFeatures`](CoreFeatures.md).[`coreTablesFeature`](CoreFeatures.md#coretablesfeature) *** ### globalFilteringFeature? ```ts optional globalFilteringFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L25) #### Inherited from [`StockFeatures`](StockFeatures.md).[`globalFilteringFeature`](StockFeatures.md#globalfilteringfeature) *** ### rowExpandingFeature? ```ts optional rowExpandingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L26) #### Inherited from [`StockFeatures`](StockFeatures.md).[`rowExpandingFeature`](StockFeatures.md#rowexpandingfeature) *** ### rowPaginationFeature? ```ts optional rowPaginationFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L27) #### Inherited from [`StockFeatures`](StockFeatures.md).[`rowPaginationFeature`](StockFeatures.md#rowpaginationfeature) *** ### rowPinningFeature? ```ts optional rowPinningFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L28) #### Inherited from [`StockFeatures`](StockFeatures.md).[`rowPinningFeature`](StockFeatures.md#rowpinningfeature) *** ### rowSelectionFeature? ```ts optional rowSelectionFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L29) #### Inherited from [`StockFeatures`](StockFeatures.md).[`rowSelectionFeature`](StockFeatures.md#rowselectionfeature) *** ### rowSortingFeature? ```ts optional rowSortingFeature: TableFeature>; ``` Defined in: [features/stockFeatures.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L30) #### Inherited from [`StockFeatures`](StockFeatures.md).[`rowSortingFeature`](StockFeatures.md#rowsortingfeature) ================================================ FILE: docs/reference/interfaces/TableMeta.md ================================================ --- id: TableMeta title: TableMeta --- # Interface: TableMeta\ Defined in: [core/table/coreTablesFeature.types.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L10) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/TableOptions_Cell.md ================================================ --- id: TableOptions_Cell title: TableOptions_Cell --- # Interface: TableOptions\_Cell Defined in: [core/cells/coreCellsFeature.types.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L63) ## Extended by - [`TableOptions_Core`](TableOptions_Core.md) ## Properties ### renderFallbackValue? ```ts optional renderFallbackValue: any; ``` Defined in: [core/cells/coreCellsFeature.types.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L67) Value used when the desired value is not found in the data. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnFiltering.md ================================================ --- id: TableOptions_ColumnFiltering title: TableOptions_ColumnFiltering --- # Interface: TableOptions\_ColumnFiltering\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:143](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L143) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### enableColumnFilters? ```ts optional enableColumnFilters: boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:150](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L150) Enables/disables **column** filtering for all columns. *** ### enableFilters? ```ts optional enableFilters: boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:154](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L154) Enables/disables all filtering for the table. *** ### filterFromLeafRows? ```ts optional filterFromLeafRows: boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:158](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L158) By default, filtering is done from parent rows down (so if a parent row is filtered out, all of its children will be filtered out as well). Setting this option to `true` will cause filtering to be done from leaf rows up (which means parent rows will be included so long as one of their child or grand-child rows is also included). *** ### manualFiltering? ```ts optional manualFiltering: boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:162](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L162) Disables the `getFilteredRowModel` from being used to filter data. This may be useful if your table needs to dynamically support both client-side and server-side filtering. *** ### maxLeafRowFilterDepth? ```ts optional maxLeafRowFilterDepth: number; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:168](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L168) By default, filtering is done for all rows (max depth of 100), no matter if they are root level parent rows or the child leaf rows of a parent row. Setting this option to `0` will cause filtering to only be applied to the root level parent rows, with all sub-rows remaining unfiltered. Similarly, setting this option to `1` will cause filtering to only be applied to child leaf rows 1 level deep, and so on. This is useful for situations where you want a row's entire child hierarchy to be visible regardless of the applied filter. *** ### onColumnFiltersChange? ```ts optional onColumnFiltersChange: OnChangeFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:172](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L172) If provided, this function will be called with an `updaterFn` when `state.columnFilters` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnGrouping.md ================================================ --- id: TableOptions_ColumnGrouping title: TableOptions_ColumnGrouping --- # Interface: TableOptions\_ColumnGrouping Defined in: [features/column-grouping/columnGroupingFeature.types.ts:152](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L152) ## Properties ### enableGrouping? ```ts optional enableGrouping: boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L156) Enables/disables grouping for the table. *** ### groupedColumnMode? ```ts optional groupedColumnMode: false | "reorder" | "remove"; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:160](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L160) Grouping columns are automatically reordered by default to the start of the columns list. If you would rather remove them or leave them as-is, set the appropriate mode here. *** ### manualGrouping? ```ts optional manualGrouping: boolean; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:164](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L164) Enables manual grouping. If this option is set to `true`, the table will not automatically group rows using `getGroupedRowModel()` and instead will expect you to manually group the rows before passing them to the table. This is useful if you are doing server-side grouping and aggregation. *** ### onGroupingChange? ```ts optional onGroupingChange: OnChangeFn; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:168](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L168) If this function is provided, it will be called when the grouping state changes and you will be expected to manage the state yourself. You can pass the managed state back to the table via the `tableOptions.state.grouping` option. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnOrdering.md ================================================ --- id: TableOptions_ColumnOrdering title: TableOptions_ColumnOrdering --- # Interface: TableOptions\_ColumnOrdering Defined in: [features/column-ordering/columnOrderingFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L11) ## Properties ### onColumnOrderChange? ```ts optional onColumnOrderChange: OnChangeFn; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L15) If provided, this function will be called with an `updaterFn` when `state.columnOrder` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnPinning.md ================================================ --- id: TableOptions_ColumnPinning title: TableOptions_ColumnPinning --- # Interface: TableOptions\_ColumnPinning Defined in: [features/column-pinning/columnPinningFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L19) ## Properties ### enableColumnPinning? ```ts optional enableColumnPinning: boolean; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L23) Enables/disables column pinning for the table. Defaults to `true`. *** ### onColumnPinningChange? ```ts optional onColumnPinningChange: OnChangeFn; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L27) If provided, this function will be called with an `updaterFn` when `state.columnPinning` changes. This overrides the default internal state management, so you will also need to supply `state.columnPinning` from your own managed state. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnResizing.md ================================================ --- id: TableOptions_ColumnResizing title: TableOptions_ColumnResizing --- # Interface: TableOptions\_ColumnResizing Defined in: [features/column-resizing/columnResizingFeature.types.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L20) ## Properties ### columnResizeDirection? ```ts optional columnResizeDirection: ColumnResizeDirection; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L32) Enables or disables right-to-left support for resizing the column. defaults to 'ltr'. *** ### columnResizeMode? ```ts optional columnResizeMode: ColumnResizeMode; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L24) Determines when the columnSizing state is updated. `onChange` updates the state when the user is dragging the resize handle. `onEnd` updates the state when the user releases the resize handle. *** ### enableColumnResizing? ```ts optional enableColumnResizing: boolean; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L28) Enables or disables column resizing for the column. *** ### onColumnResizingChange? ```ts optional onColumnResizingChange: OnChangeFn; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L36) If provided, this function will be called with an `updaterFn` when `state.columnResizing` changes. This overrides the default internal state management, so you will also need to supply `state.columnResizing` from your own managed state. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnSizing.md ================================================ --- id: TableOptions_ColumnSizing title: TableOptions_ColumnSizing --- # Interface: TableOptions\_ColumnSizing Defined in: [features/column-sizing/columnSizingFeature.types.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L10) ## Properties ### onColumnSizingChange? ```ts optional onColumnSizingChange: OnChangeFn; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L14) If provided, this function will be called with an `updaterFn` when `state.columnSizing` changes. This overrides the default internal state management, so you will also need to supply `state.columnSizing` from your own managed state. ================================================ FILE: docs/reference/interfaces/TableOptions_ColumnVisibility.md ================================================ --- id: TableOptions_ColumnVisibility title: TableOptions_ColumnVisibility --- # Interface: TableOptions\_ColumnVisibility Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L12) ## Properties ### enableHiding? ```ts optional enableHiding: boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L16) Whether to enable column hiding. Defaults to `true`. *** ### onColumnVisibilityChange? ```ts optional onColumnVisibilityChange: OnChangeFn; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L20) If provided, this function will be called with an `updaterFn` when `state.columnVisibility` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. ================================================ FILE: docs/reference/interfaces/TableOptions_Columns.md ================================================ --- id: TableOptions_Columns title: TableOptions_Columns --- # Interface: TableOptions\_Columns\ Defined in: [core/columns/coreColumnsFeature.types.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L60) ## Extended by - [`TableOptions_Core`](TableOptions_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ### TValue `TValue` *extends* [`CellData`](../type-aliases/CellData.md) = [`CellData`](../type-aliases/CellData.md) ## Properties ### columns ```ts columns: readonly ColumnDef[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L68) The array of column defs to use for the table. *** ### defaultColumn? ```ts optional defaultColumn: Partial>; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L72) Default column options to use for all column defs supplied to the table. ================================================ FILE: docs/reference/interfaces/TableOptions_Core.md ================================================ --- id: TableOptions_Core title: TableOptions_Core --- # Interface: TableOptions\_Core\ Defined in: [types/TableOptions.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableOptions.ts#L27) ## Extends - [`TableOptions_Table`](TableOptions_Table.md)\<`TFeatures`, `TData`\>.[`TableOptions_Cell`](TableOptions_Cell.md).[`TableOptions_Columns`](TableOptions_Columns.md)\<`TFeatures`, `TData`\>.[`TableOptions_Rows`](TableOptions_Rows.md)\<`TFeatures`, `TData`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_features ```ts _features: TFeatures; ``` Defined in: [core/table/coreTablesFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L22) The features that you want to enable for the table. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`_features`](TableOptions_Table.md#_features) *** ### \_rowModels? ```ts optional _rowModels: CreateRowModels_All; ``` Defined in: [core/table/coreTablesFeature.types.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L26) The row model options that you want to enable for the table. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`_rowModels`](TableOptions_Table.md#_rowmodels) *** ### autoResetAll? ```ts optional autoResetAll: boolean; ``` Defined in: [core/table/coreTablesFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L30) Set this option to override any of the `autoReset...` feature options. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`autoResetAll`](TableOptions_Table.md#autoresetall) *** ### columns ```ts columns: readonly ColumnDef[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L68) The array of column defs to use for the table. #### Inherited from [`TableOptions_Columns`](TableOptions_Columns.md).[`columns`](TableOptions_Columns.md#columns) *** ### data ```ts data: readonly TData[]; ``` Defined in: [core/table/coreTablesFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L34) The data for the table to display. When the `data` option changes reference, the table will reprocess the data. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`data`](TableOptions_Table.md#data) *** ### defaultColumn? ```ts optional defaultColumn: Partial>; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L72) Default column options to use for all column defs supplied to the table. #### Inherited from [`TableOptions_Columns`](TableOptions_Columns.md).[`defaultColumn`](TableOptions_Columns.md#defaultcolumn) *** ### getRowId()? ```ts optional getRowId: (originalRow, index, parent?) => string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L90) This optional function is used to derive a unique ID for any given row. If not provided the rows index is used (nested rows join together with `.` using their grandparents' index eg. `index.index.index`). If you need to identify individual rows that are originating from any server-side operations, it's suggested you use this function to return an ID that makes sense regardless of network IO/ambiguity eg. a userId, taskId, database ID field, etc. #### Parameters ##### originalRow `TData` ##### index `number` ##### parent? [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> #### Returns `string` #### Example ```ts getRowId: row => row.userId ``` #### Inherited from [`TableOptions_Rows`](TableOptions_Rows.md).[`getRowId`](TableOptions_Rows.md#getrowid) *** ### getSubRows()? ```ts optional getSubRows: (originalRow, index) => readonly TData[] | undefined; ``` Defined in: [core/rows/coreRowsFeature.types.ts:99](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L99) This optional function is used to access the sub rows for any given row. If you are using nested rows, you will need to use this function to return the sub rows object (or undefined) from the row. #### Parameters ##### originalRow `TData` ##### index `number` #### Returns readonly `TData`[] \| `undefined` #### Example ```ts getSubRows: row => row.subRows ``` #### Inherited from [`TableOptions_Rows`](TableOptions_Rows.md).[`getSubRows`](TableOptions_Rows.md#getsubrows) *** ### initialState? ```ts optional initialState: Partial>; ``` Defined in: [core/table/coreTablesFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L39) Use this option to optionally pass initial state to the table. This state will be used when resetting various table states either automatically by the table (eg. `options.autoResetPageIndex`) or via functions like `table.resetRowSelection()`. Most reset function allow you optionally pass a flag to reset to a blank/default state instead of the initial state. Table state will not be reset when this object changes, which also means that the initial state object does not need to be stable. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`initialState`](TableOptions_Table.md#initialstate) *** ### mergeOptions()? ```ts optional mergeOptions: (defaultOptions, options) => TableOptions; ``` Defined in: [core/table/coreTablesFeature.types.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L43) This option is used to optionally implement the merging of table options. #### Parameters ##### defaultOptions [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ##### options `Partial`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>\> #### Returns [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`mergeOptions`](TableOptions_Table.md#mergeoptions) *** ### meta? ```ts optional meta: TableMeta; ``` Defined in: [core/table/coreTablesFeature.types.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L50) You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`meta`](TableOptions_Table.md#meta) *** ### renderFallbackValue? ```ts optional renderFallbackValue: any; ``` Defined in: [core/cells/coreCellsFeature.types.ts:67](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.types.ts#L67) Value used when the desired value is not found in the data. #### Inherited from [`TableOptions_Cell`](TableOptions_Cell.md).[`renderFallbackValue`](TableOptions_Cell.md#renderfallbackvalue) *** ### state? ```ts optional state: Partial>; ``` Defined in: [core/table/coreTablesFeature.types.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L54) Pass in individual self-managed state to the table. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`state`](TableOptions_Table.md#state) *** ### store? ```ts optional store: Store>; ``` Defined in: [core/table/coreTablesFeature.types.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L58) Optionally, provide your own external TanStack Store instance if you want to manage the table state externally. #### Inherited from [`TableOptions_Table`](TableOptions_Table.md).[`store`](TableOptions_Table.md#store) ================================================ FILE: docs/reference/interfaces/TableOptions_GlobalFiltering.md ================================================ --- id: TableOptions_GlobalFiltering title: TableOptions_GlobalFiltering --- # Interface: TableOptions\_GlobalFiltering\ Defined in: [features/global-filtering/globalFilteringFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L32) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### enableGlobalFilter? ```ts optional enableGlobalFilter: boolean; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L39) Enables/disables **global** filtering for all columns. *** ### getColumnCanGlobalFilter()? ```ts optional getColumnCanGlobalFilter: (column) => boolean; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L44) If provided, this function will be called with the column and should return `true` or `false` to indicate whether this column should be used for global filtering. This is useful if the column can contain data that is not `string` or `number` (i.e. `undefined`). #### Type Parameters ##### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ##### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ##### TValue `TValue` *extends* `unknown` = `unknown` #### Parameters ##### column [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `TValue`\> #### Returns `boolean` *** ### globalFilterFn? ```ts optional globalFilterFn: FilterFnOption; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L57) The filter function to use for global filtering. - A `string` referencing a built-in filter function - A `string` that references a custom filter functions provided via the `tableOptions.filterFns` option - A custom filter function *** ### onGlobalFilterChange? ```ts optional onGlobalFilterChange: OnChangeFn; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L61) If provided, this function will be called with an `updaterFn` when `state.globalFilter` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. ================================================ FILE: docs/reference/interfaces/TableOptions_Plugins.md ================================================ --- id: TableOptions_Plugins title: TableOptions_Plugins --- # Interface: TableOptions\_Plugins\ Defined in: [types/TableOptions.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableOptions.ts#L22) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/TableOptions_RowExpanding.md ================================================ --- id: TableOptions_RowExpanding title: TableOptions_RowExpanding --- # Interface: TableOptions\_RowExpanding\ Defined in: [features/row-expanding/rowExpandingFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L37) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### autoResetExpanded? ```ts optional autoResetExpanded: boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L44) Enable this setting to automatically reset the expanded state of the table when expanding state changes. *** ### enableExpanding? ```ts optional enableExpanding: boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L48) Enable/disable expanding for all rows. *** ### getIsRowExpanded()? ```ts optional getIsRowExpanded: (row) => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L52) If provided, allows you to override the default behavior of determining whether a row is currently expanded. #### Parameters ##### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> #### Returns `boolean` *** ### getRowCanExpand()? ```ts optional getRowCanExpand: (row) => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L56) If provided, allows you to override the default behavior of determining whether a row can be expanded. #### Parameters ##### row [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> #### Returns `boolean` *** ### manualExpanding? ```ts optional manualExpanding: boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:60](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L60) Enables manual row expansion. If this is set to `true`, `getExpandedRowModel` will not be used to expand rows and you would be expected to perform the expansion in your own data model. This is useful if you are doing server-side expansion. *** ### onExpandedChange? ```ts optional onExpandedChange: OnChangeFn; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L64) This function is called when the `expanded` table state changes. If a function is provided, you will be responsible for managing this state on your own. To pass the managed state back to the table, use the `tableOptions.state.expanded` option. *** ### paginateExpandedRows? ```ts optional paginateExpandedRows: boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L68) If `true` expanded rows will be paginated along with the rest of the table (which means expanded rows may span multiple pages). If `false` expanded rows will not be considered for pagination (which means expanded rows will always render on their parents page. This also means more rows will be rendered than the set page size) ================================================ FILE: docs/reference/interfaces/TableOptions_RowPagination.md ================================================ --- id: TableOptions_RowPagination title: TableOptions_RowPagination --- # Interface: TableOptions\_RowPagination Defined in: [features/row-pagination/rowPaginationFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L15) ## Properties ### autoResetPageIndex? ```ts optional autoResetPageIndex: boolean; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L19) If set to `true`, pagination will be reset to the first page when page-altering state changes eg. `data` is updated, filters change, grouping changes, etc. *** ### manualPagination? ```ts optional manualPagination: boolean; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L23) Enables manual pagination. If this option is set to `true`, the table will not automatically paginate rows using `getPaginatedRowModel()` and instead will expect you to manually paginate the rows before passing them to the table. This is useful if you are doing server-side pagination and aggregation. *** ### onPaginationChange? ```ts optional onPaginationChange: OnChangeFn; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L27) If this function is provided, it will be called when the pagination state changes and you will be expected to manage the state yourself. You can pass the managed state back to the table via the `tableOptions.state.pagination` option. *** ### pageCount? ```ts optional pageCount: number; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L31) When manually controlling pagination, you can supply a total `pageCount` value to the table if you know it (Or supply a `rowCount` and `pageCount` will be calculated). If you do not know how many pages there are, you can set this to `-1`. *** ### rowCount? ```ts optional rowCount: number; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L35) When manually controlling pagination, you can supply a total `rowCount` value to the table if you know it. The `pageCount` can be calculated from this value and the `pageSize`. ================================================ FILE: docs/reference/interfaces/TableOptions_RowPinning.md ================================================ --- id: TableOptions_RowPinning title: TableOptions_RowPinning --- # Interface: TableOptions\_RowPinning\ Defined in: [features/row-pinning/rowPinningFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L16) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### enableRowPinning? ```ts optional enableRowPinning: boolean | (row) => boolean; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L23) Enables/disables row pinning for the table. Defaults to `true`. *** ### keepPinnedRows? ```ts optional keepPinnedRows: boolean; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L27) When `false`, pinned rows will not be visible if they are filtered or paginated out of the table. When `true`, pinned rows will always be visible regardless of filtering or pagination. Defaults to `true`. *** ### onRowPinningChange? ```ts optional onRowPinningChange: OnChangeFn; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:31](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L31) If provided, this function will be called with an `updaterFn` when `state.rowPinning` changes. This overrides the default internal state management, so you will also need to supply `state.rowPinning` from your own managed state. ================================================ FILE: docs/reference/interfaces/TableOptions_RowSelection.md ================================================ --- id: TableOptions_RowSelection title: TableOptions_RowSelection --- # Interface: TableOptions\_RowSelection\ Defined in: [features/row-selection/rowSelectionFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L12) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### enableMultiRowSelection? ```ts optional enableMultiRowSelection: boolean | (row) => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:20](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L20) - Enables/disables multiple row selection for all rows in the table OR - A function that given a row, returns whether to enable/disable multiple row selection for that row's children/grandchildren *** ### enableRowSelection? ```ts optional enableRowSelection: boolean | (row) => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L25) - Enables/disables row selection for all rows in the table OR - A function that given a row, returns whether to enable/disable row selection for that row *** ### enableSubRowSelection? ```ts optional enableSubRowSelection: boolean | (row) => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L30) Enables/disables automatic sub-row selection when a parent row is selected, or a function that enables/disables automatic sub-row selection for each row. (Use in combination with expanding or grouping features) *** ### onRowSelectionChange? ```ts optional onRowSelectionChange: OnChangeFn; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L34) If provided, this function will be called with an `updaterFn` when `state.rowSelection` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. ================================================ FILE: docs/reference/interfaces/TableOptions_RowSorting.md ================================================ --- id: TableOptions_RowSorting title: TableOptions_RowSorting --- # Interface: TableOptions\_RowSorting Defined in: [features/row-sorting/rowSortingFeature.types.ts:143](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L143) ## Properties ### enableMultiRemove? ```ts optional enableMultiRemove: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:147](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L147) Enables/disables the ability to remove multi-sorts *** ### enableMultiSort? ```ts optional enableMultiSort: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:151](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L151) Enables/Disables multi-sorting for the table. *** ### enableSorting? ```ts optional enableSorting: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:155](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L155) Enables/Disables sorting for the table. *** ### enableSortingRemoval? ```ts optional enableSortingRemoval: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:161](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L161) Enables/Disables the ability to remove sorting for the table. - If `true` then changing sort order will circle like: 'none' -> 'desc' -> 'asc' -> 'none' -> ... - If `false` then changing sort order will circle like: 'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ... *** ### isMultiSortEvent()? ```ts optional isMultiSortEvent: (e) => boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:165](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L165) Pass a custom function that will be used to determine if a multi-sort event should be triggered. It is passed the event from the sort toggle handler and should return `true` if the event should trigger a multi-sort. #### Parameters ##### e `unknown` #### Returns `boolean` *** ### manualSorting? ```ts optional manualSorting: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:169](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L169) Enables manual sorting for the table. If this is `true`, you will be expected to sort your data before it is passed to the table. This is useful if you are doing server-side sorting. *** ### maxMultiSortColCount? ```ts optional maxMultiSortColCount: number; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L173) Set a maximum number of columns that can be multi-sorted. *** ### onSortingChange? ```ts optional onSortingChange: OnChangeFn; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:177](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L177) If provided, this function will be called with an `updaterFn` when `state.sorting` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. *** ### sortDescFirst? ```ts optional sortDescFirst: boolean; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:181](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L181) If `true`, all sorts will default to descending as their first toggle state. ================================================ FILE: docs/reference/interfaces/TableOptions_Rows.md ================================================ --- id: TableOptions_Rows title: TableOptions_Rows --- # Interface: TableOptions\_Rows\ Defined in: [core/rows/coreRowsFeature.types.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L82) ## Extended by - [`TableOptions_Core`](TableOptions_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getRowId()? ```ts optional getRowId: (originalRow, index, parent?) => string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L90) This optional function is used to derive a unique ID for any given row. If not provided the rows index is used (nested rows join together with `.` using their grandparents' index eg. `index.index.index`). If you need to identify individual rows that are originating from any server-side operations, it's suggested you use this function to return an ID that makes sense regardless of network IO/ambiguity eg. a userId, taskId, database ID field, etc. #### Parameters ##### originalRow `TData` ##### index `number` ##### parent? [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> #### Returns `string` #### Example ```ts getRowId: row => row.userId ``` *** ### getSubRows()? ```ts optional getSubRows: (originalRow, index) => readonly TData[] | undefined; ``` Defined in: [core/rows/coreRowsFeature.types.ts:99](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L99) This optional function is used to access the sub rows for any given row. If you are using nested rows, you will need to use this function to return the sub rows object (or undefined) from the row. #### Parameters ##### originalRow `TData` ##### index `number` #### Returns readonly `TData`[] \| `undefined` #### Example ```ts getSubRows: row => row.subRows ``` ================================================ FILE: docs/reference/interfaces/TableOptions_Table.md ================================================ --- id: TableOptions_Table title: TableOptions_Table --- # Interface: TableOptions\_Table\ Defined in: [core/table/coreTablesFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L15) ## Extended by - [`TableOptions_Core`](TableOptions_Core.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_features ```ts _features: TFeatures; ``` Defined in: [core/table/coreTablesFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L22) The features that you want to enable for the table. *** ### \_rowModels? ```ts optional _rowModels: CreateRowModels_All; ``` Defined in: [core/table/coreTablesFeature.types.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L26) The row model options that you want to enable for the table. *** ### autoResetAll? ```ts optional autoResetAll: boolean; ``` Defined in: [core/table/coreTablesFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L30) Set this option to override any of the `autoReset...` feature options. *** ### data ```ts data: readonly TData[]; ``` Defined in: [core/table/coreTablesFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L34) The data for the table to display. When the `data` option changes reference, the table will reprocess the data. *** ### initialState? ```ts optional initialState: Partial>; ``` Defined in: [core/table/coreTablesFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L39) Use this option to optionally pass initial state to the table. This state will be used when resetting various table states either automatically by the table (eg. `options.autoResetPageIndex`) or via functions like `table.resetRowSelection()`. Most reset function allow you optionally pass a flag to reset to a blank/default state instead of the initial state. Table state will not be reset when this object changes, which also means that the initial state object does not need to be stable. *** ### mergeOptions()? ```ts optional mergeOptions: (defaultOptions, options) => TableOptions; ``` Defined in: [core/table/coreTablesFeature.types.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L43) This option is used to optionally implement the merging of table options. #### Parameters ##### defaultOptions [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> ##### options `Partial`\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>\> #### Returns [`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\> *** ### meta? ```ts optional meta: TableMeta; ``` Defined in: [core/table/coreTablesFeature.types.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L50) You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`. *** ### state? ```ts optional state: Partial>; ``` Defined in: [core/table/coreTablesFeature.types.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L54) Pass in individual self-managed state to the table. *** ### store? ```ts optional store: Store>; ``` Defined in: [core/table/coreTablesFeature.types.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L58) Optionally, provide your own external TanStack Store instance if you want to manage the table state externally. ================================================ FILE: docs/reference/interfaces/TableState_ColumnFiltering.md ================================================ --- id: TableState_ColumnFiltering title: TableState_ColumnFiltering --- # Interface: TableState\_ColumnFiltering Defined in: [features/column-filtering/columnFilteringFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L18) ## Properties ### columnFilters ```ts columnFilters: ColumnFiltersState; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L19) ================================================ FILE: docs/reference/interfaces/TableState_ColumnGrouping.md ================================================ --- id: TableState_ColumnGrouping title: TableState_ColumnGrouping --- # Interface: TableState\_ColumnGrouping Defined in: [features/column-grouping/columnGroupingFeature.types.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L17) ## Properties ### grouping ```ts grouping: GroupingState; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L18) ================================================ FILE: docs/reference/interfaces/TableState_ColumnOrdering.md ================================================ --- id: TableState_ColumnOrdering title: TableState_ColumnOrdering --- # Interface: TableState\_ColumnOrdering Defined in: [features/column-ordering/columnOrderingFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L7) ## Properties ### columnOrder ```ts columnOrder: ColumnOrderState; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L8) ================================================ FILE: docs/reference/interfaces/TableState_ColumnPinning.md ================================================ --- id: TableState_ColumnPinning title: TableState_ColumnPinning --- # Interface: TableState\_ColumnPinning Defined in: [features/column-pinning/columnPinningFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L15) ## Properties ### columnPinning ```ts columnPinning: ColumnPinningState; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L16) ================================================ FILE: docs/reference/interfaces/TableState_ColumnResizing.md ================================================ --- id: TableState_ColumnResizing title: TableState_ColumnResizing --- # Interface: TableState\_ColumnResizing Defined in: [features/column-resizing/columnResizingFeature.types.ts:3](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L3) ## Properties ### columnResizing ```ts columnResizing: columnResizingState; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:4](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L4) ================================================ FILE: docs/reference/interfaces/TableState_ColumnSizing.md ================================================ --- id: TableState_ColumnSizing title: TableState_ColumnSizing --- # Interface: TableState\_ColumnSizing Defined in: [features/column-sizing/columnSizingFeature.types.ts:4](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L4) ## Properties ### columnSizing ```ts columnSizing: ColumnSizingState; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:5](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L5) ================================================ FILE: docs/reference/interfaces/TableState_ColumnVisibility.md ================================================ --- id: TableState_ColumnVisibility title: TableState_ColumnVisibility --- # Interface: TableState\_ColumnVisibility Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L8) ## Properties ### columnVisibility ```ts columnVisibility: ColumnVisibilityState; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L9) ================================================ FILE: docs/reference/interfaces/TableState_GlobalFiltering.md ================================================ --- id: TableState_GlobalFiltering title: TableState_GlobalFiltering --- # Interface: TableState\_GlobalFiltering Defined in: [features/global-filtering/globalFilteringFeature.types.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L14) ## Properties ### globalFilter ```ts globalFilter: any; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L15) ================================================ FILE: docs/reference/interfaces/TableState_Plugins.md ================================================ --- id: TableState_Plugins title: TableState_Plugins --- # Interface: TableState\_Plugins\ Defined in: [types/TableState.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableState.ts#L21) Use this interface as a target for declaration merging to add your own state properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ================================================ FILE: docs/reference/interfaces/TableState_RowExpanding.md ================================================ --- id: TableState_RowExpanding title: TableState_RowExpanding --- # Interface: TableState\_RowExpanding Defined in: [features/row-expanding/rowExpandingFeature.types.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L10) ## Properties ### expanded ```ts expanded: ExpandedState; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L11) ================================================ FILE: docs/reference/interfaces/TableState_RowPagination.md ================================================ --- id: TableState_RowPagination title: TableState_RowPagination --- # Interface: TableState\_RowPagination Defined in: [features/row-pagination/rowPaginationFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L11) ## Properties ### pagination ```ts pagination: PaginationState; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L12) ================================================ FILE: docs/reference/interfaces/TableState_RowPinning.md ================================================ --- id: TableState_RowPinning title: TableState_RowPinning --- # Interface: TableState\_RowPinning Defined in: [features/row-pinning/rowPinningFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L12) ## Properties ### rowPinning ```ts rowPinning: RowPinningState; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L13) ================================================ FILE: docs/reference/interfaces/TableState_RowSelection.md ================================================ --- id: TableState_RowSelection title: TableState_RowSelection --- # Interface: TableState\_RowSelection Defined in: [features/row-selection/rowSelectionFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L8) ## Properties ### rowSelection ```ts rowSelection: RowSelectionState; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L9) ================================================ FILE: docs/reference/interfaces/TableState_RowSorting.md ================================================ --- id: TableState_RowSorting title: TableState_RowSorting --- # Interface: TableState\_RowSorting Defined in: [features/row-sorting/rowSortingFeature.types.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L17) ## Properties ### sorting ```ts sorting: SortingState; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L18) ================================================ FILE: docs/reference/interfaces/Table_ColumnFaceting.md ================================================ --- id: Table_ColumnFaceting title: Table_ColumnFaceting --- # Interface: Table\_ColumnFaceting\ Defined in: [features/column-faceting/columnFacetingFeature.types.ts:81](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L81) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getGlobalFacetedMinMaxValues() ```ts getGlobalFacetedMinMaxValues: () => [number, number] | undefined; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L88) Returns the min and max values for the global filter. #### Returns \[`number`, `number`\] \| `undefined` *** ### getGlobalFacetedRowModel() ```ts getGlobalFacetedRowModel: () => RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L92) Returns the row model for the table after **global** filtering has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getGlobalFacetedUniqueValues() ```ts getGlobalFacetedUniqueValues: () => Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L96) Returns the faceted unique values for the global filter. #### Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/interfaces/Table_ColumnFiltering.md ================================================ --- id: Table_ColumnFiltering title: Table_ColumnFiltering --- # Interface: Table\_ColumnFiltering Defined in: [features/column-filtering/columnFilteringFeature.types.ts:175](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L175) ## Properties ### resetColumnFilters() ```ts resetColumnFilters: (defaultState?) => void; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:179](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L179) Resets the **columnFilters** state to `initialState.columnFilters`, or `true` can be passed to force a default blank state reset to `[]`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setColumnFilters() ```ts setColumnFilters: (updater) => void; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:183](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L183) Sets or updates the `state.columnFilters` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnFiltersState`](../type-aliases/ColumnFiltersState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_ColumnGrouping.md ================================================ --- id: Table_ColumnGrouping title: Table_ColumnGrouping --- # Interface: Table\_ColumnGrouping\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L173) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### resetGrouping() ```ts resetGrouping: (defaultState?) => void; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:180](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L180) Resets the **grouping** state to `initialState.grouping`, or `true` can be passed to force a default blank state reset to `[]`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setGrouping() ```ts setGrouping: (updater) => void; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:184](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L184) Updates the grouping state of the table via an update function or value. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`GroupingState`](../type-aliases/GroupingState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_ColumnOrdering.md ================================================ --- id: Table_ColumnOrdering title: Table_ColumnOrdering --- # Interface: Table\_ColumnOrdering\ Defined in: [features/column-ordering/columnOrderingFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L37) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### resetColumnOrder() ```ts resetColumnOrder: (defaultState?) => void; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L44) Resets the **columnOrder** state to `initialState.columnOrder`, or `true` can be passed to force a default blank state reset to `[]`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setColumnOrder() ```ts setColumnOrder: (updater) => void; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L48) Sets or updates the `state.columnOrder` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnOrderState`](../type-aliases/ColumnOrderState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_ColumnPinning.md ================================================ --- id: Table_ColumnPinning title: Table_ColumnPinning --- # Interface: Table\_ColumnPinning\ Defined in: [features/column-pinning/columnPinningFeature.types.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L78) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getCenterFlatHeaders() ```ts getCenterFlatHeaders: () => Header[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L85) If pinning, returns headers for all columns that are not pinned, including parent headers. #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getCenterFooterGroups() ```ts getCenterFooterGroups: () => HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:89](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L89) If pinning, returns the footer groups for columns that are not pinned. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getCenterHeaderGroups() ```ts getCenterHeaderGroups: () => HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:93](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L93) If pinning, returns the header groups for columns that are not pinned. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getCenterLeafColumns() ```ts getCenterLeafColumns: () => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:97](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L97) Returns all center pinned (unpinned) leaf columns. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getCenterLeafHeaders() ```ts getCenterLeafHeaders: () => Header[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L101) If pinning, returns headers for all columns that are not pinned, (not including parent headers). #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getCenterVisibleLeafColumns() ```ts getCenterVisibleLeafColumns: () => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:105](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L105) If column pinning, returns a flat array of leaf-node columns that are visible in the unpinned/center portion of the table. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getIsSomeColumnsPinned() ```ts getIsSomeColumnsPinned: (position?) => boolean; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L109) Returns whether or not any columns are pinned. Optionally specify to only check for pinned columns in either the `left` or `right` position. #### Parameters ##### position? [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) #### Returns `boolean` *** ### getLeftFlatHeaders() ```ts getLeftFlatHeaders: () => Header[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L113) If pinning, returns headers for all left pinned columns in the table, including parent headers. #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getLeftFooterGroups() ```ts getLeftFooterGroups: () => HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L117) If pinning, returns the footer groups for the left pinned columns. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getLeftHeaderGroups() ```ts getLeftHeaderGroups: () => HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L121) If pinning, returns the header groups for the left pinned columns. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getLeftLeafColumns() ```ts getLeftLeafColumns: () => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:125](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L125) Returns all left pinned leaf columns. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getLeftLeafHeaders() ```ts getLeftLeafHeaders: () => Header[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:129](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L129) If pinning, returns headers for all left pinned leaf columns in the table, (not including parent headers). #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getLeftVisibleLeafColumns() ```ts getLeftVisibleLeafColumns: () => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:133](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L133) If column pinning, returns a flat array of leaf-node columns that are visible in the left portion of the table. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getPinnedLeafColumns() ```ts getPinnedLeafColumns: (position) => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:168](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L168) #### Parameters ##### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getPinnedVisibleLeafColumns() ```ts getPinnedVisibleLeafColumns: (position) => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L173) #### Parameters ##### position [`ColumnPinningPosition`](../type-aliases/ColumnPinningPosition.md) | `"center"` #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getRightFlatHeaders() ```ts getRightFlatHeaders: () => Header[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:137](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L137) If pinning, returns headers for all right pinned columns in the table, including parent headers. #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getRightFooterGroups() ```ts getRightFooterGroups: () => HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L141) If pinning, returns the footer groups for the right pinned columns. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getRightHeaderGroups() ```ts getRightHeaderGroups: () => HeaderGroup[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L145) If pinning, returns the header groups for the right pinned columns. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getRightLeafColumns() ```ts getRightLeafColumns: () => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L149) Returns all right pinned leaf columns. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getRightLeafHeaders() ```ts getRightLeafHeaders: () => Header[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:153](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L153) If pinning, returns headers for all right pinned leaf columns in the table, (not including parent headers). #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getRightVisibleLeafColumns() ```ts getRightVisibleLeafColumns: () => Column[]; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:157](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L157) If column pinning, returns a flat array of leaf-node columns that are visible in the right portion of the table. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### resetColumnPinning() ```ts resetColumnPinning: (defaultState?) => void; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:161](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L161) Resets the **columnPinning** state to `initialState.columnPinning`, or `true` can be passed to force a default blank state reset to `{ left: [], right: [], }`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setColumnPinning() ```ts setColumnPinning: (updater) => void; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:165](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L165) Sets or updates the `state.columnPinning` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnPinningState`](ColumnPinningState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_ColumnResizing.md ================================================ --- id: Table_ColumnResizing title: Table_ColumnResizing --- # Interface: Table\_ColumnResizing Defined in: [features/column-resizing/columnResizingFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L44) ## Properties ### resetHeaderSizeInfo() ```ts resetHeaderSizeInfo: (defaultState?) => void; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L48) Resets column sizing info to its initial state. If `defaultState` is `true`, the default state for the table will be used instead of the initialValue provided to the table. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setcolumnResizing() ```ts setcolumnResizing: (updater) => void; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:52](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L52) Sets the column sizing info state using an updater function or a value. This will trigger the underlying `oncolumnResizingChange` function if one is passed to the table options, otherwise the state will be managed automatically by the table. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`columnResizingState`](columnResizingState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_ColumnSizing.md ================================================ --- id: Table_ColumnSizing title: Table_ColumnSizing --- # Interface: Table\_ColumnSizing Defined in: [features/column-sizing/columnSizingFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L22) ## Properties ### getCenterTotalSize() ```ts getCenterTotalSize: () => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L26) If pinning, returns the total size of the center portion of the table by calculating the sum of the sizes of all unpinned/center leaf-columns. #### Returns `number` *** ### getLeftTotalSize() ```ts getLeftTotalSize: () => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L30) Returns the total size of the left portion of the table by calculating the sum of the sizes of all left leaf-columns. #### Returns `number` *** ### getRightTotalSize() ```ts getRightTotalSize: () => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:34](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L34) Returns the total size of the right portion of the table by calculating the sum of the sizes of all right leaf-columns. #### Returns `number` *** ### getTotalSize() ```ts getTotalSize: () => number; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L38) Returns the total size of the table by calculating the sum of the sizes of all leaf-columns. #### Returns `number` *** ### resetColumnSizing() ```ts resetColumnSizing: (defaultState?) => void; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L42) Resets column sizing to its initial state. If `defaultState` is `true`, the default state for the table will be used instead of the initialValue provided to the table. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setColumnSizing() ```ts setColumnSizing: (updater) => void; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L46) Sets the column sizing state using an updater function or a value. This will trigger the underlying `onColumnSizingChange` function if one is passed to the table options, otherwise the state will be managed automatically by the table. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnSizingState`](../type-aliases/ColumnSizingState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_ColumnVisibility.md ================================================ --- id: Table_ColumnVisibility title: Table_ColumnVisibility --- # Interface: Table\_ColumnVisibility\ Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L28) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getIsAllColumnsVisible() ```ts getIsAllColumnsVisible: () => boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L35) Returns whether all columns are visible #### Returns `boolean` *** ### getIsSomeColumnsVisible() ```ts getIsSomeColumnsVisible: () => boolean; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L39) Returns whether any columns are visible #### Returns `boolean` *** ### getToggleAllColumnsVisibilityHandler() ```ts getToggleAllColumnsVisibilityHandler: () => (event) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L43) Returns a handler for toggling the visibility of all columns, meant to be bound to a `input[type=checkbox]` element. #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` *** ### getVisibleFlatColumns() ```ts getVisibleFlatColumns: () => Column[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:47](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L47) Returns a flat array of columns that are visible, including parent columns. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getVisibleLeafColumns() ```ts getVisibleLeafColumns: () => Column[]; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L51) Returns a flat array of leaf-node columns that are visible. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### resetColumnVisibility() ```ts resetColumnVisibility: (defaultState?) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L55) Resets the column visibility state to the initial state. If `defaultState` is provided, the state will be reset to `{}` #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setColumnVisibility() ```ts setColumnVisibility: (updater) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L59) Sets or updates the `state.columnVisibility` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`ColumnVisibilityState`](../type-aliases/ColumnVisibilityState.md)\> #### Returns `void` *** ### toggleAllColumnsVisible() ```ts toggleAllColumnsVisible: (value?) => void; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L63) Toggles the visibility of all columns. #### Parameters ##### value? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_Columns.md ================================================ --- id: Table_Columns title: Table_Columns --- # Interface: Table\_Columns\ Defined in: [core/columns/coreColumnsFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L75) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getAllColumns() ```ts getAllColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L90) Returns all columns in the table in their normalized and nested hierarchy. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getAllFlatColumns() ```ts getAllFlatColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:94](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L94) Returns all columns in the table flattened to a single level. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getAllFlatColumnsById() ```ts getAllFlatColumnsById: () => Record>; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L82) Returns a map of all flat columns by their ID. #### Returns `Record`\<`string`, [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>\> *** ### getAllLeafColumns() ```ts getAllLeafColumns: () => Column[]; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L98) Returns all leaf-node columns in the table flattened to a single level. This does not include parent columns. #### Returns [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getColumn() ```ts getColumn: (columnId) => | Column | undefined; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:102](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L102) Returns a single column by its ID. #### Parameters ##### columnId `string` #### Returns \| [`Column`](../type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\> \| `undefined` *** ### getDefaultColumnDef() ```ts getDefaultColumnDef: () => Partial>; ``` Defined in: [core/columns/coreColumnsFeature.types.ts:86](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.types.ts#L86) Returns the default column options to use for all column defs supplied to the table. #### Returns `Partial`\<[`ColumnDef`](../type-aliases/ColumnDef.md)\<`TFeatures`, `TData`, `unknown`\>\> ================================================ FILE: docs/reference/interfaces/Table_CoreProperties.md ================================================ --- id: Table_CoreProperties title: Table_CoreProperties --- # Interface: Table\_CoreProperties\ Defined in: [core/table/coreTablesFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L61) ## Extended by - [`Table_Table`](Table_Table.md) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_cellPrototype? ```ts optional _cellPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L72) Prototype cache for Cell objects - shared by all cells in this table *** ### \_columnPrototype? ```ts optional _columnPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L76) Prototype cache for Column objects - shared by all columns in this table *** ### \_features ```ts _features: Partial & TFeatures; ``` Defined in: [core/table/coreTablesFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L68) The features that are enabled for the table. *** ### \_headerPrototype? ```ts optional _headerPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L80) Prototype cache for Header objects - shared by all headers in this table *** ### \_rowModelFns ```ts _rowModelFns: RowModelFns; ``` Defined in: [core/table/coreTablesFeature.types.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L84) The row model processing functions that are used to process the data by features. *** ### \_rowModels ```ts _rowModels: CachedRowModels; ``` Defined in: [core/table/coreTablesFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L88) The row models that are enabled for the table. *** ### \_rowPrototype? ```ts optional _rowPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L92) Prototype cache for Row objects - shared by all rows in this table *** ### baseStore ```ts baseStore: Store>; ``` Defined in: [core/table/coreTablesFeature.types.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L96) The base store for the table. This can be used to write to the table state. *** ### initialState ```ts initialState: TableState; ``` Defined in: [core/table/coreTablesFeature.types.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L100) This is the resolved initial state of the table. *** ### options ```ts options: TableOptions; ``` Defined in: [core/table/coreTablesFeature.types.ts:104](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L104) A read-only reference to the table's current options. *** ### store ```ts store: ReadonlyStore>; ``` Defined in: [core/table/coreTablesFeature.types.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L108) Where the table state is stored. ================================================ FILE: docs/reference/interfaces/Table_GlobalFiltering.md ================================================ --- id: Table_GlobalFiltering title: Table_GlobalFiltering --- # Interface: Table\_GlobalFiltering\ Defined in: [features/global-filtering/globalFilteringFeature.types.ts:64](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L64) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getGlobalAutoFilterFn() ```ts getGlobalAutoFilterFn: () => FilterFn | undefined; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L71) Currently, this function returns the built-in `includesString` filter function. In future releases, it may return more dynamic filter functions based on the nature of the data provided. #### Returns [`FilterFn`](FilterFn.md)\<`TFeatures`, `TData`\> \| `undefined` *** ### getGlobalFilterFn() ```ts getGlobalFilterFn: () => FilterFn | undefined; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L75) Returns the filter function (either user-defined or automatic, depending on configuration) for the global filter. #### Returns [`FilterFn`](FilterFn.md)\<`TFeatures`, `TData`\> \| `undefined` *** ### resetGlobalFilter() ```ts resetGlobalFilter: (defaultState?) => void; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L79) Resets the **globalFilter** state to `initialState.globalFilter`, or `true` can be passed to force a default blank state reset to `undefined`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setGlobalFilter() ```ts setGlobalFilter: (updater) => void; ``` Defined in: [features/global-filtering/globalFilteringFeature.types.ts:83](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts#L83) Sets or updates the `state.globalFilter` state. #### Parameters ##### updater `any` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_Headers.md ================================================ --- id: Table_Headers title: Table_Headers --- # Interface: Table\_Headers\ Defined in: [core/headers/coreHeadersFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L8) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getFlatHeaders() ```ts getFlatHeaders: () => Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L23) Returns headers for all columns in the table, including parent headers. #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] *** ### getFooterGroups() ```ts getFooterGroups: () => HeaderGroup[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L19) Returns the footer groups for the table. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getHeaderGroups() ```ts getHeaderGroups: () => HeaderGroup[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L15) Returns all header groups for the table. #### Returns [`HeaderGroup`](../type-aliases/HeaderGroup.md)\<`TFeatures`, `TData`\>[] *** ### getLeafHeaders() ```ts getLeafHeaders: () => Header[]; ``` Defined in: [core/headers/coreHeadersFeature.types.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.types.ts#L27) Returns headers for all leaf columns in the table, (not including parent headers). #### Returns [`Header`](../type-aliases/Header.md)\<`TFeatures`, `TData`, `unknown`\>[] ================================================ FILE: docs/reference/interfaces/Table_Plugins.md ================================================ --- id: Table_Plugins title: Table_Plugins --- # Interface: Table\_Plugins\ Defined in: [types/Table.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L32) Use this interface as a target for declaration merging to add your own plugin properties. Note: This will affect the types of all tables in your project. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ================================================ FILE: docs/reference/interfaces/Table_RowExpanding.md ================================================ --- id: Table_RowExpanding title: Table_RowExpanding --- # Interface: Table\_RowExpanding\ Defined in: [features/row-expanding/rowExpandingFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L71) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### autoResetExpanded() ```ts autoResetExpanded: () => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L75) #### Returns `void` *** ### getCanSomeRowsExpand() ```ts getCanSomeRowsExpand: () => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L79) Returns whether there are any rows that can be expanded. #### Returns `boolean` *** ### getExpandedDepth() ```ts getExpandedDepth: () => number; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:83](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L83) Returns the maximum depth of the expanded rows. #### Returns `number` *** ### getIsAllRowsExpanded() ```ts getIsAllRowsExpanded: () => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:87](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L87) Returns whether all rows are currently expanded. #### Returns `boolean` *** ### getIsSomeRowsExpanded() ```ts getIsSomeRowsExpanded: () => boolean; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:91](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L91) Returns whether there are any rows that are currently expanded. #### Returns `boolean` *** ### getToggleAllRowsExpandedHandler() ```ts getToggleAllRowsExpandedHandler: () => (event) => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:95](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L95) Returns a handler that can be used to toggle the expanded state of all rows. This handler is meant to be used with an `input[type=checkbox]` element. #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` *** ### resetExpanded() ```ts resetExpanded: (defaultState?) => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:99](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L99) Resets the expanded state of the table to the initial state. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setExpanded() ```ts setExpanded: (updater) => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:103](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L103) Updates the expanded state of the table via an update function or value. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`ExpandedState`](../type-aliases/ExpandedState.md)\> #### Returns `void` *** ### toggleAllRowsExpanded() ```ts toggleAllRowsExpanded: (expanded?) => void; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:107](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L107) Toggles the expanded state for all rows. #### Parameters ##### expanded? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_RowModels_Core.md ================================================ --- id: Table_RowModels_Core title: Table_RowModels_Core --- # Interface: Table\_RowModels\_Core\ Defined in: [core/row-models/coreRowModelsFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L44) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getCoreRowModel() ```ts getCoreRowModel: () => RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L51) Returns the core row model before any processing has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getRowModel() ```ts getRowModel: () => RowModel; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L55) Returns the final model after all processing from other used features has been applied. This is the row model that is most commonly used for rendering. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/Table_RowModels_Expanded.md ================================================ --- id: Table_RowModels_Expanded title: Table_RowModels_Expanded --- # Interface: Table\_RowModels\_Expanded\ Defined in: [features/row-expanding/rowExpandingFeature.types.ts:110](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L110) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getExpandedRowModel() ```ts getExpandedRowModel: () => RowModel; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L117) Returns the row model after expansion has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getPreExpandedRowModel() ```ts getPreExpandedRowModel: () => RowModel; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L121) Returns the row model before expansion has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/Table_RowModels_Faceted.md ================================================ --- id: Table_RowModels_Faceted title: Table_RowModels_Faceted --- # Interface: Table\_RowModels\_Faceted\ Defined in: [features/column-faceting/columnFacetingFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L24) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getFacetedMinMaxValues() ```ts getFacetedMinMaxValues: () => [number, number] | undefined; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L32) A function that **computes and returns** a min/max tuple derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. > ⚠️ Requires that you pass a valid `getFacetedMinMaxValues` function to `options.getFacetedMinMaxValues`. A default implementation is provided via the exported `getFacetedMinMaxValues` function. #### Returns \[`number`, `number`\] \| `undefined` *** ### getFacetedRowModel() ```ts getFacetedRowModel: () => RowModel; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L37) Returns the row model with all other column filters applied, excluding its own filter. Useful for displaying faceted result counts. > ⚠️ Requires that you pass a valid `getFacetedRowModel` function to `options.facetedRowModel`. A default implementation is provided via the exported `getFacetedRowModel` function. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getFacetedUniqueValues() ```ts getFacetedUniqueValues: () => Map; ``` Defined in: [features/column-faceting/columnFacetingFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts#L42) A function that **computes and returns** a `Map` of unique values and their occurrences derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. > ⚠️ Requires that you pass a valid `getFacetedUniqueValues` function to `options.getFacetedUniqueValues`. A default implementation is provided via the exported `getFacetedUniqueValues` function. #### Returns `Map`\<`any`, `number`\> ================================================ FILE: docs/reference/interfaces/Table_RowModels_Filtered.md ================================================ --- id: Table_RowModels_Filtered title: Table_RowModels_Filtered --- # Interface: Table\_RowModels\_Filtered\ Defined in: [features/column-filtering/columnFilteringFeature.types.ts:186](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L186) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getFilteredRowModel() ```ts getFilteredRowModel: () => RowModel; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:193](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L193) Returns the row model for the table after **column** filtering has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getPreFilteredRowModel() ```ts getPreFilteredRowModel: () => RowModel; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:197](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L197) Returns the row model for the table before any **column** filtering has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/Table_RowModels_Grouped.md ================================================ --- id: Table_RowModels_Grouped title: Table_RowModels_Grouped --- # Interface: Table\_RowModels\_Grouped\ Defined in: [features/column-grouping/columnGroupingFeature.types.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L187) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getGroupedRowModel() ```ts getGroupedRowModel: () => RowModel; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:194](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L194) Returns the row model for the table after grouping has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getPreGroupedRowModel() ```ts getPreGroupedRowModel: () => RowModel; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:198](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L198) Returns the row model for the table before any grouping has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/Table_RowModels_Paginated.md ================================================ --- id: Table_RowModels_Paginated title: Table_RowModels_Paginated --- # Interface: Table\_RowModels\_Paginated\ Defined in: [features/row-pagination/rowPaginationFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L109) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getPaginatedRowModel() ```ts getPaginatedRowModel: () => RowModel; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:116](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L116) Returns the row model for the table after pagination has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getPrePaginatedRowModel() ```ts getPrePaginatedRowModel: () => RowModel; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L120) Returns the row model for the table before any pagination has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/Table_RowModels_Sorted.md ================================================ --- id: Table_RowModels_Sorted title: Table_RowModels_Sorted --- # Interface: Table\_RowModels\_Sorted\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:198](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L198) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getPreSortedRowModel() ```ts getPreSortedRowModel: () => RowModel; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:205](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L205) Returns the row model for the table before any sorting has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getSortedRowModel() ```ts getSortedRowModel: () => RowModel; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:209](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L209) Returns the row model for the table after sorting has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/interfaces/Table_RowPagination.md ================================================ --- id: Table_RowPagination title: Table_RowPagination --- # Interface: Table\_RowPagination\ Defined in: [features/row-pagination/rowPaginationFeature.types.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L42) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_autoResetPageIndex() ```ts _autoResetPageIndex: () => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L46) #### Returns `void` *** ### firstPage() ```ts firstPage: () => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L78) Sets the page index to `0`. #### Returns `void` *** ### getCanNextPage() ```ts getCanNextPage: () => boolean; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L50) Returns whether the table can go to the next page. #### Returns `boolean` *** ### getCanPreviousPage() ```ts getCanPreviousPage: () => boolean; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L54) Returns whether the table can go to the previous page. #### Returns `boolean` *** ### getPageCount() ```ts getPageCount: () => number; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L58) Returns the page count. If manually paginating or controlling the pagination state, this will come directly from the `options.pageCount` table option, otherwise it will be calculated from the table data using the total row count and current page size. #### Returns `number` *** ### getPageOptions() ```ts getPageOptions: () => number[]; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L66) Returns an array of page options (zero-index-based) for the current page size. #### Returns `number`[] *** ### getRowCount() ```ts getRowCount: () => number; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L62) Returns the row count. If manually paginating or controlling the pagination state, this will come directly from the `options.rowCount` table option, otherwise it will be calculated from the table data. #### Returns `number` *** ### lastPage() ```ts lastPage: () => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L82) Sets the page index to the last page. #### Returns `void` *** ### nextPage() ```ts nextPage: () => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:70](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L70) Increments the page index by one, if possible. #### Returns `void` *** ### previousPage() ```ts previousPage: () => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:74](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L74) Decrements the page index by one, if possible. #### Returns `void` *** ### resetPageIndex() ```ts resetPageIndex: (defaultState?) => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:86](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L86) Resets the page index to its initial state. If `defaultState` is `true`, the page index will be reset to `0` regardless of initial state. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### resetPageSize() ```ts resetPageSize: (defaultState?) => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L90) Resets the page size to its initial state. If `defaultState` is `true`, the page size will be reset to `10` regardless of initial state. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### resetPagination() ```ts resetPagination: (defaultState?) => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:94](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L94) Resets the **pagination** state to `initialState.pagination`, or `true` can be passed to force a default blank state reset to `[]`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setPageIndex() ```ts setPageIndex: (updater) => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L98) Updates the page index using the provided function or value in the `state.pagination.pageIndex` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<`number`\> #### Returns `void` *** ### setPageSize() ```ts setPageSize: (updater) => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:102](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L102) Updates the page size using the provided function or value in the `state.pagination.pageSize` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<`number`\> #### Returns `void` *** ### setPagination() ```ts setPagination: (updater) => void; ``` Defined in: [features/row-pagination/rowPaginationFeature.types.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts#L106) Sets or updates the `state.pagination` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`PaginationState`](PaginationState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_RowPinning.md ================================================ --- id: Table_RowPinning title: Table_RowPinning --- # Interface: Table\_RowPinning\ Defined in: [features/row-pinning/rowPinningFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L61) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getBottomRows() ```ts getBottomRows: () => Row[]; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L68) Returns all bottom pinned rows. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] *** ### getCenterRows() ```ts getCenterRows: () => Row[]; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L72) Returns all rows that are not pinned to the top or bottom. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] *** ### getIsSomeRowsPinned() ```ts getIsSomeRowsPinned: (position?) => boolean; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L76) Returns whether or not any rows are pinned. Optionally specify to only check for pinned rows in either the `top` or `bottom` position. #### Parameters ##### position? [`RowPinningPosition`](../type-aliases/RowPinningPosition.md) #### Returns `boolean` *** ### getTopRows() ```ts getTopRows: () => Row[]; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L80) Returns all top pinned rows. #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] *** ### resetRowPinning() ```ts resetRowPinning: (defaultState?) => void; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L84) Resets the **rowPinning** state to `initialState.rowPinning`, or `true` can be passed to force a default blank state reset to `{ top: [], bottom: [], }`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setRowPinning() ```ts setRowPinning: (updater) => void; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L88) Sets or updates the `state.rowPinning` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`RowPinningState`](RowPinningState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_RowSelection.md ================================================ --- id: Table_RowSelection title: Table_RowSelection --- # Interface: Table\_RowSelection\ Defined in: [features/row-selection/rowSelectionFeature.types.ts:83](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L83) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getFilteredSelectedRowModel() ```ts getFilteredSelectedRowModel: () => RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L90) Returns the row model of all rows that are selected after filtering has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getGroupedSelectedRowModel() ```ts getGroupedSelectedRowModel: () => RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:94](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L94) Returns the row model of all rows that are selected after grouping has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getIsAllPageRowsSelected() ```ts getIsAllPageRowsSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L98) Returns whether or not all rows on the current page are selected. #### Returns `boolean` *** ### getIsAllRowsSelected() ```ts getIsAllRowsSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:102](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L102) Returns whether or not all rows in the table are selected. #### Returns `boolean` *** ### getIsSomePageRowsSelected() ```ts getIsSomePageRowsSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:106](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L106) Returns whether or not any rows on the current page are selected. #### Returns `boolean` *** ### getIsSomeRowsSelected() ```ts getIsSomeRowsSelected: () => boolean; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:110](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L110) Returns whether or not any rows in the table are selected. #### Returns `boolean` *** ### getPreSelectedRowModel() ```ts getPreSelectedRowModel: () => RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:114](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L114) Returns the core row model of all rows before row selection has been applied. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getSelectedRowModel() ```ts getSelectedRowModel: () => RowModel; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L118) Returns the row model of all rows that are selected. #### Returns [`RowModel`](RowModel.md)\<`TFeatures`, `TData`\> *** ### getToggleAllPageRowsSelectedHandler() ```ts getToggleAllPageRowsSelectedHandler: () => (event) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L122) Returns a handler that can be used to toggle all rows on the current page. #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` *** ### getToggleAllRowsSelectedHandler() ```ts getToggleAllRowsSelectedHandler: () => (event) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:126](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L126) Returns a handler that can be used to toggle all rows in the table. #### Returns ```ts (event): void; ``` ##### Parameters ###### event `unknown` ##### Returns `void` *** ### resetRowSelection() ```ts resetRowSelection: (defaultState?) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:130](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L130) Resets the **rowSelection** state to the `initialState.rowSelection`, or `true` can be passed to force a default blank state reset to `{}`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setRowSelection() ```ts setRowSelection: (updater) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:134](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L134) Sets or updates the `state.rowSelection` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`RowSelectionState`](../type-aliases/RowSelectionState.md)\> #### Returns `void` *** ### toggleAllPageRowsSelected() ```ts toggleAllPageRowsSelected: (value?) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:138](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L138) Selects/deselects all rows on the current page. #### Parameters ##### value? `boolean` #### Returns `void` *** ### toggleAllRowsSelected() ```ts toggleAllRowsSelected: (value?) => void; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:142](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L142) Selects/deselects all rows in the table. #### Parameters ##### value? `boolean` #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_RowSorting.md ================================================ --- id: Table_RowSorting title: Table_RowSorting --- # Interface: Table\_RowSorting\ Defined in: [features/row-sorting/rowSortingFeature.types.ts:184](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L184) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### resetSorting() ```ts resetSorting: (defaultState?) => void; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:191](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L191) Resets the **sorting** state to `initialState.sorting`, or `true` can be passed to force a default blank state reset to `[]`. #### Parameters ##### defaultState? `boolean` #### Returns `void` *** ### setSorting() ```ts setSorting: (updater) => void; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:195](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L195) Sets or updates the `state.sorting` state. #### Parameters ##### updater [`Updater`](../type-aliases/Updater.md)\<[`SortingState`](../type-aliases/SortingState.md)\> #### Returns `void` ================================================ FILE: docs/reference/interfaces/Table_Rows.md ================================================ --- id: Table_Rows title: Table_Rows --- # Interface: Table\_Rows\ Defined in: [core/rows/coreRowsFeature.types.ts:105](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L105) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### getRow() ```ts getRow: (id, searchAll?) => Row; ``` Defined in: [core/rows/coreRowsFeature.types.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L113) Returns the row with the given ID. #### Parameters ##### id `string` ##### searchAll? `boolean` #### Returns [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> *** ### getRowId() ```ts getRowId: (_, index, parent?) => string; ``` Defined in: [core/rows/coreRowsFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L109) #### Parameters ##### \_ `TData` ##### index `number` ##### parent? [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\> #### Returns `string` ================================================ FILE: docs/reference/interfaces/Table_Table.md ================================================ --- id: Table_Table title: Table_Table --- # Interface: Table\_Table\ Defined in: [core/table/coreTablesFeature.types.ts:111](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L111) ## Extends - [`Table_CoreProperties`](Table_CoreProperties.md)\<`TFeatures`, `TData`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](TableFeatures.md) ### TData `TData` *extends* [`RowData`](../type-aliases/RowData.md) ## Properties ### \_cellPrototype? ```ts optional _cellPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L72) Prototype cache for Cell objects - shared by all cells in this table #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_cellPrototype`](Table_CoreProperties.md#_cellprototype) *** ### \_columnPrototype? ```ts optional _columnPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L76) Prototype cache for Column objects - shared by all columns in this table #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_columnPrototype`](Table_CoreProperties.md#_columnprototype) *** ### \_features ```ts _features: Partial & TFeatures; ``` Defined in: [core/table/coreTablesFeature.types.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L68) The features that are enabled for the table. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_features`](Table_CoreProperties.md#_features) *** ### \_headerPrototype? ```ts optional _headerPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L80) Prototype cache for Header objects - shared by all headers in this table #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_headerPrototype`](Table_CoreProperties.md#_headerprototype) *** ### \_rowModelFns ```ts _rowModelFns: RowModelFns; ``` Defined in: [core/table/coreTablesFeature.types.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L84) The row model processing functions that are used to process the data by features. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_rowModelFns`](Table_CoreProperties.md#_rowmodelfns) *** ### \_rowModels ```ts _rowModels: CachedRowModels; ``` Defined in: [core/table/coreTablesFeature.types.ts:88](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L88) The row models that are enabled for the table. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_rowModels`](Table_CoreProperties.md#_rowmodels) *** ### \_rowPrototype? ```ts optional _rowPrototype: object; ``` Defined in: [core/table/coreTablesFeature.types.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L92) Prototype cache for Row objects - shared by all rows in this table #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`_rowPrototype`](Table_CoreProperties.md#_rowprototype) *** ### baseStore ```ts baseStore: Store>; ``` Defined in: [core/table/coreTablesFeature.types.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L96) The base store for the table. This can be used to write to the table state. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`baseStore`](Table_CoreProperties.md#basestore) *** ### initialState ```ts initialState: TableState; ``` Defined in: [core/table/coreTablesFeature.types.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L100) This is the resolved initial state of the table. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`initialState`](Table_CoreProperties.md#initialstate) *** ### options ```ts options: TableOptions; ``` Defined in: [core/table/coreTablesFeature.types.ts:104](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L104) A read-only reference to the table's current options. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`options`](Table_CoreProperties.md#options) *** ### reset() ```ts reset: () => void; ``` Defined in: [core/table/coreTablesFeature.types.ts:118](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L118) Call this function to reset the table state to the initial state. #### Returns `void` *** ### setOptions() ```ts setOptions: (newOptions) => void; ``` Defined in: [core/table/coreTablesFeature.types.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L122) This function can be used to update the table options. #### Parameters ##### newOptions [`Updater`](../type-aliases/Updater.md)\<[`TableOptions`](../type-aliases/TableOptions.md)\<`TFeatures`, `TData`\>\> #### Returns `void` *** ### store ```ts store: ReadonlyStore>; ``` Defined in: [core/table/coreTablesFeature.types.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.types.ts#L108) Where the table state is stored. #### Inherited from [`Table_CoreProperties`](Table_CoreProperties.md).[`store`](Table_CoreProperties.md#store) ================================================ FILE: docs/reference/interfaces/columnResizingState.md ================================================ --- id: columnResizingState title: columnResizingState --- # Interface: columnResizingState Defined in: [features/column-resizing/columnResizingFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L7) ## Properties ### columnSizingStart ```ts columnSizingStart: [string, number][]; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L8) *** ### deltaOffset ```ts deltaOffset: number | null; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L9) *** ### deltaPercentage ```ts deltaPercentage: number | null; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L10) *** ### isResizingColumn ```ts isResizingColumn: string | false; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L11) *** ### startOffset ```ts startOffset: number | null; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L12) *** ### startSize ```ts startSize: number | null; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L13) ================================================ FILE: docs/reference/type-aliases/APIObject.md ================================================ --- id: APIObject title: APIObject --- # Type Alias: APIObject\ ```ts type APIObject = Record>; ``` Defined in: [utils.ts:272](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L272) ## Type Parameters ### TDeps `TDeps` *extends* `ReadonlyArray`\<`any`\> ### TDepArgs `TDepArgs` ================================================ FILE: docs/reference/type-aliases/AccessorColumnDef.md ================================================ --- id: AccessorColumnDef title: AccessorColumnDef --- # Type Alias: AccessorColumnDef\ ```ts type AccessorColumnDef = | AccessorKeyColumnDef | AccessorFnColumnDef; ``` Defined in: [types/ColumnDef.ts:194](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L194) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/AccessorFn.md ================================================ --- id: AccessorFn title: AccessorFn --- # Type Alias: AccessorFn()\ ```ts type AccessorFn = (originalRow, index) => TValue; ``` Defined in: [types/ColumnDef.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L30) ## Type Parameters ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ## Parameters ### originalRow `TData` ### index `number` ## Returns `TValue` ================================================ FILE: docs/reference/type-aliases/AccessorFnColumnDef.md ================================================ --- id: AccessorFnColumnDef title: AccessorFnColumnDef --- # Type Alias: AccessorFnColumnDef\ ```ts type AccessorFnColumnDef = AccessorFnColumnDefBase & ColumnIdentifiers; ``` Defined in: [types/ColumnDef.ts:171](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L171) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/AccessorFnColumnDefBase.md ================================================ --- id: AccessorFnColumnDefBase title: AccessorFnColumnDefBase --- # Type Alias: AccessorFnColumnDefBase\ ```ts type AccessorFnColumnDefBase = ColumnDefBase & object; ``` Defined in: [types/ColumnDef.ts:163](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L163) ## Type Declaration ### accessorFn ```ts accessorFn: AccessorFn; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/AccessorKeyColumnDef.md ================================================ --- id: AccessorKeyColumnDef title: AccessorKeyColumnDef --- # Type Alias: AccessorKeyColumnDef\ ```ts type AccessorKeyColumnDef = AccessorKeyColumnDefBase & Partial>; ``` Defined in: [types/ColumnDef.ts:187](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L187) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/AccessorKeyColumnDefBase.md ================================================ --- id: AccessorKeyColumnDefBase title: AccessorKeyColumnDefBase --- # Type Alias: AccessorKeyColumnDefBase\ ```ts type AccessorKeyColumnDefBase = ColumnDefBase & object; ``` Defined in: [types/ColumnDef.ts:178](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L178) ## Type Declaration ### accessorKey ```ts accessorKey: string & object | keyof TData; ``` ### id? ```ts optional id: string; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/AggregationFn.md ================================================ --- id: AggregationFn title: AggregationFn --- # Type Alias: AggregationFn()\ ```ts type AggregationFn = (columnId, leafRows, childRows) => any; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L30) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### columnId `string` ### leafRows [`Row`](Row.md)\<`TFeatures`, `TData`\>[] ### childRows [`Row`](Row.md)\<`TFeatures`, `TData`\>[] ## Returns `any` ================================================ FILE: docs/reference/type-aliases/AggregationFnOption.md ================================================ --- id: AggregationFnOption title: AggregationFnOption --- # Type Alias: AggregationFnOption\ ```ts type AggregationFnOption = | "auto" | keyof AggregationFns | BuiltInAggregationFn | AggregationFn; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L44) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/AssignCellPrototype.md ================================================ --- id: AssignCellPrototype title: AssignCellPrototype --- # Type Alias: AssignCellPrototype()\ ```ts type AssignCellPrototype = (prototype, table) => void; ``` Defined in: [types/TableFeatures.ts:77](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L77) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### prototype `Record`\<`string`, `any`\> ### table [`Table_Internal`](Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/type-aliases/AssignColumnPrototype.md ================================================ --- id: AssignColumnPrototype title: AssignColumnPrototype --- # Type Alias: AssignColumnPrototype()\ ```ts type AssignColumnPrototype = (prototype, table) => void; ``` Defined in: [types/TableFeatures.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L85) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### prototype `Record`\<`string`, `any`\> ### table [`Table_Internal`](Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/type-aliases/AssignHeaderPrototype.md ================================================ --- id: AssignHeaderPrototype title: AssignHeaderPrototype --- # Type Alias: AssignHeaderPrototype()\ ```ts type AssignHeaderPrototype = (prototype, table) => void; ``` Defined in: [types/TableFeatures.ts:93](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L93) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### prototype `Record`\<`string`, `any`\> ### table [`Table_Internal`](Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/type-aliases/AssignRowPrototype.md ================================================ --- id: AssignRowPrototype title: AssignRowPrototype --- # Type Alias: AssignRowPrototype()\ ```ts type AssignRowPrototype = (prototype, table) => void; ``` Defined in: [types/TableFeatures.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L101) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### prototype `Record`\<`string`, `any`\> ### table [`Table_Internal`](Table_Internal.md)\<`TFeatures`, `TData`\> ## Returns `void` ================================================ FILE: docs/reference/type-aliases/BuiltInAggregationFn.md ================================================ --- id: BuiltInAggregationFn title: BuiltInAggregationFn --- # Type Alias: BuiltInAggregationFn ```ts type BuiltInAggregationFn = keyof typeof aggregationFns; ``` Defined in: [fns/aggregationFns.ts:220](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L220) ================================================ FILE: docs/reference/type-aliases/BuiltInFilterFn.md ================================================ --- id: BuiltInFilterFn title: BuiltInFilterFn --- # Type Alias: BuiltInFilterFn ```ts type BuiltInFilterFn = keyof typeof filterFns; ``` Defined in: [fns/filterFns.ts:373](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L373) ================================================ FILE: docs/reference/type-aliases/BuiltInSortFn.md ================================================ --- id: BuiltInSortFn title: BuiltInSortFn --- # Type Alias: BuiltInSortFn ```ts type BuiltInSortFn = keyof typeof sortFns; ``` Defined in: [fns/sortFns.ts:173](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L173) ================================================ FILE: docs/reference/type-aliases/CachedRowModel_All.md ================================================ --- id: CachedRowModel_All title: CachedRowModel_All --- # Type Alias: CachedRowModel\_All\ ```ts type CachedRowModel_All = Partial & CachedRowModel_Expanded & CachedRowModel_Faceted & CachedRowModel_Filtered & CachedRowModel_Grouped & CachedRowModel_Paginated & CachedRowModel_Sorted>; ``` Defined in: [types/RowModel.ts:126](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModel.ts#L126) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) = `any` ================================================ FILE: docs/reference/type-aliases/CachedRowModels.md ================================================ --- id: CachedRowModels title: CachedRowModels --- # Type Alias: CachedRowModels\ ```ts type CachedRowModels = object & UnionToIntersection< | "columnFacetingFeature" extends keyof TFeatures ? CachedRowModel_Faceted : never | "columnFilteringFeature" extends keyof TFeatures ? CachedRowModel_Filtered : never | "rowExpandingFeature" extends keyof TFeatures ? CachedRowModel_Expanded : never | "columnGroupingFeature" extends keyof TFeatures ? CachedRowModel_Grouped : never | "rowPaginationFeature" extends keyof TFeatures ? CachedRowModel_Paginated : never | "rowSortingFeature" extends keyof TFeatures ? CachedRowModel_Sorted : never> & ExtractFeatureTypes<"CachedRowModel", TFeatures> & CachedRowModels_Plugins; ``` Defined in: [types/RowModel.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModel.ts#L92) ## Type Declaration ### CachedRowModel\_Core() ```ts CachedRowModel_Core: () => RowModel; ``` #### Returns [`RowModel`](../interfaces/RowModel.md)\<`TFeatures`, `TData`\> ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/Cell.md ================================================ --- id: Cell title: Cell --- # Type Alias: Cell\ ```ts type Cell = Cell_Cell & UnionToIntersection<"columnGroupingFeature" extends keyof TFeatures ? Cell_ColumnGrouping : never> & ExtractFeatureTypes<"Cell", TFeatures> & Cell_Plugins; ``` Defined in: [types/Cell.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Cell.ts#L22) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/CellData.md ================================================ --- id: CellData title: CellData --- # Type Alias: CellData ```ts type CellData = unknown; ``` Defined in: [types/type-utils.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L7) ================================================ FILE: docs/reference/type-aliases/Column.md ================================================ --- id: Column title: Column --- # Type Alias: Column\ ```ts type Column = Column_Core & UnionToIntersection< | "columnFacetingFeature" extends keyof TFeatures ? Column_ColumnFaceting : never | "columnFilteringFeature" extends keyof TFeatures ? Column_ColumnFiltering : never | "columnGroupingFeature" extends keyof TFeatures ? Column_ColumnGrouping : never | "columnOrderingFeature" extends keyof TFeatures ? Column_ColumnOrdering : never | "columnPinningFeature" extends keyof TFeatures ? Column_ColumnPinning : never | "columnResizingFeature" extends keyof TFeatures ? Column_ColumnResizing : never | "columnSizingFeature" extends keyof TFeatures ? Column_ColumnSizing : never | "columnVisibilityFeature" extends keyof TFeatures ? Column_ColumnVisibility : never | "globalFilteringFeature" extends keyof TFeatures ? Column_GlobalFiltering : never | "rowSortingFeature" extends keyof TFeatures ? Column_RowSorting : never> & ExtractFeatureTypes<"Column", TFeatures> & Column_Plugins; ``` Defined in: [types/Column.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Column.ts#L32) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` = `unknown` ================================================ FILE: docs/reference/type-aliases/ColumnDef.md ================================================ --- id: ColumnDef title: ColumnDef --- # Type Alias: ColumnDef\ ```ts type ColumnDef = | DisplayColumnDef | GroupColumnDef | AccessorColumnDef; ``` Defined in: [types/ColumnDef.ts:202](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L202) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/ColumnDefBase.md ================================================ --- id: ColumnDefBase title: ColumnDefBase --- # Type Alias: ColumnDefBase\ ```ts type ColumnDefBase = ColumnDefBase_Core & UnionToIntersection< | "columnVisibilityFeature" extends keyof TFeatures ? ColumnDef_ColumnVisibility : never | "columnPinningFeature" extends keyof TFeatures ? ColumnDef_ColumnPinning : never | "columnFilteringFeature" extends keyof TFeatures ? ColumnDef_ColumnFiltering : never | "globalFilteringFeature" extends keyof TFeatures ? ColumnDef_GlobalFiltering : never | "rowSortingFeature" extends keyof TFeatures ? ColumnDef_RowSorting : never | "columnGroupingFeature" extends keyof TFeatures ? ColumnDef_ColumnGrouping : never | "columnSizingFeature" extends keyof TFeatures ? ColumnDef_ColumnSizing : never | "columnResizingFeature" extends keyof TFeatures ? ColumnDef_ColumnResizing : never> & ExtractFeatureTypes<"ColumnDef", TFeatures> & ColumnDef_Plugins; ``` Defined in: [types/ColumnDef.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L75) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/ColumnDefBase_All.md ================================================ --- id: ColumnDefBase_All title: ColumnDefBase_All --- # Type Alias: ColumnDefBase\_All\ ```ts type ColumnDefBase_All = ColumnDefBase_Core & Partial & ColumnDef_GlobalFiltering & ColumnDef_RowSorting & ColumnDef_ColumnGrouping & ColumnDef_ColumnSizing & ColumnDef_ColumnResizing>; ``` Defined in: [types/ColumnDef.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L117) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/ColumnDefResolved.md ================================================ --- id: ColumnDefResolved title: ColumnDefResolved --- # Type Alias: ColumnDefResolved\ ```ts type ColumnDefResolved = Partial>> & object; ``` Defined in: [types/ColumnDef.ts:211](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L211) ## Type Declaration ### accessorKey? ```ts optional accessorKey: string; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/ColumnDefTemplate.md ================================================ --- id: ColumnDefTemplate title: ColumnDefTemplate --- # Type Alias: ColumnDefTemplate\ ```ts type ColumnDefTemplate = string | (props) => any; ``` Defined in: [types/ColumnDef.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L35) ## Type Parameters ### TProps `TProps` *extends* `object` ================================================ FILE: docs/reference/type-aliases/ColumnFilterAutoRemoveTestFn.md ================================================ --- id: ColumnFilterAutoRemoveTestFn title: ColumnFilterAutoRemoveTestFn --- # Type Alias: ColumnFilterAutoRemoveTestFn()\ ```ts type ColumnFilterAutoRemoveTestFn = (value, column?) => boolean; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:65](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L65) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ## Parameters ### value `any` ### column? [`Column`](Column.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `boolean` ================================================ FILE: docs/reference/type-aliases/ColumnFiltersState.md ================================================ --- id: ColumnFiltersState title: ColumnFiltersState --- # Type Alias: ColumnFiltersState ```ts type ColumnFiltersState = ColumnFilter[]; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L22) ================================================ FILE: docs/reference/type-aliases/ColumnHelper.md ================================================ --- id: ColumnHelper title: ColumnHelper --- # Type Alias: ColumnHelper\ ```ts type ColumnHelper = object; ``` Defined in: [helpers/columnHelper.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/columnHelper.ts#L13) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Properties ### accessor() ```ts accessor: (accessor, column) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef; ``` Defined in: [helpers/columnHelper.ts:25](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/columnHelper.ts#L25) Creates a data column definition with an accessor key or function to extract the cell value. #### Type Parameters ##### TAccessor `TAccessor` *extends* \| [`AccessorFn`](AccessorFn.md)\<`TData`\> \| [`DeepKeys`](DeepKeys.md)\<`TData`\> ##### TValue `TValue` *extends* `TAccessor` *extends* [`AccessorFn`](AccessorFn.md)\<`TData`, infer TReturn\> ? `TReturn` : `TAccessor` *extends* [`DeepKeys`](DeepKeys.md)\<`TData`\> ? [`DeepValue`](DeepValue.md)\<`TData`, `TAccessor`\> : `never` #### Parameters ##### accessor `TAccessor` ##### column `TAccessor` *extends* [`AccessorFn`](AccessorFn.md)\<`TData`\> ? [`DisplayColumnDef`](DisplayColumnDef.md)\<`TFeatures`, `TData`, `TValue`\> : [`IdentifiedColumnDef`](IdentifiedColumnDef.md)\<`TFeatures`, `TData`, `TValue`\> #### Returns `TAccessor` *extends* [`AccessorFn`](AccessorFn.md)\<`TData`\> ? [`AccessorFnColumnDef`](AccessorFnColumnDef.md)\<`TFeatures`, `TData`, `TValue`\> : [`AccessorKeyColumnDef`](AccessorKeyColumnDef.md)\<`TFeatures`, `TData`, `TValue`\> #### Example ```ts helper.accessor('firstName', { cell: (info) => info.getValue() }) helper.accessor((row) => row.lastName, { id: 'lastName' }) ``` *** ### columns() ```ts columns: (columns) => ColumnDef[] & [...TColumns]; ``` Defined in: [helpers/columnHelper.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/columnHelper.ts#L48) Wraps an array of column definitions to preserve each column's individual TValue type. Uses variadic tuple types to infer element types before checking constraints, preventing type widening. #### Type Parameters ##### TColumns `TColumns` *extends* `ReadonlyArray`\<[`ColumnDef`](ColumnDef.md)\<`TFeatures`, `TData`, `any`\>\> #### Parameters ##### columns \[`...TColumns`\] #### Returns [`ColumnDef`](ColumnDef.md)\<`TFeatures`, `TData`, `any`\>[] & \[`...TColumns`\] #### Example ```ts helper.columns([helper.accessor('firstName', {}), helper.accessor('age', {})]) ``` *** ### display() ```ts display: (column) => DisplayColumnDef; ``` Defined in: [helpers/columnHelper.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/columnHelper.ts#L58) Creates a display column definition for non-data columns like actions or row selection. #### Parameters ##### column [`DisplayColumnDef`](DisplayColumnDef.md)\<`TFeatures`, `TData`\> #### Returns [`DisplayColumnDef`](DisplayColumnDef.md)\<`TFeatures`, `TData`, `unknown`\> #### Example ```ts helper.display({ id: 'actions', header: 'Actions', cell: () => }) ``` *** ### group() ```ts group: (column) => GroupColumnDef; ``` Defined in: [helpers/columnHelper.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/columnHelper.ts#L75) Creates a group column definition that contains nested child columns. #### Parameters ##### column [`GroupColumnDef`](GroupColumnDef.md)\<`TFeatures`, `TData`, `unknown`\> #### Returns [`GroupColumnDef`](GroupColumnDef.md)\<`TFeatures`, `TData`, `unknown`\> #### Example ```ts helper.group({ id: 'name', header: 'Name', columns: helper.columns([ helper.accessor('firstName', {}), helper.accessor('lastName', { id: 'lastName' }), ]), }) ``` ================================================ FILE: docs/reference/type-aliases/ColumnOrderState.md ================================================ --- id: ColumnOrderState title: ColumnOrderState --- # Type Alias: ColumnOrderState ```ts type ColumnOrderState = string[]; ``` Defined in: [features/column-ordering/columnOrderingFeature.types.ts:5](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts#L5) ================================================ FILE: docs/reference/type-aliases/ColumnPinningPosition.md ================================================ --- id: ColumnPinningPosition title: ColumnPinningPosition --- # Type Alias: ColumnPinningPosition ```ts type ColumnPinningPosition = false | "left" | "right"; ``` Defined in: [features/column-pinning/columnPinningFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts#L8) ================================================ FILE: docs/reference/type-aliases/ColumnResizeDirection.md ================================================ --- id: ColumnResizeDirection title: ColumnResizeDirection --- # Type Alias: ColumnResizeDirection ```ts type ColumnResizeDirection = "ltr" | "rtl"; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L18) ================================================ FILE: docs/reference/type-aliases/ColumnResizeMode.md ================================================ --- id: ColumnResizeMode title: ColumnResizeMode --- # Type Alias: ColumnResizeMode ```ts type ColumnResizeMode = "onChange" | "onEnd"; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:16](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L16) ================================================ FILE: docs/reference/type-aliases/ColumnResizingDefaultOptions.md ================================================ --- id: ColumnResizingDefaultOptions title: ColumnResizingDefaultOptions --- # Type Alias: ColumnResizingDefaultOptions ```ts type ColumnResizingDefaultOptions = Pick; ``` Defined in: [features/column-resizing/columnResizingFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts#L39) ================================================ FILE: docs/reference/type-aliases/ColumnSizingDefaultOptions.md ================================================ --- id: ColumnSizingDefaultOptions title: ColumnSizingDefaultOptions --- # Type Alias: ColumnSizingDefaultOptions ```ts type ColumnSizingDefaultOptions = Pick; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L17) ================================================ FILE: docs/reference/type-aliases/ColumnSizingState.md ================================================ --- id: ColumnSizingState title: ColumnSizingState --- # Type Alias: ColumnSizingState ```ts type ColumnSizingState = Record; ``` Defined in: [features/column-sizing/columnSizingFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts#L8) ================================================ FILE: docs/reference/type-aliases/ColumnVisibilityState.md ================================================ --- id: ColumnVisibilityState title: ColumnVisibilityState --- # Type Alias: ColumnVisibilityState ```ts type ColumnVisibilityState = Record; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:6](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L6) ================================================ FILE: docs/reference/type-aliases/Column_Internal.md ================================================ --- id: Column_Internal title: Column_Internal --- # Type Alias: Column\_Internal\ ```ts type Column_Internal = Column & object; ``` Defined in: [types/Column.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Column.ts#L80) ## Type Declaration ### columnDef ```ts columnDef: ColumnDefBase_All; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` = `unknown` ================================================ FILE: docs/reference/type-aliases/ConstructTableAPIs.md ================================================ --- id: ConstructTableAPIs title: ConstructTableAPIs --- # Type Alias: ConstructTableAPIs()\ ```ts type ConstructTableAPIs = (table) => void; ``` Defined in: [types/TableFeatures.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L45) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### table [`Table_Internal`](Table_Internal.md)\<`TFeatures`, `TData`\> & `Partial`\<`TConstructors`\[`"Table"`\]\> & `object` ## Returns `void` ================================================ FILE: docs/reference/type-aliases/CreateRowModels.md ================================================ --- id: CreateRowModels title: CreateRowModels --- # Type Alias: CreateRowModels\ ```ts type CreateRowModels = CreateRowModel_Core & UnionToIntersection< | "columnFacetingFeature" extends keyof TFeatures ? CreateRowModel_Faceted : never | "columnFilteringFeature" extends keyof TFeatures ? CreateRowModel_Filtered : never | "rowExpandingFeature" extends keyof TFeatures ? CreateRowModel_Expanded : never | "columnGroupingFeature" extends keyof TFeatures ? CreateRowModel_Grouped : never | "rowPaginationFeature" extends keyof TFeatures ? CreateRowModel_Paginated : never | "rowSortingFeature" extends keyof TFeatures ? CreateRowModel_Sorted : never> & ExtractFeatureTypes<"CreateRowModels", TFeatures> & CreateRowModels_Plugins; ``` Defined in: [types/RowModel.ts:42](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModel.ts#L42) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/CreateRowModels_All.md ================================================ --- id: CreateRowModels_All title: CreateRowModels_All --- # Type Alias: CreateRowModels\_All\ ```ts type CreateRowModels_All = CreateRowModel_Core & CreateRowModel_Expanded & CreateRowModel_Faceted & CreateRowModel_Filtered & CreateRowModel_Grouped & CreateRowModel_Paginated & CreateRowModel_Sorted; ``` Defined in: [types/RowModel.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModel.ts#L76) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/CustomAggregationFns.md ================================================ --- id: CustomAggregationFns title: CustomAggregationFns --- # Type Alias: CustomAggregationFns\ ```ts type CustomAggregationFns = Record>; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L39) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/CustomFilterFns.md ================================================ --- id: CustomFilterFns title: CustomFilterFns --- # Type Alias: CustomFilterFns\ ```ts type CustomFilterFns = Record>; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L71) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/CustomSortFns.md ================================================ --- id: CustomSortFns title: CustomSortFns --- # Type Alias: CustomSortFns\ ```ts type CustomSortFns = Record>; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L41) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/DebugOptions.md ================================================ --- id: DebugOptions title: DebugOptions --- # Type Alias: DebugOptions\ ```ts type DebugOptions = object & DebugKeysFor; ``` Defined in: [types/TableOptions.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableOptions.ts#L41) ## Type Declaration ### debugAll? ```ts optional debugAll: boolean; ``` ### debugCache? ```ts optional debugCache: boolean; ``` ### debugCells? ```ts optional debugCells: boolean; ``` ### debugColumns? ```ts optional debugColumns: boolean; ``` ### debugHeaders? ```ts optional debugHeaders: boolean; ``` ### debugRows? ```ts optional debugRows: boolean; ``` ### debugTable? ```ts optional debugTable: boolean; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ================================================ FILE: docs/reference/type-aliases/DeepKeys.md ================================================ --- id: DeepKeys title: DeepKeys --- # Type Alias: DeepKeys\ ```ts type DeepKeys = TDepth["length"] extends 5 ? never : unknown extends T ? string : T extends ReadonlyArray & IsTuple ? | AllowedIndexes | DeepKeysPrefix, TDepth> : T extends any[] ? DeepKeys : T extends Date ? never : T extends object ? keyof T & string | DeepKeysPrefix : never; ``` Defined in: [types/type-utils.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L46) ## Type Parameters ### T `T` ### TDepth `TDepth` *extends* `any`[] = \[\] ================================================ FILE: docs/reference/type-aliases/DeepValue.md ================================================ --- id: DeepValue title: DeepValue --- # Type Alias: DeepValue\ ```ts type DeepValue = T extends Record ? TProp extends `${infer TBranch}.${infer TDeepProp}` ? DeepValue : T[TProp & string] : never; ``` Defined in: [types/type-utils.ts:71](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L71) ## Type Parameters ### T `T` ### TProp `TProp` ================================================ FILE: docs/reference/type-aliases/DisplayColumnDef.md ================================================ --- id: DisplayColumnDef title: DisplayColumnDef --- # Type Alias: DisplayColumnDef\ ```ts type DisplayColumnDef = ColumnDefBase & ColumnIdentifiers; ``` Defined in: [types/ColumnDef.ts:142](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L142) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/ExpandedState.md ================================================ --- id: ExpandedState title: ExpandedState --- # Type Alias: ExpandedState ```ts type ExpandedState = true | Record; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L8) ================================================ FILE: docs/reference/type-aliases/ExpandedStateList.md ================================================ --- id: ExpandedStateList title: ExpandedStateList --- # Type Alias: ExpandedStateList ```ts type ExpandedStateList = Record; ``` Defined in: [features/row-expanding/rowExpandingFeature.types.ts:7](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts#L7) ================================================ FILE: docs/reference/type-aliases/ExtractFeatureTypes.md ================================================ --- id: ExtractFeatureTypes title: ExtractFeatureTypes --- # Type Alias: ExtractFeatureTypes\ ```ts type ExtractFeatureTypes = UnionToIntersection<{ [K in keyof TFeatures]: TFeatures[K] extends TableFeature ? TKey extends keyof FeatureConstructorOptions ? FeatureConstructorOptions[TKey] : never : any }[keyof TFeatures]>; ``` Defined in: [types/TableFeatures.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L10) ## Type Parameters ### TKey `TKey` *extends* keyof `FeatureConstructors` ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ================================================ FILE: docs/reference/type-aliases/FilterFnOption.md ================================================ --- id: FilterFnOption title: FilterFnOption --- # Type Alias: FilterFnOption\ ```ts type FilterFnOption = | "auto" | BuiltInFilterFn | keyof FilterFns | FilterFn; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:76](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L76) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/GetDefaultColumnDef.md ================================================ --- id: GetDefaultColumnDef title: GetDefaultColumnDef --- # Type Alias: GetDefaultColumnDef()\ ```ts type GetDefaultColumnDef = () => ColumnDefBase_All & Partial; ``` Defined in: [types/TableFeatures.ts:55](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L55) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ## Returns [`ColumnDefBase_All`](ColumnDefBase_All.md)\<`TFeatures`, `TData`, `TValue`\> & `Partial`\<`TConstructors`\[`"ColumnDef"`\]\> ================================================ FILE: docs/reference/type-aliases/GetDefaultStateSelector.md ================================================ --- id: GetDefaultStateSelector title: GetDefaultStateSelector --- # Type Alias: GetDefaultStateSelector()\ ```ts type GetDefaultStateSelector = (state) => Partial & Partial; ``` Defined in: [types/TableFeatures.ts:72](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L72) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Parameters ### state [`TableState_All`](TableState_All.md) ## Returns `Partial`\<[`TableState_All`](TableState_All.md)\> & `Partial`\<`TConstructors`\[`"TableState"`\]\> ================================================ FILE: docs/reference/type-aliases/GetDefaultTableOptions.md ================================================ --- id: GetDefaultTableOptions title: GetDefaultTableOptions --- # Type Alias: GetDefaultTableOptions()\ ```ts type GetDefaultTableOptions = (table) => Partial> & Partial; ``` Defined in: [types/TableFeatures.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L62) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### table [`Table_Internal`](Table_Internal.md)\<`TFeatures`, `TData`\> & `Partial`\<`TConstructors`\[`"Table"`\]\> ## Returns `Partial`\<[`TableOptions_All`](TableOptions_All.md)\<`TFeatures`, `TData`\>\> & `Partial`\<`TConstructors`\[`"TableOptions"`\]\> ================================================ FILE: docs/reference/type-aliases/GetInitialState.md ================================================ --- id: GetInitialState title: GetInitialState --- # Type Alias: GetInitialState()\ ```ts type GetInitialState = (initialState) => TableState_All & Partial; ``` Defined in: [types/TableFeatures.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L68) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Parameters ### initialState `Partial`\<[`TableState_All`](TableState_All.md)\> & `Partial`\<`TConstructors`\[`"TableState"`\]\> ## Returns [`TableState_All`](TableState_All.md) & `Partial`\<`TConstructors`\[`"TableState"`\]\> ================================================ FILE: docs/reference/type-aliases/Getter.md ================================================ --- id: Getter title: Getter --- # Type Alias: Getter()\ ```ts type Getter = () => NoInfer; ``` Defined in: [types/type-utils.ts:80](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L80) ## Type Parameters ### TValue `TValue` ## Type Parameters ### TTValue `TTValue` = `TValue` ## Returns [`NoInfer`](NoInfer.md)\<`TTValue`\> ================================================ FILE: docs/reference/type-aliases/GroupColumnDef.md ================================================ --- id: GroupColumnDef title: GroupColumnDef --- # Type Alias: GroupColumnDef\ ```ts type GroupColumnDef = GroupColumnDefBase & ColumnIdentifiers; ``` Defined in: [types/ColumnDef.ts:156](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L156) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/GroupingColumnMode.md ================================================ --- id: GroupingColumnMode title: GroupingColumnMode --- # Type Alias: GroupingColumnMode ```ts type GroupingColumnMode = false | "reorder" | "remove"; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:171](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L171) ================================================ FILE: docs/reference/type-aliases/GroupingState.md ================================================ --- id: GroupingState title: GroupingState --- # Type Alias: GroupingState ```ts type GroupingState = string[]; ``` Defined in: [features/column-grouping/columnGroupingFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts#L15) ================================================ FILE: docs/reference/type-aliases/Header.md ================================================ --- id: Header title: Header --- # Type Alias: Header\ ```ts type Header = Header_Core & UnionToIntersection< | "columnSizingFeature" extends keyof TFeatures ? Header_ColumnSizing : never | "columnResizingFeature" extends keyof TFeatures ? Header_ColumnResizing : never> & ExtractFeatureTypes<"Header", TFeatures> & Header_Plugins; ``` Defined in: [types/Header.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Header.ts#L23) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/HeaderGroup.md ================================================ --- id: HeaderGroup title: HeaderGroup --- # Type Alias: HeaderGroup\ ```ts type HeaderGroup = HeaderGroup_Core & ExtractFeatureTypes<"HeaderGroup", TFeatures> & HeaderGroup_Plugins; ``` Defined in: [types/HeaderGroup.ts:19](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/HeaderGroup.ts#L19) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/IdentifiedColumnDef.md ================================================ --- id: IdentifiedColumnDef title: IdentifiedColumnDef --- # Type Alias: IdentifiedColumnDef\ ```ts type IdentifiedColumnDef = ColumnDefBase & object; ``` Defined in: [types/ColumnDef.ts:133](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L133) ## Type Declaration ### header? ```ts optional header: StringOrTemplateHeader; ``` ### id? ```ts optional id: string; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/InitRowInstanceData.md ================================================ --- id: InitRowInstanceData title: InitRowInstanceData --- # Type Alias: InitRowInstanceData()\ ```ts type InitRowInstanceData = (row) => void; ``` Defined in: [types/TableFeatures.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableFeatures.ts#L109) ## Type Parameters ### TConstructors `TConstructors` *extends* `FeatureConstructors` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ## Parameters ### row [`Row`](Row.md)\<`TFeatures`, `TData`\> & `Partial`\<`TConstructors`\[`"Row"`\]\> ## Returns `void` ================================================ FILE: docs/reference/type-aliases/MemoFnMeta.md ================================================ --- id: MemoFnMeta title: MemoFnMeta --- # Type Alias: MemoFnMeta ```ts type MemoFnMeta = object; ``` Defined in: [utils.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L62) ## Properties ### originalArgsLength? ```ts optional originalArgsLength: number; ``` Defined in: [utils.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L62) ================================================ FILE: docs/reference/type-aliases/NoInfer.md ================================================ --- id: NoInfer title: NoInfer --- # Type Alias: NoInfer\ ```ts type NoInfer = [T][T extends any ? 0 : never]; ``` Defined in: [types/type-utils.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L78) ## Type Parameters ### T `T` ================================================ FILE: docs/reference/type-aliases/OnChangeFn.md ================================================ --- id: OnChangeFn title: OnChangeFn --- # Type Alias: OnChangeFn()\ ```ts type OnChangeFn = (updaterOrValue) => void; ``` Defined in: [types/type-utils.ts:3](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L3) ## Type Parameters ### T `T` ## Parameters ### updaterOrValue [`Updater`](Updater.md)\<`T`\> ## Returns `void` ================================================ FILE: docs/reference/type-aliases/PartialKeys.md ================================================ --- id: PartialKeys title: PartialKeys --- # Type Alias: PartialKeys\ ```ts type PartialKeys = Omit & Partial>; ``` Defined in: [types/type-utils.ts:9](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L9) ## Type Parameters ### T `T` ### K `K` *extends* keyof `T` ================================================ FILE: docs/reference/type-aliases/Prettify.md ================================================ --- id: Prettify title: Prettify --- # Type Alias: Prettify\ ```ts type Prettify = { [K in keyof T]: T[K] } & unknown; ``` Defined in: [types/type-utils.ts:82](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L82) ## Type Parameters ### T `T` ================================================ FILE: docs/reference/type-aliases/PrototypeAPIObject.md ================================================ --- id: PrototypeAPIObject title: PrototypeAPIObject --- # Type Alias: PrototypeAPIObject\ ```ts type PrototypeAPIObject = Record>; ``` Defined in: [utils.ts:327](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L327) ## Type Parameters ### TDeps `TDeps` *extends* `ReadonlyArray`\<`any`\> ### TDepArgs `TDepArgs` ================================================ FILE: docs/reference/type-aliases/RequiredKeys.md ================================================ --- id: RequiredKeys title: RequiredKeys --- # Type Alias: RequiredKeys\ ```ts type RequiredKeys = Omit & Required>; ``` Defined in: [types/type-utils.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L11) ## Type Parameters ### T `T` ### K `K` *extends* keyof `T` ================================================ FILE: docs/reference/type-aliases/Row.md ================================================ --- id: Row title: Row --- # Type Alias: Row\ ```ts type Row = Row_Core & UnionToIntersection< | "columnFilteringFeature" extends keyof TFeatures ? Row_ColumnFiltering : never | "columnGroupingFeature" extends keyof TFeatures ? Row_ColumnGrouping : never | "columnPinningFeature" extends keyof TFeatures ? Row_ColumnPinning : never | "columnVisibilityFeature" extends keyof TFeatures ? Row_ColumnVisibility : never | "rowExpandingFeature" extends keyof TFeatures ? Row_RowExpanding : never | "rowPinningFeature" extends keyof TFeatures ? Row_RowPinning : never | "rowSelectionFeature" extends keyof TFeatures ? Row_RowSelection : never> & ExtractFeatureTypes<"Row", TFeatures> & Row_Plugins; ``` Defined in: [types/Row.ts:26](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Row.ts#L26) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/RowData.md ================================================ --- id: RowData title: RowData --- # Type Alias: RowData ```ts type RowData = Record | any[]; ``` Defined in: [types/type-utils.ts:5](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L5) ================================================ FILE: docs/reference/type-aliases/RowModelFns.md ================================================ --- id: RowModelFns title: RowModelFns --- # Type Alias: RowModelFns\ ```ts type RowModelFns = Partial : never | "columnGroupingFeature" extends keyof TFeatures ? RowModelFns_ColumnGrouping : never | "rowSortingFeature" extends keyof TFeatures ? RowModelFns_RowSorting : never> & ExtractFeatureTypes<"RowModelFns", TFeatures> & RowModelFns_Plugins>; ``` Defined in: [types/RowModelFns.ts:18](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModelFns.ts#L18) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/RowModelFns_All.md ================================================ --- id: RowModelFns_All title: RowModelFns_All --- # Type Alias: RowModelFns\_All\ ```ts type RowModelFns_All = Partial & RowModelFns_ColumnGrouping & RowModelFns_RowSorting>; ``` Defined in: [types/RowModelFns.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/RowModelFns.ts#L44) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/RowPinningPosition.md ================================================ --- id: RowPinningPosition title: RowPinningPosition --- # Type Alias: RowPinningPosition ```ts type RowPinningPosition = false | "top" | "bottom"; ``` Defined in: [features/row-pinning/rowPinningFeature.types.ts:5](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts#L5) ================================================ FILE: docs/reference/type-aliases/RowSelectionState.md ================================================ --- id: RowSelectionState title: RowSelectionState --- # Type Alias: RowSelectionState ```ts type RowSelectionState = Record; ``` Defined in: [features/row-selection/rowSelectionFeature.types.ts:6](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts#L6) ================================================ FILE: docs/reference/type-aliases/SortDirection.md ================================================ --- id: SortDirection title: SortDirection --- # Type Alias: SortDirection ```ts type SortDirection = "asc" | "desc"; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L8) ================================================ FILE: docs/reference/type-aliases/SortFnOption.md ================================================ --- id: SortFnOption title: SortFnOption --- # Type Alias: SortFnOption\ ```ts type SortFnOption = | "auto" | keyof SortFns | BuiltInSortFn | SortFn; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:46](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L46) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/SortingState.md ================================================ --- id: SortingState title: SortingState --- # Type Alias: SortingState ```ts type SortingState = ColumnSort[]; ``` Defined in: [features/row-sorting/rowSortingFeature.types.ts:15](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts#L15) ================================================ FILE: docs/reference/type-aliases/StringOrTemplateHeader.md ================================================ --- id: StringOrTemplateHeader title: StringOrTemplateHeader --- # Type Alias: StringOrTemplateHeader\ ```ts type StringOrTemplateHeader = | string | ColumnDefTemplate>; ``` Defined in: [types/ColumnDef.ts:39](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/ColumnDef.ts#L39) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ================================================ FILE: docs/reference/type-aliases/Table.md ================================================ --- id: Table title: Table --- # Type Alias: Table\ ```ts type Table = Table_Core & UnionToIntersection< | "columnFilteringFeature" extends keyof TFeatures ? Table_ColumnFiltering : never | "columnGroupingFeature" extends keyof TFeatures ? Table_ColumnGrouping : never | "columnOrderingFeature" extends keyof TFeatures ? Table_ColumnOrdering : never | "columnPinningFeature" extends keyof TFeatures ? Table_ColumnPinning : never | "columnResizingFeature" extends keyof TFeatures ? Table_ColumnResizing : never | "columnSizingFeature" extends keyof TFeatures ? Table_ColumnSizing : never | "columnVisibilityFeature" extends keyof TFeatures ? Table_ColumnVisibility : never | "columnFacetingFeature" extends keyof TFeatures ? Table_ColumnFaceting : never | "globalFilteringFeature" extends keyof TFeatures ? Table_GlobalFiltering : never | "rowExpandingFeature" extends keyof TFeatures ? Table_RowExpanding : never | "rowPaginationFeature" extends keyof TFeatures ? Table_RowPagination : never | "rowPinningFeature" extends keyof TFeatures ? Table_RowPinning : never | "rowSelectionFeature" extends keyof TFeatures ? Table_RowSelection : never | "rowSortingFeature" extends keyof TFeatures ? Table_RowSorting : never> & ExtractFeatureTypes<"Table", TFeatures> & Table_Plugins; ``` Defined in: [types/Table.ts:53](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L53) The table object that includes both the core table functionality and the features that are enabled via the `_features` table option. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/TableHelperOptions.md ================================================ --- id: TableHelperOptions title: TableHelperOptions --- # Type Alias: TableHelperOptions\ ```ts type TableHelperOptions = Omit, "columns" | "data" | "store" | "state" | "initialState"> & object; ``` Defined in: [helpers/tableHelper.ts:12](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L12) Options for creating a table helper to share common options across multiple tables coreColumnsFeature, data, and state are excluded from this type and reserved for only the `useTable`/`createTable` functions ## Type Declaration ### \_features ```ts _features: TFeatures; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ================================================ FILE: docs/reference/type-aliases/TableHelper_Core.md ================================================ --- id: TableHelper_Core title: TableHelper_Core --- # Type Alias: TableHelper\_Core\ ```ts type TableHelper_Core = object; ``` Defined in: [helpers/tableHelper.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L22) Internal type that each adapter package will build off of to create a table helper ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ## Properties ### createColumnHelper() ```ts createColumnHelper: () => ColumnHelper; ``` Defined in: [helpers/tableHelper.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L23) #### Type Parameters ##### TData `TData` *extends* [`RowData`](RowData.md) #### Returns [`ColumnHelper`](ColumnHelper.md)\<`TFeatures`, `TData`\> *** ### features ```ts features: TFeatures; ``` Defined in: [helpers/tableHelper.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L27) *** ### options ```ts options: Omit, "columns" | "data" | "store" | "state" | "initialState">; ``` Defined in: [helpers/tableHelper.ts:28](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L28) *** ### tableCreator() ```ts tableCreator: (tableOptions, selector?) => Table; ``` Defined in: [helpers/tableHelper.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/helpers/tableHelper.ts#L32) #### Type Parameters ##### TData `TData` *extends* [`RowData`](RowData.md) #### Parameters ##### tableOptions `Omit`\<[`TableOptions`](TableOptions.md)\<`TFeatures`, `TData`\>, `"_features"` \| `"_rowModels"`\> ##### selector? `any` #### Returns [`Table`](Table.md)\<`TFeatures`, `TData`\> ================================================ FILE: docs/reference/type-aliases/TableOptions.md ================================================ --- id: TableOptions title: TableOptions --- # Type Alias: TableOptions\ ```ts type TableOptions = TableOptions_Core & UnionToIntersection< | "columnFilteringFeature" extends keyof TFeatures ? TableOptions_ColumnFiltering : never | "columnGroupingFeature" extends keyof TFeatures ? TableOptions_ColumnGrouping : never | "columnOrderingFeature" extends keyof TFeatures ? TableOptions_ColumnOrdering : never | "columnPinningFeature" extends keyof TFeatures ? TableOptions_ColumnPinning : never | "columnResizingFeature" extends keyof TFeatures ? TableOptions_ColumnResizing : never | "columnSizingFeature" extends keyof TFeatures ? TableOptions_ColumnSizing : never | "columnVisibilityFeature" extends keyof TFeatures ? TableOptions_ColumnVisibility : never | "globalFilteringFeature" extends keyof TFeatures ? TableOptions_GlobalFiltering : never | "rowExpandingFeature" extends keyof TFeatures ? TableOptions_RowExpanding : never | "rowPaginationFeature" extends keyof TFeatures ? TableOptions_RowPagination : never | "rowPinningFeature" extends keyof TFeatures ? TableOptions_RowPinning : never | "rowSelectionFeature" extends keyof TFeatures ? TableOptions_RowSelection : never | "rowSortingFeature" extends keyof TFeatures ? TableOptions_RowSorting : never> & ExtractFeatureTypes<"TableOptions", TFeatures> & TableOptions_Plugins & DebugOptions; ``` Defined in: [types/TableOptions.ts:51](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableOptions.ts#L51) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/TableOptions_All.md ================================================ --- id: TableOptions_All title: TableOptions_All --- # Type Alias: TableOptions\_All\ ```ts type TableOptions_All = TableOptions_Core & Partial & TableOptions_ColumnGrouping & TableOptions_ColumnOrdering & TableOptions_ColumnPinning & TableOptions_ColumnResizing & TableOptions_ColumnSizing & TableOptions_ColumnVisibility & TableOptions_GlobalFiltering & TableOptions_RowExpanding & TableOptions_RowPagination & TableOptions_RowPinning & TableOptions_RowSelection & TableOptions_RowSorting>; ``` Defined in: [types/TableOptions.ts:107](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableOptions.ts#L107) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/TableState.md ================================================ --- id: TableState title: TableState --- # Type Alias: TableState\ ```ts type TableState = UnionToIntersection< | "columnFilteringFeature" extends keyof TFeatures ? TableState_ColumnFiltering : never | "columnGroupingFeature" extends keyof TFeatures ? TableState_ColumnGrouping : never | "columnOrderingFeature" extends keyof TFeatures ? TableState_ColumnOrdering : never | "columnPinningFeature" extends keyof TFeatures ? TableState_ColumnPinning : never | "columnResizingFeature" extends keyof TFeatures ? TableState_ColumnResizing : never | "columnSizingFeature" extends keyof TFeatures ? TableState_ColumnSizing : never | "columnVisibilityFeature" extends keyof TFeatures ? TableState_ColumnVisibility : never | "globalFilteringFeature" extends keyof TFeatures ? TableState_GlobalFiltering : never | "rowExpandingFeature" extends keyof TFeatures ? TableState_RowExpanding : never | "rowPaginationFeature" extends keyof TFeatures ? TableState_RowPagination : never | "rowPinningFeature" extends keyof TFeatures ? TableState_RowPinning : never | "rowSelectionFeature" extends keyof TFeatures ? TableState_RowSelection : never | "rowSortingFeature" extends keyof TFeatures ? TableState_RowSorting : never> & ExtractFeatureTypes<"TableState", TFeatures> & TableState_Plugins; ``` Defined in: [types/TableState.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableState.ts#L23) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ================================================ FILE: docs/reference/type-aliases/TableState_All.md ================================================ --- id: TableState_All title: TableState_All --- # Type Alias: TableState\_All ```ts type TableState_All = Partial; ``` Defined in: [types/TableState.ts:74](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/TableState.ts#L74) ================================================ FILE: docs/reference/type-aliases/Table_Core.md ================================================ --- id: Table_Core title: Table_Core --- # Type Alias: Table\_Core\ ```ts type Table_Core = Table_Table & Table_Columns & Table_Rows & Table_RowModels & Table_Headers; ``` Defined in: [types/Table.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L41) The core table object that only includes the core table functionality such as column, header, row, and table APIS. No features are included. ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/Table_Internal.md ================================================ --- id: Table_Internal title: Table_Internal --- # Type Alias: Table\_Internal\ ```ts type Table_Internal = Table & object; ``` Defined in: [types/Table.ts:111](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/Table.ts#L111) ## Type Declaration ### \_rowModelFns ```ts _rowModelFns: RowModelFns_All; ``` ### \_rowModels ```ts _rowModels: CachedRowModel_All; ``` ### baseStore ```ts baseStore: Store; ``` ### initialState ```ts initialState: TableState_All; ``` ### options ```ts options: TableOptions_All & object; ``` #### Type Declaration ##### \_rowModels? ```ts optional _rowModels: CreateRowModels_All; ``` ##### initialState? ```ts optional initialState: TableState_All; ``` ##### state? ```ts optional state: TableState_All; ``` ### store ```ts store: ReadonlyStore; ``` ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) = `any` ================================================ FILE: docs/reference/type-aliases/Table_RowModels.md ================================================ --- id: Table_RowModels title: Table_RowModels --- # Type Alias: Table\_RowModels\ ```ts type Table_RowModels = Table_RowModels_Core & Table_RowModels_Faceted & Table_RowModels_Filtered & Table_RowModels_Grouped & Table_RowModels_Expanded & Table_RowModels_Paginated & Table_RowModels_Sorted; ``` Defined in: [core/row-models/coreRowModelsFeature.types.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts#L58) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ================================================ FILE: docs/reference/type-aliases/TransformFilterValueFn.md ================================================ --- id: TransformFilterValueFn title: TransformFilterValueFn --- # Type Alias: TransformFilterValueFn()\ ```ts type TransformFilterValueFn = (value, column?) => TValue; ``` Defined in: [features/column-filtering/columnFilteringFeature.types.ts:59](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts#L59) ## Type Parameters ### TFeatures `TFeatures` *extends* [`TableFeatures`](../interfaces/TableFeatures.md) ### TData `TData` *extends* [`RowData`](RowData.md) ### TValue `TValue` *extends* [`CellData`](CellData.md) = [`CellData`](CellData.md) ## Parameters ### value `any` ### column? [`Column`](Column.md)\<`TFeatures`, `TData`, `TValue`\> ## Returns `TValue` ================================================ FILE: docs/reference/type-aliases/UnionToIntersection.md ================================================ --- id: UnionToIntersection title: UnionToIntersection --- # Type Alias: UnionToIntersection\ ```ts type UnionToIntersection = T extends any ? (x) => any : never extends (x) => any ? R : never; ``` Defined in: [types/type-utils.ts:14](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L14) ## Type Parameters ### T `T` ================================================ FILE: docs/reference/type-aliases/Updater.md ================================================ --- id: Updater title: Updater --- # Type Alias: Updater\ ```ts type Updater = T | (old) => T; ``` Defined in: [types/type-utils.ts:1](https://github.com/TanStack/table/blob/main/packages/table-core/src/types/type-utils.ts#L1) ## Type Parameters ### T `T` ================================================ FILE: docs/reference/type-aliases/VisibilityDefaultOptions.md ================================================ --- id: VisibilityDefaultOptions title: VisibilityDefaultOptions --- # Type Alias: VisibilityDefaultOptions ```ts type VisibilityDefaultOptions = Pick; ``` Defined in: [features/column-visibility/columnVisibilityFeature.types.ts:23](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts#L23) ================================================ FILE: docs/reference/variables/$internalMemoFnMeta.md ================================================ --- id: $internalMemoFnMeta title: $internalMemoFnMeta --- # Variable: $internalMemoFnMeta ```ts const $internalMemoFnMeta: typeof $internalMemoFnMeta; ``` Defined in: [utils.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/utils.ts#L61) ================================================ FILE: docs/reference/variables/aggregationFn_count.md ================================================ --- id: aggregationFn_count title: aggregationFn_count --- # Variable: aggregationFn\_count ```ts const aggregationFn_count: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:198](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L198) Aggregation function for counting the number of rows in a column. ================================================ FILE: docs/reference/variables/aggregationFn_extent.md ================================================ --- id: aggregationFn_extent title: aggregationFn_extent --- # Variable: aggregationFn\_extent ```ts const aggregationFn_extent: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L84) Aggregation function for finding the extent (min and max) of a column. ================================================ FILE: docs/reference/variables/aggregationFn_max.md ================================================ --- id: aggregationFn_max title: aggregationFn_max --- # Variable: aggregationFn\_max ```ts const aggregationFn_max: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L57) Aggregation function for finding the maximum value of a column. ================================================ FILE: docs/reference/variables/aggregationFn_mean.md ================================================ --- id: aggregationFn_mean title: aggregationFn_mean --- # Variable: aggregationFn\_mean ```ts const aggregationFn_mean: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L113) Aggregation function for finding the mean (average) of a column. ================================================ FILE: docs/reference/variables/aggregationFn_median.md ================================================ --- id: aggregationFn_median title: aggregationFn_median --- # Variable: aggregationFn\_median ```ts const aggregationFn_median: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L145) Aggregation function for finding the median value of a column. ================================================ FILE: docs/reference/variables/aggregationFn_min.md ================================================ --- id: aggregationFn_min title: aggregationFn_min --- # Variable: aggregationFn\_min ```ts const aggregationFn_min: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:29](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L29) Aggregation function for finding the minimum value of a column. ================================================ FILE: docs/reference/variables/aggregationFn_sum.md ================================================ --- id: aggregationFn_sum title: aggregationFn_sum --- # Variable: aggregationFn\_sum ```ts const aggregationFn_sum: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:10](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L10) Aggregation function for summing up the values of a column. ================================================ FILE: docs/reference/variables/aggregationFn_unique.md ================================================ --- id: aggregationFn_unique title: aggregationFn_unique --- # Variable: aggregationFn\_unique ```ts const aggregationFn_unique: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:172](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L172) Aggregation function for finding the unique values of a column. ================================================ FILE: docs/reference/variables/aggregationFn_uniqueCount.md ================================================ --- id: aggregationFn_uniqueCount title: aggregationFn_uniqueCount --- # Variable: aggregationFn\_uniqueCount ```ts const aggregationFn_uniqueCount: AggregationFn; ``` Defined in: [fns/aggregationFns.ts:185](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L185) Aggregation function for finding the count of unique values of a column. ================================================ FILE: docs/reference/variables/aggregationFns.md ================================================ --- id: aggregationFns title: aggregationFns --- # Variable: aggregationFns ```ts const aggregationFns: object; ``` Defined in: [fns/aggregationFns.ts:208](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/aggregationFns.ts#L208) ## Type Declaration ### count ```ts count: AggregationFn = aggregationFn_count; ``` ### extent ```ts extent: AggregationFn = aggregationFn_extent; ``` ### max ```ts max: AggregationFn = aggregationFn_max; ``` ### mean ```ts mean: AggregationFn = aggregationFn_mean; ``` ### median ```ts median: AggregationFn = aggregationFn_median; ``` ### min ```ts min: AggregationFn = aggregationFn_min; ``` ### sum ```ts sum: AggregationFn = aggregationFn_sum; ``` ### unique ```ts unique: AggregationFn = aggregationFn_unique; ``` ### uniqueCount ```ts uniqueCount: AggregationFn = aggregationFn_uniqueCount; ``` ================================================ FILE: docs/reference/variables/columnFacetingFeature.md ================================================ --- id: columnFacetingFeature title: columnFacetingFeature --- # Variable: columnFacetingFeature ```ts const columnFacetingFeature: TableFeature>; ``` Defined in: [features/column-faceting/columnFacetingFeature.ts:112](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts#L112) The Column Faceting feature adds column faceting APIs to the column objects. ================================================ FILE: docs/reference/variables/columnFilteringFeature.md ================================================ --- id: columnFilteringFeature title: columnFilteringFeature --- # Variable: columnFilteringFeature ```ts const columnFilteringFeature: TableFeature>; ``` Defined in: [features/column-filtering/columnFilteringFeature.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-filtering/columnFilteringFeature.ts#L121) The Column Filtering feature adds column filtering state and APIs to the table, row, and column objects. **Note:** This does not include Global Filtering. The globalFilteringFeature feature has been split out into its own standalone feature. ================================================ FILE: docs/reference/variables/columnGroupingFeature.md ================================================ --- id: columnGroupingFeature title: columnGroupingFeature --- # Variable: columnGroupingFeature ```ts const columnGroupingFeature: TableFeature>; ``` Defined in: [features/column-grouping/columnGroupingFeature.ts:151](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-grouping/columnGroupingFeature.ts#L151) The (Column) Grouping feature adds column grouping state and APIs to the table, row, column, and cell objects. ================================================ FILE: docs/reference/variables/columnOrderingFeature.md ================================================ --- id: columnOrderingFeature title: columnOrderingFeature --- # Variable: columnOrderingFeature ```ts const columnOrderingFeature: TableFeature>; ``` Defined in: [features/column-ordering/columnOrderingFeature.ts:96](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts#L96) The Column Ordering feature adds column ordering state and APIs to the table and column objects. ================================================ FILE: docs/reference/variables/columnPinningFeature.md ================================================ --- id: columnPinningFeature title: columnPinningFeature --- # Variable: columnPinningFeature ```ts const columnPinningFeature: TableFeature>; ``` Defined in: [features/column-pinning/columnPinningFeature.ts:324](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-pinning/columnPinningFeature.ts#L324) The Column Pinning feature adds column pinning state and APIs to the table, row, and column objects. ================================================ FILE: docs/reference/variables/columnResizingFeature.md ================================================ --- id: columnResizingFeature title: columnResizingFeature --- # Variable: columnResizingFeature ```ts const columnResizingFeature: TableFeature>; ``` Defined in: [features/column-resizing/columnResizingFeature.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-resizing/columnResizingFeature.ts#L92) The Column Resizing feature adds column resizing state and APIs to the table and column objects. **Note:** This is dependent on the Column Sizing feature. ================================================ FILE: docs/reference/variables/columnSizingFeature.md ================================================ --- id: columnSizingFeature title: columnSizingFeature --- # Variable: columnSizingFeature ```ts const columnSizingFeature: TableFeature>; ``` Defined in: [features/column-sizing/columnSizingFeature.ts:146](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-sizing/columnSizingFeature.ts#L146) The Column Sizing feature adds column sizing state and APIs to the table, header, and column objects. **Note:** This does not include column resizing. The columnResizingFeature feature has been split out into its own standalone feature. ================================================ FILE: docs/reference/variables/columnVisibilityFeature.md ================================================ --- id: columnVisibilityFeature title: columnVisibilityFeature --- # Variable: columnVisibilityFeature ```ts const columnVisibilityFeature: TableFeature>; ``` Defined in: [features/column-visibility/columnVisibilityFeature.ts:155](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts#L155) The Column Visibility feature adds column visibility state and APIs to the table, row, and column objects. ================================================ FILE: docs/reference/variables/coreCellsFeature.md ================================================ --- id: coreCellsFeature title: coreCellsFeature --- # Variable: coreCellsFeature ```ts const coreCellsFeature: TableFeature>; ``` Defined in: [core/cells/coreCellsFeature.ts:44](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/cells/coreCellsFeature.ts#L44) The Core Cells feature provides the core cell functionality. ================================================ FILE: docs/reference/variables/coreColumnsFeature.md ================================================ --- id: coreColumnsFeature title: coreColumnsFeature --- # Variable: coreColumnsFeature ```ts const coreColumnsFeature: TableFeature>; ``` Defined in: [core/columns/coreColumnsFeature.ts:90](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/columns/coreColumnsFeature.ts#L90) The Core Columns feature provides the core column functionality. ================================================ FILE: docs/reference/variables/coreFeatures.md ================================================ --- id: coreFeatures title: coreFeatures --- # Variable: coreFeatures ```ts const coreFeatures: CoreFeatures; ``` Defined in: [core/coreFeatures.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/coreFeatures.ts#L17) ================================================ FILE: docs/reference/variables/coreHeadersFeature.md ================================================ --- id: coreHeadersFeature title: coreHeadersFeature --- # Variable: coreHeadersFeature ```ts const coreHeadersFeature: TableFeature>; ``` Defined in: [core/headers/coreHeadersFeature.ts:98](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/headers/coreHeadersFeature.ts#L98) The Core Headers feature provides the core header functionality. ================================================ FILE: docs/reference/variables/coreRowModelsFeature.md ================================================ --- id: coreRowModelsFeature title: coreRowModelsFeature --- # Variable: coreRowModelsFeature ```ts const coreRowModelsFeature: TableFeature>; ``` Defined in: [core/row-models/coreRowModelsFeature.ts:78](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/row-models/coreRowModelsFeature.ts#L78) The Core Row Models feature provides the core row model functionality. ================================================ FILE: docs/reference/variables/coreRowsFeature.md ================================================ --- id: coreRowsFeature title: coreRowsFeature --- # Variable: coreRowsFeature ```ts const coreRowsFeature: TableFeature>; ``` Defined in: [core/rows/coreRowsFeature.ts:84](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.ts#L84) The Core Rows feature provides the core row functionality. ================================================ FILE: docs/reference/variables/coreTablesFeature.md ================================================ --- id: coreTablesFeature title: coreTablesFeature --- # Variable: coreTablesFeature ```ts const coreTablesFeature: TableFeature>; ``` Defined in: [core/table/coreTablesFeature.ts:36](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/table/coreTablesFeature.ts#L36) The Core Tables feature provides the core table functionality for handling state and options. ================================================ FILE: docs/reference/variables/filterFn_arrHas.md ================================================ --- id: filterFn_arrHas title: filterFn_arrHas --- # Variable: filterFn\_arrHas ```ts const filterFn_arrHas: FilterFn; ``` Defined in: [fns/filterFns.ts:287](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L287) Filter function for checking if an array has a given value. ================================================ FILE: docs/reference/variables/filterFn_arrIncludes.md ================================================ --- id: filterFn_arrIncludes title: filterFn_arrIncludes --- # Variable: filterFn\_arrIncludes ```ts const filterFn_arrIncludes: FilterFn; ``` Defined in: [fns/filterFns.ts:301](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L301) Filter function for checking if an array includes a given value. ================================================ FILE: docs/reference/variables/filterFn_arrIncludesAll.md ================================================ --- id: filterFn_arrIncludesAll title: filterFn_arrIncludesAll --- # Variable: filterFn\_arrIncludesAll ```ts const filterFn_arrIncludesAll: FilterFn; ``` Defined in: [fns/filterFns.ts:321](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L321) Filter function for checking if an array includes all of the given values. ================================================ FILE: docs/reference/variables/filterFn_arrIncludesSome.md ================================================ --- id: filterFn_arrIncludesSome title: filterFn_arrIncludesSome --- # Variable: filterFn\_arrIncludesSome ```ts const filterFn_arrIncludesSome: FilterFn; ``` Defined in: [fns/filterFns.ts:340](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L340) Filter function for checking if an array includes any of the given values. ================================================ FILE: docs/reference/variables/filterFn_equals.md ================================================ --- id: filterFn_equals title: filterFn_equals --- # Variable: filterFn\_equals ```ts const filterFn_equals: FilterFn; ``` Defined in: [fns/filterFns.ts:11](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L11) Filter function for checking if a value is exactly equal to a given value. (JS === comparison) ================================================ FILE: docs/reference/variables/filterFn_equalsString.md ================================================ --- id: filterFn_equalsString title: filterFn_equalsString --- # Variable: filterFn\_equalsString ```ts const filterFn_equalsString: FilterFn; ``` Defined in: [fns/filterFns.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L85) Filter function for checking if a string is exactly equal to a given string. (Non-case-sensitive) ================================================ FILE: docs/reference/variables/filterFn_equalsStringSensitive.md ================================================ --- id: filterFn_equalsStringSensitive title: filterFn_equalsStringSensitive --- # Variable: filterFn\_equalsStringSensitive ```ts const filterFn_equalsStringSensitive: FilterFn; ``` Defined in: [fns/filterFns.ts:104](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L104) Filter function for checking if a string is exactly equal to a given string. (Case-sensitive) ================================================ FILE: docs/reference/variables/filterFn_greaterThan.md ================================================ --- id: filterFn_greaterThan title: filterFn_greaterThan --- # Variable: filterFn\_greaterThan ```ts const filterFn_greaterThan: FilterFn; ``` Defined in: [fns/filterFns.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L122) Filter function for checking if a number is greater than a given number. ================================================ FILE: docs/reference/variables/filterFn_greaterThanOrEqualTo.md ================================================ --- id: filterFn_greaterThanOrEqualTo title: filterFn_greaterThanOrEqualTo --- # Variable: filterFn\_greaterThanOrEqualTo ```ts const filterFn_greaterThanOrEqualTo: FilterFn; ``` Defined in: [fns/filterFns.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L149) Filter function for checking if a number is greater than or equal to a given number. ================================================ FILE: docs/reference/variables/filterFn_inNumberRange.md ================================================ --- id: filterFn_inNumberRange title: filterFn_inNumberRange --- # Variable: filterFn\_inNumberRange ```ts const filterFn_inNumberRange: FilterFn; ``` Defined in: [fns/filterFns.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L244) Filter function for checking if a number is within a given range. ================================================ FILE: docs/reference/variables/filterFn_includesString.md ================================================ --- id: filterFn_includesString title: filterFn_includesString --- # Variable: filterFn\_includesString ```ts const filterFn_includesString: FilterFn; ``` Defined in: [fns/filterFns.ts:63](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L63) Filter function for checking if a string includes a given substring. (Non-case-sensitive) ================================================ FILE: docs/reference/variables/filterFn_includesStringSensitive.md ================================================ --- id: filterFn_includesStringSensitive title: filterFn_includesStringSensitive --- # Variable: filterFn\_includesStringSensitive ```ts const filterFn_includesStringSensitive: FilterFn; ``` Defined in: [fns/filterFns.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L45) Filter function for checking if a string includes a given substring. (Case-sensitive) ================================================ FILE: docs/reference/variables/filterFn_lessThan.md ================================================ --- id: filterFn_lessThan title: filterFn_lessThan --- # Variable: filterFn\_lessThan ```ts const filterFn_lessThan: FilterFn; ``` Defined in: [fns/filterFns.ts:168](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L168) Filter function for checking if a number is less than a given number. ================================================ FILE: docs/reference/variables/filterFn_lessThanOrEqualTo.md ================================================ --- id: filterFn_lessThanOrEqualTo title: filterFn_lessThanOrEqualTo --- # Variable: filterFn\_lessThanOrEqualTo ```ts const filterFn_lessThanOrEqualTo: FilterFn; ``` Defined in: [fns/filterFns.ts:184](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L184) Filter function for checking if a number is less than or equal to a given number. ================================================ FILE: docs/reference/variables/filterFn_weakEquals.md ================================================ --- id: filterFn_weakEquals title: filterFn_weakEquals --- # Variable: filterFn\_weakEquals ```ts const filterFn_weakEquals: FilterFn; ``` Defined in: [fns/filterFns.ts:27](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L27) Filter function for checking if a value is weakly equal to a given value. (JS == comparison) ================================================ FILE: docs/reference/variables/filterFns.md ================================================ --- id: filterFns title: filterFns --- # Variable: filterFns ```ts const filterFns: object; ``` Defined in: [fns/filterFns.ts:358](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/filterFns.ts#L358) ## Type Declaration ### arrHas ```ts arrHas: FilterFn = filterFn_arrHas; ``` ### arrIncludes ```ts arrIncludes: FilterFn = filterFn_arrIncludes; ``` ### arrIncludesAll ```ts arrIncludesAll: FilterFn = filterFn_arrIncludesAll; ``` ### arrIncludesSome ```ts arrIncludesSome: FilterFn = filterFn_arrIncludesSome; ``` ### between ```ts between: FilterFn = filterFn_between; ``` ### betweenInclusive ```ts betweenInclusive: FilterFn = filterFn_betweenInclusive; ``` ### equals ```ts equals: FilterFn = filterFn_equals; ``` ### equalsString ```ts equalsString: FilterFn = filterFn_equalsString; ``` ### includesString ```ts includesString: FilterFn = filterFn_includesString; ``` ### includesStringSensitive ```ts includesStringSensitive: FilterFn = filterFn_includesStringSensitive; ``` ### inNumberRange ```ts inNumberRange: FilterFn = filterFn_inNumberRange; ``` ### weakEquals ```ts weakEquals: FilterFn = filterFn_weakEquals; ``` ================================================ FILE: docs/reference/variables/globalFilteringFeature.md ================================================ --- id: globalFilteringFeature title: globalFilteringFeature --- # Variable: globalFilteringFeature ```ts const globalFilteringFeature: TableFeature>; ``` Defined in: [features/global-filtering/globalFilteringFeature.ts:92](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/global-filtering/globalFilteringFeature.ts#L92) The Global Filtering feature adds global filtering state and APIs to the table and column objects. **Note:** This is dependent on the columnFilteringFeature feature. ================================================ FILE: docs/reference/variables/reSplitAlphaNumeric.md ================================================ --- id: reSplitAlphaNumeric title: reSplitAlphaNumeric --- # Variable: reSplitAlphaNumeric ```ts const reSplitAlphaNumeric: RegExp; ``` Defined in: [fns/sortFns.ts:6](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L6) ================================================ FILE: docs/reference/variables/rowExpandingFeature.md ================================================ --- id: rowExpandingFeature title: rowExpandingFeature --- # Variable: rowExpandingFeature ```ts const rowExpandingFeature: TableFeature>; ``` Defined in: [features/row-expanding/rowExpandingFeature.ts:122](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-expanding/rowExpandingFeature.ts#L122) The Row Expanding feature adds row expanding state and APIs to the table and row objects. ================================================ FILE: docs/reference/variables/rowPaginationFeature.md ================================================ --- id: rowPaginationFeature title: rowPaginationFeature --- # Variable: rowPaginationFeature ```ts const rowPaginationFeature: TableFeature>; ``` Defined in: [features/row-pagination/rowPaginationFeature.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pagination/rowPaginationFeature.ts#L121) The (Row) Pagination feature adds pagination state and APIs to the table object. ================================================ FILE: docs/reference/variables/rowPinningFeature.md ================================================ --- id: rowPinningFeature title: rowPinningFeature --- # Variable: rowPinningFeature ```ts const rowPinningFeature: TableFeature>; ``` Defined in: [features/row-pinning/rowPinningFeature.ts:121](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-pinning/rowPinningFeature.ts#L121) The Row Pinning feature adds row pinning state and APIs to the table and row objects. ================================================ FILE: docs/reference/variables/rowSelectionFeature.md ================================================ --- id: rowSelectionFeature title: rowSelectionFeature --- # Variable: rowSelectionFeature ```ts const rowSelectionFeature: TableFeature>; ``` Defined in: [features/row-selection/rowSelectionFeature.ts:164](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-selection/rowSelectionFeature.ts#L164) The Row Selection feature adds row selection state and APIs to the table and row objects. ================================================ FILE: docs/reference/variables/rowSortingFeature.md ================================================ --- id: rowSortingFeature title: rowSortingFeature --- # Variable: rowSortingFeature ```ts const rowSortingFeature: TableFeature>; ``` Defined in: [features/row-sorting/rowSortingFeature.ts:136](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/row-sorting/rowSortingFeature.ts#L136) The (Row) Sorting feature adds sorting state and APIs to the table and column objects. ================================================ FILE: docs/reference/variables/sortFn_alphanumeric.md ================================================ --- id: sortFn_alphanumeric title: sortFn_alphanumeric --- # Variable: sortFn\_alphanumeric ```ts const sortFn_alphanumeric: SortFn; ``` Defined in: [fns/sortFns.ts:8](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L8) ================================================ FILE: docs/reference/variables/sortFn_alphanumericCaseSensitive.md ================================================ --- id: sortFn_alphanumericCaseSensitive title: sortFn_alphanumericCaseSensitive --- # Variable: sortFn\_alphanumericCaseSensitive ```ts const sortFn_alphanumericCaseSensitive: SortFn; ``` Defined in: [fns/sortFns.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L22) ================================================ FILE: docs/reference/variables/sortFn_basic.md ================================================ --- id: sortFn_basic title: sortFn_basic --- # Variable: sortFn\_basic ```ts const sortFn_basic: SortFn; ``` Defined in: [fns/sortFns.ts:85](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L85) ================================================ FILE: docs/reference/variables/sortFn_datetime.md ================================================ --- id: sortFn_datetime title: sortFn_datetime --- # Variable: sortFn\_datetime ```ts const sortFn_datetime: SortFn; ``` Defined in: [fns/sortFns.ts:68](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L68) ================================================ FILE: docs/reference/variables/sortFn_text.md ================================================ --- id: sortFn_text title: sortFn_text --- # Variable: sortFn\_text ```ts const sortFn_text: SortFn; ``` Defined in: [fns/sortFns.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L38) ================================================ FILE: docs/reference/variables/sortFn_textCaseSensitive.md ================================================ --- id: sortFn_textCaseSensitive title: sortFn_textCaseSensitive --- # Variable: sortFn\_textCaseSensitive ```ts const sortFn_textCaseSensitive: SortFn; ``` Defined in: [fns/sortFns.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L54) ================================================ FILE: docs/reference/variables/sortFns.md ================================================ --- id: sortFns title: sortFns --- # Variable: sortFns ```ts const sortFns: object; ``` Defined in: [fns/sortFns.ts:164](https://github.com/TanStack/table/blob/main/packages/table-core/src/fns/sortFns.ts#L164) ## Type Declaration ### alphanumeric ```ts alphanumeric: SortFn = sortFn_alphanumeric; ``` ### alphanumericCaseSensitive ```ts alphanumericCaseSensitive: SortFn = sortFn_alphanumericCaseSensitive; ``` ### basic ```ts basic: SortFn = sortFn_basic; ``` ### datetime ```ts datetime: SortFn = sortFn_datetime; ``` ### text ```ts text: SortFn = sortFn_text; ``` ### textCaseSensitive ```ts textCaseSensitive: SortFn = sortFn_textCaseSensitive; ``` ================================================ FILE: docs/reference/variables/stockFeatures.md ================================================ --- id: stockFeatures title: stockFeatures --- # Variable: stockFeatures ```ts const stockFeatures: StockFeatures; ``` Defined in: [features/stockFeatures.ts:33](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/stockFeatures.ts#L33) ================================================ FILE: docs/vanilla.md ================================================ --- title: Vanilla TS/JS --- The `@tanstack/table-core` library contains the core logic for TanStack Table. If you are using a non-standard framework or don't have access to a framework, you can use the core library directly via TypeScript or JavaScript. ## `_createTable` Takes an `options` object and returns a table. ```tsx import { _createTable } from '@tanstack/table-core' const table = _createTable(options) ``` ================================================ FILE: eslint.config.js ================================================ // @ts-check // @ts-ignore Needed due to moduleResolution Node vs Bundler import { tanstackConfig } from '@tanstack/eslint-config' /** @type {any} */ const config = [ ...tanstackConfig, { name: 'tanstack/temp', rules: { 'no-case-declarations': 'off', 'no-shadow': 'off', '@typescript-eslint/naming-convention': 'off', '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-unnecessary-condition': 'warn', '@typescript-eslint/no-unsafe-function-type': 'off', }, }, ] export default config ================================================ FILE: examples/angular/basic/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/basic/README.md ================================================ # CustomPlugin This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/basic/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "basic": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "basic:build:production" }, "development": { "buildTarget": "basic:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/basic/package.json ================================================ { "name": "tanstack-table-example-angular-basic", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/basic/src/app/app.config.ts ================================================ import { provideRouter } from '@angular/router' import { provideBrowserGlobalErrorListeners } from '@angular/core' import { routes } from './app.routes' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners(), provideRouter(routes)], } ================================================ FILE: examples/angular/basic/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (footer of footerGroup.headers; track footer.id) { } }
{{ footer }}
================================================ FILE: examples/angular/basic/src/app/app.routes.ts ================================================ import type { Routes } from '@angular/router' export const routes: Routes = [] ================================================ FILE: examples/angular/basic/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, signal } from '@angular/core' import { FlexRender, injectTable, tableFeatures } from '@tanstack/angular-table' import type { ColumnDef } from '@tanstack/angular-table' // This example uses the classic standalone `injectTable` hook to create a table without the new `createTableHook` util. // 1. Define what the shape of your data will be for each row type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] // 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 _features = tableFeatures({}) // util method to create sharable TFeatures object/type // 4. Define the columns for your table. This uses the new `ColumnDef` type to define columns. // Alternatively, check out the createAppTable/createColumnHelper util for an even more type-safe way to define columns. const defaultColumns: Array> = [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (info) => info.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => `${info.getValue()}`, header: () => `Last Name`, footer: (info) => info.column.id, }, { accessorKey: 'age', header: () => 'Age', 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, }, ] @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(defaultData) // 5. Create the table instance with required _features, columns, and data table = injectTable(() => ({ _features, // new required option in V9. Tell the table which features you are importing and using (better tree-shaking) _rowModels: {}, // `Core` row model is now included by default, but you can still override it here data: this.data(), columns: defaultColumns, // ...other options here })) rerender() { this.data.set([...defaultData.sort(() => -1)]) } } ================================================ FILE: examples/angular/basic/src/index.html ================================================ Basic ================================================ FILE: examples/angular/basic/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/basic/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } .pagination-actions { margin: 10px; display: flex; gap: 10px; } ================================================ FILE: examples/angular/basic/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/basic/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/basic-app-table/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/basic-app-table/README.md ================================================ # CustomPlugin This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/basic-app-table/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "basic-app-table": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "basic-app-table:build:production" }, "development": { "buildTarget": "basic-app-table:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/basic-app-table/package.json ================================================ { "name": "tanstack-table-example-angular-basic-app-table", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/basic-app-table/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/basic-app-table/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (footer of footerGroup.headers; track footer.id) { } }
{{ footer }}
================================================ FILE: examples/angular/basic-app-table/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, signal } from '@angular/core' import { FlexRender, createTableHook } from '@tanstack/angular-table' // This example uses the new `createTableHook` method to create a re-usable table hook factory 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 lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 28, visits: 100, status: 'Single', progress: 70, }, ] // 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 { injectAppTable, createAppColumnHelper } = createTableHook({ _features: {}, _rowModels: {}, // client-side row models. `Core` row model is now included by default, but you can still override it here debugTable: true, }) // 4. Create a helper object to help define our columns const columnHelper = createAppColumnHelper() // 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, }), ]) @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(defaultData) // 6. Create the table instance with the required columns and data. // Features and row models are already defined in the createTableHook call above readonly table = injectAppTable(() => ({ columns, data: this.data(), // add additional table options here or in the createTableHook call above })) rerender() { this.data.set([...defaultData.sort(() => -1)]) } } ================================================ FILE: examples/angular/basic-app-table/src/index.html ================================================ Basic App Table ================================================ FILE: examples/angular/basic-app-table/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/basic-app-table/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } .pagination-actions { margin: 10px; display: flex; gap: 10px; } ================================================ FILE: examples/angular/basic-app-table/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/basic-app-table/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/column-ordering/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/column-ordering/README.md ================================================ # CustomPlugin This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/column-ordering/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "column-ordering": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "column-ordering:build:production" }, "development": { "buildTarget": "column-ordering:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/column-ordering/package.json ================================================ { "name": "tanstack-table-example-angular-column-ordering", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/column-ordering/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/column-ordering/src/app/app.html ================================================
@for (column of table.getAllLeafColumns(); track column.id) {
}
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (header of footerGroup.headers; track header.id) { } }
@if (!header.isPlaceholder) { {{ header }} }
{{ cell }}
@if (!header.isPlaceholder) { {{ header }} }
{{ stringifiedColumnOrdering() }}
================================================ FILE: examples/angular/column-ordering/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, columnOrderingFeature, columnVisibilityFeature, createColumnHelper, injectTable, tableFeatures, } from '@tanstack/angular-table' import { faker } from '@faker-js/faker' import { makeData } from './makeData' import type { Person } from './makeData' import type { ColumnOrderState, ColumnVisibilityState, } from '@tanstack/angular-table' const _features = tableFeatures({ columnVisibilityFeature, columnOrderingFeature, }) const columnHelper = createColumnHelper() const defaultColumns = columnHelper.columns([ columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor('lastName', { cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => 'Visits', footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(20)) readonly columnVisibility = signal({}) readonly columnOrder = signal([]) readonly table = injectTable(() => ({ _features, data: this.data(), columns: defaultColumns, state: { columnOrder: this.columnOrder(), columnVisibility: this.columnVisibility(), }, onColumnVisibilityChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.columnVisibility.update(updaterOrValue) : this.columnVisibility.set(updaterOrValue) }, onColumnOrderChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.columnOrder.update(updaterOrValue) : this.columnOrder.set(updaterOrValue) }, debugTable: true, debugHeaders: true, debugColumns: true, })) readonly stringifiedColumnOrdering = computed(() => { return JSON.stringify(this.table.state().columnOrder) }) randomizeColumns() { this.table.setColumnOrder( faker.helpers.shuffle(this.table.getAllLeafColumns().map((d) => d.id)), ) } rerender() { this.data.set([...makeData(20)]) } } ================================================ FILE: examples/angular/column-ordering/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/column-ordering/src/index.html ================================================ Basic ================================================ FILE: examples/angular/column-ordering/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/column-ordering/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/column-ordering/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/column-ordering/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/column-pinning/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/column-pinning/README.md ================================================ # Column Pinning This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/column-pinning/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "column-pinning": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "column-pinning:build:production" }, "development": { "buildTarget": "column-pinning:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/column-pinning/package.json ================================================ { "name": "tanstack-table-example-angular-column-pinning", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/column-pinning/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/column-pinning/src/app/app.html ================================================
@for (column of table.getAllLeafColumns(); track column.id) {
}
@if (split()) { @for (headerGroup of table.getLeftHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows | slice: 0 : 20; track row.id) { @for (cell of row.getLeftVisibleCells(); track cell.id) { } }
@if (!header.isPlaceholder) { {{ headerValue }} }
{{ cellValue }}
} @if (split() ? table.getCenterHeaderGroups() : table.getHeaderGroups(); as headerGroups) { @for (headerGroup of headerGroups; track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } } @for (row of table.getRowModel().rows | slice: 0 : 20; track row.id) { @if (split() ? row.getCenterVisibleCells() : row.getVisibleCells(); as cells) { @for (cell of cells; track cell.id) { } } }
@if (!header.isPlaceholder) { {{ headerValue }} }
{{ cellValue }}
@if (split()) { @for (headerGroup of table.getRightHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows | slice: 0 : 20; track row.id) { @for (cell of row.getRightVisibleCells(); track cell.id) { } }
@if (!header.isPlaceholder) { {{ headerValue }} }
{{ cellValue }}
}
{{ stringifiedColumnPinning() }}
@if (!header.isPlaceholder && header.column.getCanPin()) {
@if (header.column.getIsPinned() !== 'left') { } @if (header.column.getIsPinned()) { } @if (header.column.getIsPinned() !== 'right') { }
}
================================================ FILE: examples/angular/column-pinning/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRenderDirective, columnOrderingFeature, columnPinningFeature, columnVisibilityFeature, injectTable, tableFeatures, } from '@tanstack/angular-table' import { faker } from '@faker-js/faker' import { NgTemplateOutlet, SlicePipe } from '@angular/common' import { makeData } from './makeData' import type { Person } from './makeData' import type { ColumnDef, ColumnOrderState, ColumnPinningState, ColumnVisibilityState, } from '@tanstack/angular-table' const _features = tableFeatures({ columnPinningFeature, columnOrderingFeature, columnVisibilityFeature, }) const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => 'Visits', footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] @Component({ selector: 'app-root', imports: [FlexRenderDirective, SlicePipe, NgTemplateOutlet], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(5000)) readonly columnVisibility = signal({}) readonly columnOrder = signal([]) readonly columnPinning = signal({ left: [], right: [], }) readonly split = signal(false) table = injectTable(() => ({ _features, columns: defaultColumns, data: this.data(), state: { columnVisibility: this.columnVisibility(), columnOrder: this.columnOrder(), columnPinning: this.columnPinning(), }, onColumnVisibilityChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.columnVisibility.update(updaterOrValue) : this.columnVisibility.set(updaterOrValue) }, onColumnOrderChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.columnOrder.update(updaterOrValue) : this.columnOrder.set(updaterOrValue) }, onColumnPinningChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.columnPinning.update(updaterOrValue) : this.columnPinning.set(updaterOrValue) }, debugTable: true, debugHeaders: true, debugColumns: true, })) stringifiedColumnPinning = computed(() => { return JSON.stringify(this.table.state().columnPinning) }) randomizeColumns() { this.table.setColumnOrder( faker.helpers.shuffle(this.table.getAllLeafColumns().map((d) => d.id)), ) } rerender() { this.data.set(makeData(5000)) } } ================================================ FILE: examples/angular/column-pinning/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/column-pinning/src/index.html ================================================ Basic ================================================ FILE: examples/angular/column-pinning/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/column-pinning/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/column-pinning/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/column-pinning/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/column-pinning-sticky/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/column-pinning-sticky/README.md ================================================ # Column Pinning Sticky This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/column-pinning-sticky/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "column-pinning-sticky": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "column-pinning-sticky:build:production" }, "development": { "buildTarget": "column-pinning-sticky:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/column-pinning-sticky/package.json ================================================ { "name": "tanstack-table-example-angular-column-pinning-sticky", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/column-pinning-sticky/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/column-pinning-sticky/src/app/app.html ================================================
@for (column of table.getAllLeafColumns(); track column.id) {
}
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
@if (!header.isPlaceholder) { {{ headerValue }} } {{ header.column.getIndex(header.column.getIsPinned() || 'center') }}
@if (!header.isPlaceholder && header.column.getCanPin()) {
@if (header.column.getIsPinned() !== 'left') { } @if (header.column.getIsPinned()) { } @if (header.column.getIsPinned() !== 'right') { }
}
{{ cellValue }}
{{ stringifiedColumnPinning() }}
================================================ FILE: examples/angular/column-pinning-sticky/src/app/app.ts ================================================ import { Component, computed, signal } from '@angular/core' import { FlexRender, columnOrderingFeature, columnPinningFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, createColumnHelper, injectTable, tableFeatures, } from '@tanstack/angular-table' import { faker } from '@faker-js/faker' import { makeData } from './makeData' import type { Person } from './makeData' import type { Column, ColumnOrderState, ColumnPinningState, ColumnVisibilityState, } from '@tanstack/angular-table' const _features = tableFeatures({ columnOrderingFeature, columnPinningFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, }) const columnHelper = createColumnHelper() const defaultColumns = columnHelper.columns([ columnHelper.accessor('firstName', { id: 'firstName', header: 'First Name', cell: (info) => info.getValue(), footer: (props) => props.column.id, size: 180, }), columnHelper.accessor('lastName', { id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, size: 180, }), columnHelper.accessor('age', { id: 'age', header: 'Age', footer: (props) => props.column.id, size: 180, }), columnHelper.accessor('visits', { id: 'visits', header: 'Visits', footer: (props) => props.column.id, size: 180, }), columnHelper.accessor('status', { id: 'status', header: 'Status', footer: (props) => props.column.id, size: 180, }), columnHelper.accessor('progress', { id: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, size: 180, }), ]) @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', }) export class App { readonly columns = signal([...defaultColumns]) readonly data = signal>(makeData(30)) readonly columnVisibility = signal({}) readonly columnOrder = signal([]) readonly columnPinning = signal({ left: [], right: [], }) readonly split = signal(false) table = injectTable(() => ({ _features, columns: this.columns(), data: this.data(), debugTable: true, debugHeaders: true, debugColumns: true, columnResizeMode: 'onChange' as const, })) stringifiedColumnPinning = computed(() => { return JSON.stringify(this.table.state().columnPinning) }) readonly getCommonPinningStyles = ( column: Column, ): Record => { const isPinned = column.getIsPinned() const isLastLeftPinnedColumn = isPinned === 'left' && column.getIsLastColumn('left') const isFirstRightPinnedColumn = isPinned === 'right' && column.getIsFirstColumn('right') return { boxShadow: isLastLeftPinnedColumn ? '-4px 0 4px -4px gray inset' : isFirstRightPinnedColumn ? '4px 0 4px -4px gray inset' : undefined, left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined, right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined, opacity: isPinned ? 0.95 : 1, position: isPinned ? 'sticky' : 'relative', width: `${column.getSize()}px`, zIndex: isPinned ? 1 : 0, } } randomizeColumns() { this.table.setColumnOrder( faker.helpers.shuffle(this.table.getAllLeafColumns().map((d) => d.id)), ) } rerender() { this.data.set(makeData(30)) } } ================================================ FILE: examples/angular/column-pinning-sticky/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/column-pinning-sticky/src/index.html ================================================ Column Pinning Sticky ================================================ FILE: examples/angular/column-pinning-sticky/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/column-pinning-sticky/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } .table-container { border: 1px solid lightgray; overflow-x: scroll; width: 100%; max-width: 960px; position: relative; } table { /* box-shadow and borders will not work with position: sticky otherwise */ border-collapse: separate !important; border-spacing: 0; } th { background-color: lightgray; border-bottom: 1px solid lightgray; font-weight: bold; height: 30px; padding: 2px 4px; position: relative; text-align: center; } td { background-color: white; padding: 2px 4px; } .resizer { background: rgba(0, 0, 0, 0.5); cursor: col-resize; height: 100%; position: absolute; right: 0; top: 0; touch-action: none; user-select: none; width: 5px; } .resizer.isResizing { background: blue; opacity: 1; } ================================================ FILE: examples/angular/column-pinning-sticky/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/column-pinning-sticky/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/column-resizing-performant/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/column-resizing-performant/README.md ================================================ # Column Resizing Performant This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/column-resizing-performant/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "column-pinning-sticky": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "column-pinning-sticky:build:production" }, "development": { "buildTarget": "column-pinning-sticky:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/column-resizing-performant/package.json ================================================ { "name": "tanstack-table-example-angular-column-resizing-performant", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/column-resizing-performant/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/column-resizing-performant/src/app/app.html ================================================
    {{ columnSizingDebugInfo() }}
  
({{ data().length }} rows)
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {
@for (header of headerGroup.headers; track header.id) {
@if (!header.isPlaceholder) {
}
}
}
@for (row of table.getRowModel().rows; track row.id) {
@for (cell of row.getAllCells(); track cell.id) {
}
}
================================================ FILE: examples/angular/column-resizing-performant/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, untracked, } from '@angular/core' import { FlexRender, columnResizingFeature, columnSizingFeature, injectTable, tableFeatures, } from '@tanstack/angular-table' import { makeData } from './makeData' import { TableResizableCells } from './resizable-cell/resizable-cell' import type { Person } from './makeData' import type { ColumnDef, ColumnResizeMode } from '@tanstack/angular-table' const _features = tableFeatures({ columnSizingFeature, columnResizingFeature, }) const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { accessorKey: 'visits', header: () => 'Visits', footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ] @Component({ selector: 'app-root', imports: [FlexRender, TableResizableCells], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(200)) readonly table = injectTable(() => ({ data: this.data(), _features, columns: defaultColumns, columnResizeMode: 'onChange' as ColumnResizeMode, defaultColumn: { minSize: 60, maxSize: 800, }, debugTable: true, debugHeaders: true, debugColumns: true, })) readonly columnSizing = this.table.computed({ selector: (state) => state.columnSizing, }) /** * Instead of calling `column.getSize()` on every render for every header * and especially every data cell (very expensive), * we will calculate all column sizes at once at the root table level in a useMemo * and pass the column sizes down as CSS variables to the element. */ readonly columnSizeVars = computed(() => { void this.columnSizing() const headers = untracked(() => this.table.getFlatHeaders()) const colSizes: { [key: string]: number } = {} let i = headers.length while (--i >= 0) { const header = headers[i] colSizes[`--header-${header.id}-size`] = header.getSize() colSizes[`--col-${header.column.id}-size`] = header.column.getSize() } return colSizes }) readonly columnSizingDebugInfo = computed(() => JSON.stringify( { columnSizing: this.columnSizing(), }, null, 2, ), ) } ================================================ FILE: examples/angular/column-resizing-performant/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/column-resizing-performant/src/app/resizable-cell/resizable-cell.ts ================================================ import { Directive, computed, input } from '@angular/core' @Directive({ selector: '[tableResizableHeader]', host: { '[style.width]': 'width()', }, standalone: true, }) export class TableResizableHeader { readonly cellId = input.required({ alias: 'tableResizableHeader', }) readonly width = computed( () => `calc(var(--header-${this.cellId()}-size) * 1px)`, ) } @Directive({ selector: '[tableResizableCell]', host: { '[style.width]': 'width()', }, standalone: true, }) export class TableResizableCell { readonly cellId = input.required({ alias: 'tableResizableCell', }) readonly width = computed( () => `calc(var(--col-${this.cellId()}-size) * 1px)`, ) } export const TableResizableCells = [ TableResizableCell, TableResizableHeader, ] as const ================================================ FILE: examples/angular/column-resizing-performant/src/index.html ================================================ Performant Column Resizing ================================================ FILE: examples/angular/column-resizing-performant/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/column-resizing-performant/src/styles.css ================================================ * { box-sizing: border-box; } html { font-family: sans-serif; font-size: 14px; } table, .divTable { display: block; border: 1px solid lightgray; width: fit-content; } .tr { display: flex; } tr, .tr { width: fit-content; height: 30px; } th, .th, td, .td { box-shadow: inset 0 0 0 1px lightgray; padding: 0.25rem; } th, .th { padding: 2px 4px; position: relative; font-weight: bold; text-align: center; height: 30px; } td, .td { height: 30px; } .resizer { position: absolute; top: 0; height: 100%; right: 0; width: 5px; background: rgba(0, 0, 0, 0.5); cursor: col-resize; user-select: none; touch-action: none; } .resizer.isResizing { background: blue; opacity: 1; } @media (hover: hover) { .resizer { opacity: 0; } *:hover > .resizer { opacity: 1; } } ================================================ FILE: examples/angular/column-resizing-performant/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/column-resizing-performant/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/column-visibility/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/column-visibility/README.md ================================================ # Column Visibility This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/column-visibility/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "column-visibility": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "column-visibility:build:production" }, "development": { "buildTarget": "column-visibility:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/column-visibility/package.json ================================================ { "name": "tanstack-table-example-angular-column-visibility", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/column-visibility/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/column-visibility/src/app/app.html ================================================
@for (column of table.getAllLeafColumns(); track column.id) {
}
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (header of footerGroup.headers; track header.id) { } }
@if (!header.isPlaceholder) { {{ header }} }
{{ cell }}
@if (!header.isPlaceholder) { {{ header }} }
{{ stringifiedColumnVisibility() }}
================================================ FILE: examples/angular/column-visibility/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, columnVisibilityFeature, injectTable, isFunction, tableFeatures, } from '@tanstack/angular-table' import type { ColumnDef, ColumnVisibilityState } from '@tanstack/angular-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const _features = tableFeatures({ columnVisibilityFeature, }) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => 'Visits', footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(defaultData) readonly columnVisibility = signal({}) readonly table = injectTable(() => ({ _features, columns: defaultColumns, data: this.data(), state: { columnVisibility: this.columnVisibility(), }, onColumnVisibilityChange: (updaterOrValue) => { const visibilityState = isFunction(updaterOrValue) ? updaterOrValue(this.columnVisibility()) : updaterOrValue this.columnVisibility.set(visibilityState) }, debugTable: true, debugHeaders: true, debugColumns: true, })) readonly stringifiedColumnVisibility = computed(() => { return JSON.stringify(this.table.state().columnVisibility) }) rerender() { this.data.update((data) => [...data.reverse()]) } } ================================================ FILE: examples/angular/column-visibility/src/index.html ================================================ Column Visibility ================================================ FILE: examples/angular/column-visibility/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/column-visibility/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } .pagination-actions { margin: 10px; display: flex; gap: 10px; } ================================================ FILE: examples/angular/column-visibility/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/column-visibility/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/composable-tables/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/composable-tables/README.md ================================================ # Composable Tables This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/composable-tables/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "composable-tables": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "composable-tables:build:production" }, "development": { "buildTarget": "composable-tables:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/composable-tables/package.json ================================================ { "name": "tanstack-table-example-angular-composable-tables", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/composable-tables/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/composable-tables/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component } from '@angular/core' import { UsersTable } from './components/users-table/users-table' import { ProductsTable } from './components/products-table/products-table' @Component({ selector: 'app-root', imports: [UsersTable, ProductsTable], host: { class: 'app', }, template: `

Composable Tables Example

Both tables below use the same injectAppTable function and shareable components, but with different data types and column configurations.

`, changeDetection: ChangeDetectionStrategy.OnPush, }) export class App {} ================================================ FILE: examples/angular/composable-tables/src/app/components/cell-components.ts ================================================ import { Component, computed } from '@angular/core' import { injectFlexRenderContext } from '@tanstack/angular-table' import { CurrencyPipe } from '@angular/common' import { injectTableCellContext } from '../table' import type { CellContext, TableFeatures } from '@tanstack/angular-table' import type { Person } from '../makeData' @Component({ // Using dynamic components with Angular, we can just put a simple selector // that will be rendered, but we need to specify an unique host property // that will identify this component selector: 'span', host: { 'tanstack-table-text-cell': '', }, template: ` {{ cell.getValue() }} `, }) export class TextCell { readonly cell = injectFlexRenderContext>() } @Component({ selector: 'span', host: { 'tanstack-table-number-cell': '', }, template: ` {{ cell.getValue().toLocaleString() }} `, }) export class NumberCell { readonly cell = injectFlexRenderContext>() } @Component({ selector: 'span', host: { 'tanstack-table-status-cell': '', '[class.status-badge]': 'true', '[class]': 'cell().getValue()', }, template: ` {{ cell().getValue() }} `, }) export class StatusCell { readonly cell = injectTableCellContext< 'relationship' | 'complicated' | 'single' >() } @Component({ selector: 'table-progress-cell', template: `
`, }) export class ProgressCell { readonly cell = injectTableCellContext() readonly progress = computed(() => this.cell().getValue()) } @Component({ selector: 'table-row-actions', template: `
`, }) export class RowActionsCell { readonly cell = injectTableCellContext() view() { alert( `View: ${this.cell().row.original.firstName} ${this.cell().row.original.lastName}`, ) } edit() { alert( `Edit: ${this.cell().row.original.firstName} ${this.cell().row.original.lastName}`, ) } delete() { alert( `Delete: ${this.cell().row.original.firstName} ${this.cell().row.original.lastName}`, ) } } @Component({ selector: 'table-price-cell', template: ` {{ cell().getValue() | currency }} `, imports: [CurrencyPipe], }) export class PriceCell { readonly cell = injectTableCellContext() } @Component({ selector: 'span', host: { 'tanstack-table-category-cell': '', '[class.category-badge]': 'true', '[class]': 'cell().getValue()', }, template: ` {{ cell().getValue() }} `, }) export class CategoryCell { readonly cell = injectTableCellContext< 'electronics' | 'clothing' | 'food' | 'books' >() } ================================================ FILE: examples/angular/composable-tables/src/app/components/header-components.ts ================================================ // export function SortIndicator() { // const header = useHeaderContext() // const sorted = header.column.getIsSorted() // // if (!sorted) return null // // return ( // {sorted === 'asc' ? '🔼' : '🔽'} // ) // } import { Component, computed } from '@angular/core' import { flexRenderComponent } from '@tanstack/angular-table' import { FormsModule } from '@angular/forms' import { injectTableHeaderContext } from '../table' import type { FlexRenderComponent } from '@tanstack/angular-table' export function SortIndicator(): string | null { const header = injectTableHeaderContext() const sorted = header().column.getIsSorted() if (!sorted) { return null } return `${sorted === 'asc' ? '🔼' : '🔽'}` } export function ColumnFilter(): FlexRenderComponent | null { const header = injectTableHeaderContext() if (!header().column.getCanFilter()) return null return flexRenderComponent(_ColumnFilter) } @Component({ template: `
`, imports: [FormsModule], }) export class _ColumnFilter { readonly header = injectTableHeaderContext() readonly filterValue = computed(() => this.header().column.getFilterValue()) readonly placeholder = computed(() => `Filter ${this.header().column.id}...`) } @Component({ selector: 'span', host: { 'tanstack-footer-column-id': '', class: 'footer-column-id', }, template: `{{ header().column.id }}`, }) export class FooterColumnId { readonly header = injectTableHeaderContext() } @Component({ selector: 'span', host: { 'tanstack-footer-sum': '', class: 'footer-sum', }, template: `{{ sum() > 0 ? sum().toLocaleString() : '—' }}`, }) export class FooterSum { readonly header = injectTableHeaderContext() readonly table = computed(() => this.header().getContext().table) readonly rows = computed(() => this.table().getFilteredRowModel().rows) readonly sum = computed(() => this.rows().reduce((acc, row) => { const value = row.getValue(this.header().column.id) return acc + (typeof value === 'number' ? value : 0) }, 0), ) } ================================================ FILE: examples/angular/composable-tables/src/app/components/products-table/products-table.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (_header of headerGroup.headers; track _header.id) { @let header = table.appHeader(_header); @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (footer of footerGroup.headers; track footer.id) { } }
{{ header }}
{{ cell }}
@if (!footer.isPlaceholder) { {{ footer }} }
================================================ FILE: examples/angular/composable-tables/src/app/components/products-table/products-table.ts ================================================ import { ChangeDetectionStrategy, Component, signal } from '@angular/core' import { NgComponentOutlet } from '@angular/common' import { FlexRender, TanStackTable, TanStackTableCell, TanStackTableHeader, } from '@tanstack/angular-table' import { makeProductData } from '../../makeData' import { createAppColumnHelper, injectAppTable } from '../../table' import type { Product } from '../../makeData' export const productColumnHelper = createAppColumnHelper() @Component({ selector: 'products-table', templateUrl: './products-table.html', imports: [ NgComponentOutlet, FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell, ], changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProductsTable { readonly data = signal(makeProductData(5000)) readonly columns = productColumnHelper.columns([ productColumnHelper.accessor('name', { header: 'Product Name', footer: (props) => props.column.id, cell: ({ cell }) => cell.TextCell, }), productColumnHelper.accessor('category', { header: 'Category', footer: (props) => props.column.id, cell: ({ cell }) => cell.CategoryCell, }), productColumnHelper.accessor('price', { header: 'Price', footer: (props) => props.column.id, cell: ({ cell }) => cell.PriceCell, }), productColumnHelper.accessor('stock', { header: 'In Stock', footer: (props) => props.column.id, cell: ({ cell }) => cell.NumberCell, }), productColumnHelper.accessor('rating', { header: 'Rating', footer: (props) => props.column.id, cell: ({ cell }) => cell.ProgressCell, }), ]) table = injectAppTable(() => ({ columns: this.columns, data: this.data(), getRowId: (row) => row.id, // more table options })) onRefresh = () => { this.data.set([...makeProductData(5000)]) } } ================================================ FILE: examples/angular/composable-tables/src/app/components/table-components.ts ================================================ import { ChangeDetectionStrategy, Component, computed, input, } from '@angular/core' import { injectTableContext } from '../table' @Component({ selector: 'app-table-toolbar', template: `

{{ title() }}

@if (onRefresh(); as onRefresh) { }
`, changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableToolbar { readonly title = input.required() readonly onRefresh = input<() => void>() readonly table = injectTableContext() constructor() { this.table().resetColumnFilters() } } @Component({ selector: 'app-row-count', template: `
Showing {{ length() }} of {{ rowCount() }} rows
`, changeDetection: ChangeDetectionStrategy.OnPush, }) export class RowCount { readonly table = injectTableContext() readonly length = computed(() => this.table().getRowModel().rows.length.toLocaleString(), ) readonly rowCount = computed(() => this.table().getRowCount().toLocaleString(), ) } /** * Pagination controls for the table */ @Component({ selector: 'app-pagination-controls', template: ` `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class PaginationControls { readonly table = injectTableContext() readonly pageSizes = [10, 20, 30, 40, 50] readonly canPreviousPage = computed(() => this.table().getCanPreviousPage()) readonly canNextPage = computed(() => this.table().getCanNextPage()) readonly pageIndex = computed(() => this.table().state().pagination.pageIndex) readonly pageSize = computed(() => this.table().state().pagination.pageSize) readonly pageCount = computed(() => this.table().getPageCount().toLocaleString(), ) onPageChange(event: Event) { const target = event.target as HTMLInputElement const page = target.value ? Number(target.value) - 1 : 0 this.table().setPageIndex(page) } onPageSizeChange(event: Event) { const target = event.target as HTMLSelectElement this.table().setPageSize(Number(target.value)) } } ================================================ FILE: examples/angular/composable-tables/src/app/components/users-table/users-table.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (_header of headerGroup.headers; track _header.id) { @let header = table.appHeader(_header); @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (footer of footerGroup.headers; track footer.id) { } }
{{ header }}
{{ cell }}
@if (!footer.isPlaceholder) { {{ footer }} }
================================================ FILE: examples/angular/composable-tables/src/app/components/users-table/users-table.ts ================================================ import { ChangeDetectionStrategy, Component, signal } from '@angular/core' import { NgComponentOutlet } from '@angular/common' import { FlexRender, TanStackTable, TanStackTableCell, TanStackTableHeader, flexRenderComponent, } from '@tanstack/angular-table' import { makeData } from '../../makeData' import { createAppColumnHelper, injectAppTable } from '../../table' import type { Person } from '../../makeData' export const personColumnHelper = createAppColumnHelper() @Component({ selector: 'users-table', templateUrl: './users-table.html', imports: [ NgComponentOutlet, FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell, ], changeDetection: ChangeDetectionStrategy.OnPush, }) export class UsersTable { readonly data = signal(makeData(5000)) readonly columns = personColumnHelper.columns([ personColumnHelper.accessor('firstName', { header: 'First Name', footer: ({ header }) => flexRenderComponent(header.FooterColumnId), cell: ({ cell }) => flexRenderComponent(cell.TextCell), }), personColumnHelper.accessor('lastName', { header: 'Last Name', footer: ({ header }) => flexRenderComponent(header.FooterColumnId), cell: ({ cell }) => flexRenderComponent(cell.TextCell), }), personColumnHelper.accessor('age', { header: 'Age', footer: ({ header }) => flexRenderComponent(header.FooterSum), cell: ({ cell }) => flexRenderComponent(cell.NumberCell), }), personColumnHelper.accessor('visits', { header: 'Visits', footer: ({ header }) => flexRenderComponent(header.FooterSum), cell: ({ cell }) => flexRenderComponent(cell.NumberCell), }), personColumnHelper.accessor('status', { header: 'Status', footer: ({ header }) => flexRenderComponent(header.FooterColumnId), cell: ({ cell }) => flexRenderComponent(cell.StatusCell), }), personColumnHelper.accessor('progress', { header: 'Progress', footer: ({ header }) => flexRenderComponent(header.FooterSum), cell: ({ cell }) => flexRenderComponent(cell.ProgressCell), }), personColumnHelper.display({ id: 'actions', header: 'Actions', cell: ({ cell }) => flexRenderComponent(cell.RowActionsCell), }), ]) table = injectAppTable(() => ({ columns: this.columns, data: this.data(), debugTable: true, // more table options })) onRefresh = () => { this.data.set([...makeData(5000)]) } } ================================================ FILE: examples/angular/composable-tables/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } export type Product = { id: string name: string category: 'electronics' | 'clothing' | 'food' | 'books' price: number stock: number rating: number } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } const newProduct = (): Product => { return { id: faker.string.uuid(), name: faker.commerce.productName(), category: faker.helpers.shuffle([ 'electronics', 'clothing', 'food', 'books', ])[0], price: parseFloat(faker.commerce.price({ min: 5, max: 500 })), stock: faker.number.int({ min: 0, max: 200 }), rating: faker.number.int({ min: 0, max: 100 }), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } export function makeProductData(count: number): Array { return range(count).map(() => newProduct()) } ================================================ FILE: examples/angular/composable-tables/src/app/table.ts ================================================ /** * Custom table hook setup using createTableHook * * This file creates a custom useAppTable hook with pre-bound components. * Features, row models, and default options are defined once here and shared across all tables. * Context hooks and a pre-bound createAppColumnHelper are also exported. */ import { columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, createTableHook, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/angular-table' // Import table-level components import { PaginationControls, RowCount, TableToolbar, } from './components/table-components' // Import cell-level components import { CategoryCell, NumberCell, PriceCell, ProgressCell, RowActionsCell, StatusCell, TextCell, } from './components/cell-components' // Import header-level components (both use injectTableHeaderContext()) import { ColumnFilter, FooterColumnId, FooterSum, SortIndicator, } from './components/header-components' /** * Create the custom table hook with all pre-bound components. * This exports: * - createAppColumnHelper: Create column definitions with TFeatures already bound * - injectAppTable: Function for creating tables with TFeatures baked in * - injectTableContext: Access table instance in tableComponents * - injectTableCellContext: Access cell instance in cellComponents * - injectTableHeaderContext: Access header instance in headerComponents * - injectFlexRenderHeaderContext: Access FlexRenderContext with header-level typings * - injectFlexRenderCellContext: Access FlexRenderContext with cell-level typings */ export const { createAppColumnHelper, injectAppTable, injectTableContext, injectTableCellContext, injectTableHeaderContext, // injectFlexRenderHeaderContext // injectFlexRenderCellContext } = createTableHook({ // Features are set once here and shared across all tables _features: tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }), // Row models are set once here _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, // set any default table options here too getRowId: (row) => row.id, // Register table-level components (accessible via table.ComponentName) tableComponents: { PaginationControls, RowCount, TableToolbar, }, // Register cell-level components (accessible via cell.ComponentName in AppCell) cellComponents: { TextCell, NumberCell, ProgressCell, StatusCell, CategoryCell, PriceCell, RowActionsCell, }, // Register header/footer-level components (accessible via header.ComponentName in AppHeader/AppFooter) headerComponents: { SortIndicator, ColumnFilter, FooterColumnId, FooterSum, }, }) ================================================ FILE: examples/angular/composable-tables/src/index.html ================================================ Composable tables ================================================ FILE: examples/angular/composable-tables/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/composable-tables/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; border-collapse: collapse; width: 100%; } tbody { border-bottom: 1px solid lightgray; } th, td { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 8px 12px; text-align: left; } th { background-color: #f5f5f5; font-weight: 600; } tfoot { color: gray; } tfoot th { font-weight: normal; } .table-container { padding: 16px; max-width: 1200px; margin: 0 auto; } .pagination { display: flex; align-items: center; gap: 8px; margin-top: 16px; flex-wrap: wrap; } .pagination button { border: 1px solid #ccc; border-radius: 4px; padding: 4px 8px; cursor: pointer; background: white; } .pagination button:disabled { opacity: 0.5; cursor: not-allowed; } .pagination input { border: 1px solid #ccc; border-radius: 4px; padding: 4px; width: 64px; } .pagination select { border: 1px solid #ccc; border-radius: 4px; padding: 4px; } .sort-indicator { margin-left: 4px; } .column-filter { margin-top: 4px; } .column-filter input { border: 1px solid #ccc; border-radius: 4px; padding: 4px; width: 100%; font-size: 12px; } .sortable-header { cursor: pointer; user-select: none; } .sortable-header:hover { background-color: #e8e8e8; } .row-actions { display: flex; gap: 4px; } .row-actions button { border: 1px solid #ccc; border-radius: 4px; padding: 2px 8px; cursor: pointer; background: white; font-size: 12px; } .row-actions button:hover { background-color: #f0f0f0; } .status-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; } .status-badge.relationship { background-color: #d4edda; color: #155724; } .status-badge.complicated { background-color: #fff3cd; color: #856404; } .status-badge.single { background-color: #cce5ff; color: #004085; } .progress-bar { width: 100%; height: 8px; background-color: #e9ecef; border-radius: 4px; overflow: hidden; } .progress-bar-fill { height: 100%; background-color: #007bff; transition: width 0.2s; } .table-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 8px; } .table-toolbar h2 { margin: 0; } .table-toolbar button { border: 1px solid #ccc; border-radius: 4px; padding: 8px 16px; cursor: pointer; background: white; } .table-toolbar button:hover { background-color: #f0f0f0; } .row-count { color: #666; font-size: 14px; margin-top: 8px; } .app { padding: 16px; } .app h1 { text-align: center; margin-bottom: 8px; } .description { text-align: center; color: #666; margin-bottom: 32px; } .description code { background-color: #f5f5f5; padding: 2px 6px; border-radius: 4px; font-size: 13px; } .table-divider { height: 48px; border-bottom: 1px solid #e0e0e0; margin: 32px auto; max-width: 1200px; } .category-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; text-transform: capitalize; } .category-badge.electronics { background-color: #e3f2fd; color: #1565c0; } .category-badge.clothing { background-color: #fce4ec; color: #c2185b; } .category-badge.food { background-color: #e8f5e9; color: #2e7d32; } .category-badge.books { background-color: #fff8e1; color: #f57c00; } .price { font-weight: 600; color: #2e7d32; } ================================================ FILE: examples/angular/composable-tables/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/composable-tables/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/composable-tables/tsconfig.spec.json ================================================ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": ["jasmine"] }, "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } ================================================ FILE: examples/angular/custom-plugin/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/custom-plugin/.vscode/extensions.json ================================================ { // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 "recommendations": ["angular.ng-template"] } ================================================ FILE: examples/angular/custom-plugin/.vscode/launch.json ================================================ { // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "ng serve", "type": "chrome", "request": "launch", "preLaunchTask": "npm: start", "url": "http://localhost:4200/" } ] } ================================================ FILE: examples/angular/custom-plugin/.vscode/mcp.json ================================================ { // For more information, visit: https://angular.dev/ai/mcp "mcpServers": { "angular-cli": { "command": "npx", "args": ["-y", "@angular/cli", "mcp"] } } } ================================================ FILE: examples/angular/custom-plugin/.vscode/tasks.json ================================================ { // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 "version": "2.0.0", "tasks": [ { "type": "npm", "script": "start", "isBackground": true, "problemMatcher": { "owner": "typescript", "pattern": "$tsc", "background": { "activeOnStart": true, "beginsPattern": { "regexp": "Changes detected" }, "endsPattern": { "regexp": "bundle generation (complete|failed)" } } } } ] } ================================================ FILE: examples/angular/custom-plugin/README.md ================================================ # CustomPlugin This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/custom-plugin/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "custom-plugin": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "custom-plugin:build:production" }, "development": { "buildTarget": "custom-plugin:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/custom-plugin/package.json ================================================ { "name": "tanstack-table-example-angular-custom-plugin", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/custom-plugin/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/custom-plugin/src/app/app.css ================================================ table { &[data-table-density] { :where(td, th) { transition: padding 0.2s; padding: 16px; } &[data-table-density='sm'] { :where(td, th) { padding: 4px; } } &[data-table-density='md'] { :where(td, th) { padding: 8px; } } } } ================================================ FILE: examples/angular/custom-plugin/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (footer of footerGroup.headers; track footer.id) { } }
{{ footer }}
================================================ FILE: examples/angular/custom-plugin/src/app/app.ts ================================================ import { Component, signal } from '@angular/core' import { FlexRender, createColumnHelper, createPaginatedRowModel, injectTable, isFunction, rowPaginationFeature, tableFeatures, } from '@tanstack/angular-table' import { densityPlugin } from './density/density-feature' import { makeData } from './makeData' import type { DensityState } from './density/density-feature' import type { Person } from './makeData' const _features = tableFeatures({ rowPaginationFeature, densityPlugin, // pass in our plugin just like any other stock feature }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.accessor('visits', { header: () => 'Visits', footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]) @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', styleUrl: './app.css', }) export class App { readonly data = signal(makeData(1000)) readonly density = signal('md') readonly table = injectTable(() => ({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, columns, data: this.data(), debugTable: true, state: { // passing the density state to the table, TS is still happy :) density: this.density(), }, // using the new onDensityChange option, TS is still happy :) onDensityChange: (updater) => isFunction(updater) ? this.density.update(updater) : this.density.set(updater), })) } ================================================ FILE: examples/angular/custom-plugin/src/app/density/density-feature.ts ================================================ import { functionalUpdate, makeStateUpdater } from '@tanstack/angular-table' import type { OnChangeFn, TableFeature, TableFeatures, Updater, } from '@tanstack/angular-table' // TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features // define types for our new feature's custom state export type DensityState = 'sm' | 'md' | 'lg' export interface TableState_Density { density: DensityState } // 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 export interface Table_Density { setDensity: (updater: Updater) => void toggleDensity: (value?: DensityState) => void } interface DensityPluginConstructors { Table: Table_Density TableOptions: TableOptions_Density TableState: TableState_Density } // Here is all of the actual javascript code for our new feature export const densityPlugin: TableFeature< DensityPluginConstructors > = { // define the new feature's initial state getInitialState: (initialState) => { return { density: 'md', ...initialState, // must come last } }, // define the new feature's default options getDefaultTableOptions: (table) => { return { enableDensity: true, onDensityChange: makeStateUpdater('density', table), } }, // if you need to add a default column definition... // getDefaultColumnDef: () => {}, // 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.toggleDensity = (value) => { table.setDensity?.((old) => { if (value) return value return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options }) } }, // if you need to add row instance APIs... // constructRowAPIs: (row) => {}, // if you need to add cell instance APIs... // constructCellAPIs: (cell) => {}, // if you need to add column instance APIs... // constructColumnAPIs: (column) => {}, // if you need to add header instance APIs... // constructHeaderAPIs: (header) => {}, } // end of custom feature code ================================================ FILE: examples/angular/custom-plugin/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/custom-plugin/src/index.html ================================================ CustomPlugin ================================================ FILE: examples/angular/custom-plugin/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/custom-plugin/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } tr { border-bottom: 1px solid lightgray; } button:disabled { opacity: 0.5; } ================================================ FILE: examples/angular/custom-plugin/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/custom-plugin/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/editable/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/editable/README.md ================================================ # Editable Data This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/editable/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "editable-data": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "editable-data:build:production" }, "development": { "buildTarget": "editable-data:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/editable/package.json ================================================ { "name": "tanstack-table-example-angular-editable", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/editable/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/editable/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } } @for (footerGroup of table.getFooterGroups(); track footerGroup.id) { @for (footer of footerGroup.headers; track footer.id) { } }
{{ footer }}
Page
{{ table.state().pagination.pageIndex + 1 }} of {{ table.getPageCount() }}

================================================ FILE: examples/angular/editable/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, Injector, afterNextRender, inject, signal, } from '@angular/core' import { FlexRender, createPaginatedRowModel, flexRenderComponent, injectTable, rowPaginationFeature, tableFeatures, } from '@tanstack/angular-table' import { EditableCell } from './editable-cell/editable-cell' import { makeData } from './makeData' import type { Person } from './makeData' import type { ColumnDef, RowData, TableFeatures } from '@tanstack/angular-table' declare module '@tanstack/angular-table' { interface TableMeta { updateData: (rowIndex: number, columnId: string, value: unknown) => void } } const _features = tableFeatures({ rowPaginationFeature, }) const defaultColumn: Partial> = { cell: ({ getValue, row, column, table }) => { const initialValue = getValue() return flexRenderComponent(EditableCell, { inputs: { value: initialValue, }, outputs: { change: (value) => { if (table.options.meta?.updateData) { table.options.meta.updateData(row.index, column.id, value) } }, }, }) }, } const defaultColumns: Array> = [ { accessorKey: 'firstName', footer: (info) => info.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', header: () => `Last Name`, footer: (info) => info.column.id, }, { accessorKey: 'age', header: () => 'Age', 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, }, ] @Component({ selector: 'app-root', imports: [FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(10_000)) readonly injector = inject(Injector) readonly autoResetPageIndex = signal(true) readonly table = injectTable(() => ({ data: this.data(), columns: defaultColumns, _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, defaultColumn: defaultColumn, debugTable: true, autoResetPageIndex: this.autoResetPageIndex(), // Provide our updateData function to our table meta meta: { updateData: (rowIndex, columnId, value) => { // Skip page index reset until after next rerender this.autoResetPageIndex.set(false) this.data.update((old) => old.map((row, index) => { if (index === rowIndex) { return { ...old[rowIndex], [columnId]: value, } } return row }), ) afterNextRender(() => this.autoResetPageIndex.set(true), { injector: this.injector, }) }, }, })) refresh() { this.data.set(makeData(10_000)) } } ================================================ FILE: examples/angular/editable/src/app/editable-cell/editable-cell.ts ================================================ import { Component, input, output } from '@angular/core' import { FormsModule } from '@angular/forms' @Component({ selector: 'editable-cell', template: ` `, imports: [FormsModule], }) export class EditableCell { readonly value = input() readonly change = output() } ================================================ FILE: examples/angular/editable/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/editable/src/index.html ================================================ Editable data ================================================ FILE: examples/angular/editable/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/editable/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } .pagination-actions { margin: 10px; display: flex; gap: 10px; } ================================================ FILE: examples/angular/editable/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/editable/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/expanding/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/expanding/README.md ================================================ # Expanding This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/expanding/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "expanding": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "expanding:build:production" }, "development": { "buildTarget": "expanding:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/expanding/package.json ================================================ { "name": "tanstack-table-example-angular-expanding", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/expanding/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/expanding/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } }
@if (!header.isPlaceholder) {
}
Page
{{ table.store.state.pagination.pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:
{{ rawExpandedState() }}
{{ rawRowSelectionState() }}
================================================ FILE: examples/angular/expanding/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, createExpandedRowModel, createPaginatedRowModel, flexRenderComponent, injectTable, rowExpandingFeature, rowPaginationFeature, rowSelectionFeature, tableFeatures, } from '@tanstack/angular-table' import { ReactiveFormsModule } from '@angular/forms' import { makeData } from './makeData' import { ExpandableCell, ExpandableHeaderCell, } from './expandable-cell/expandable-cell' import type { Person } from './makeData' import type { ColumnDef, ExpandedState } from '@tanstack/angular-table' export const _features = tableFeatures({ rowExpandingFeature: rowExpandingFeature, rowPaginationFeature: rowPaginationFeature, rowSelectionFeature: rowSelectionFeature, }) const defaultColumns: Array> = [ { accessorKey: 'firstName', header: () => flexRenderComponent(ExpandableHeaderCell, { inputs: { label: 'First name', }, }), cell: () => flexRenderComponent(ExpandableCell), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }, { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { accessorKey: 'visits', header: () => `Visits`, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ] @Component({ selector: 'app-root', imports: [FlexRender, ReactiveFormsModule], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(100, 5, 3)) readonly expanded = signal({}) readonly table = injectTable(() => ({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), expandedRowModel: createExpandedRowModel(), }, data: this.data(), columns: defaultColumns, state: { expanded: this.expanded(), }, onExpandedChange: (updater) => typeof updater === 'function' ? this.expanded.update(updater) : this.expanded.set(updater), getSubRows: (row) => row.subRows, // filterFromLeafRows: true, // maxLeafRowFilterDepth: 0, debugTable: true, })) readonly rawExpandedState = computed(() => JSON.stringify(this.expanded(), undefined, 2), ) readonly rowSelectionState = this.table.computed({ selector: (state) => state.rowSelection, }) readonly rawRowSelectionState = computed(() => JSON.stringify(this.rowSelectionState(), undefined, 2), ) onPageInputChange(event: Event): void { const inputElement = event.target as HTMLInputElement const page = inputElement.value ? Number(inputElement.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any): void { this.table.setPageSize(Number(event.target.value)) } } ================================================ FILE: examples/angular/expanding/src/app/expandable-cell/expandable-cell.ts ================================================ import { ChangeDetectionStrategy, Component, input } from '@angular/core' import { injectTableCellContext, injectTableHeaderContext, } from '@tanstack/angular-table' import type { RowData } from '@tanstack/angular-table' import type { _features } from '../app' @Component({ standalone: true, template: ` {{ ' ' }} {{ label() }} `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class ExpandableHeaderCell { readonly context = injectTableHeaderContext() readonly label = input.required() get table() { return this.context().table } } @Component({ standalone: true, template: `
{{ ' ' }} @if (row.getCanExpand()) { } @else { 🔵 } {{ ' ' }} {{ context().getValue() }}
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ` :host { > div { padding-left: calc(2rem * var(--depth, 1)); } } `, }) export class ExpandableCell { readonly context = injectTableCellContext() get row() { return this.context().row } } ================================================ FILE: examples/angular/expanding/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/expanding/src/index.html ================================================ Expanding ================================================ FILE: examples/angular/expanding/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/expanding/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/expanding/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/expanding/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/filters/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/filters/README.md ================================================ # Filters This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/filters/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "filters": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "filters:build:production" }, "development": { "buildTarget": "filters:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/filters/package.json ================================================ { "name": "tanstack-table-example-angular-filters", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "lint": "eslint ./src", "watch": "ng build --watch --configuration development" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/filters/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/filters/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } }
@if (!header.isPlaceholder) {
{{ headerCell }} @if (header.column.getIsSorted() === 'asc') { 🔼 } @if (header.column.getIsSorted() === 'desc') { 🔽 }
@if (header.column.getCanFilter()) {
} }
{{ renderCell }}
Page
{{ table.store.state.pagination.pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:
{{ table.getPrePaginatedRowModel().rows.length }} Rows
{{ stringifiedFilters() }}
================================================ FILE: examples/angular/filters/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, columnFacetingFeature, columnFilteringFeature, createFacetedMinMaxValues, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, createTableHook, filterFns, isFunction, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/angular-table' import { makeData } from './makeData' import { TableFilter } from './table-filter/table-filter' import type { ColumnFiltersState, Updater } from '@tanstack/angular-table' import type { Person } from './makeData' export const _features = tableFeatures({ columnFilteringFeature, columnFacetingFeature, rowPaginationFeature, rowSortingFeature, }) const { injectAppTable, createAppColumnHelper } = createTableHook({ _features, _rowModels: { facetedMinMaxValues: createFacetedMinMaxValues(), facetedRowModel: createFacetedRowModel(), facetedUniqueValues: createFacetedUniqueValues(), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, debugTable: true, debugHeaders: true, debugColumns: false, }) const columnHelper = createAppColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', }), columnHelper.accessor('age', { header: () => 'Age', meta: { filterVariant: 'range', }, }), columnHelper.accessor('visits', { header: () => 'Visits', meta: { filterVariant: 'range', }, }), columnHelper.accessor('status', { header: 'Status', meta: { filterVariant: 'select', }, }), columnHelper.accessor('progress', { header: 'Profile Progress', meta: { filterVariant: 'range', }, }), ]) @Component({ selector: 'app-root', imports: [TableFilter, FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly columnFilters = signal([]) readonly data = signal(makeData(5000)) table = injectAppTable(() => ({ columns, data: this.data(), state: { columnFilters: this.columnFilters(), }, onColumnFiltersChange: (updater: Updater) => { isFunction(updater) ? this.columnFilters.update(updater) : this.columnFilters.set(updater) }, })) readonly stringifiedFilters = computed(() => JSON.stringify(this.columnFilters(), null, 2), ) onPageInputChange(event: Event): void { const inputElement = event.target as HTMLInputElement const page = inputElement.value ? Number(inputElement.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any): void { this.table.setPageSize(Number(event.target.value)) } refreshData(): void { this.data.set(makeData(100_000)) // stress test } } ================================================ FILE: examples/angular/filters/src/app/debounced-input/debounced-input.ts ================================================ import { Directive, ElementRef, inject, input } from '@angular/core' import { debounceTime, fromEvent, switchMap } from 'rxjs' import { outputFromObservable, toObservable } from '@angular/core/rxjs-interop' @Directive({ standalone: true, selector: 'input[debouncedInput]', }) export class DebouncedInput { #ref = inject(ElementRef).nativeElement as HTMLInputElement readonly debounce = input(500) readonly debounce$ = toObservable(this.debounce) readonly changeEvent = outputFromObservable( this.debounce$.pipe( switchMap((debounce: number) => { return fromEvent(this.#ref, 'change').pipe(debounceTime(debounce)) }), ), ) } ================================================ FILE: examples/angular/filters/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/filters/src/app/table-filter/table-filter.ts ================================================ import { Component, computed, input } from '@angular/core' import { DebouncedInput } from '../debounced-input/debounced-input' import type { _features } from '../app' import type { Person } from '../makeData' import type { CellData, Column, RowData, Table, TableFeatures, } from '@tanstack/angular-table' declare module '@tanstack/angular-table' { // allows us to define custom properties for our columns interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { filterVariant?: 'text' | 'range' | 'select' } } @Component({ selector: 'app-table-filter', template: ` @switch (filterVariant()) { @case ('range') {
} @case ('select') { } @default { @for (value of sortedUniqueValues(); track value) { }
} } `, imports: [DebouncedInput], }) export class TableFilter { readonly column = input.required>() readonly table = input.required>() readonly filterVariant = computed(() => { return (this.column().columnDef.meta ?? {}).filterVariant }) readonly columnFilterValue = computed( () => this.column().getFilterValue() as any, ) readonly minRangePlaceholder = computed(() => { return `Min ${ this.column().getFacetedMinMaxValues()?.[0] !== undefined ? `(${this.column().getFacetedMinMaxValues()?.[0]})` : '' }` }) readonly maxRangePlaceholder = computed(() => { return `Max ${ this.column().getFacetedMinMaxValues()?.[1] ? `(${this.column().getFacetedMinMaxValues()?.[1]})` : '' }` }) readonly sortedUniqueValues = computed(() => { const filterVariant = this.filterVariant() const column = this.column() if (filterVariant === 'range') { return [] } return Array.from(column.getFacetedUniqueValues().keys()) .sort() .slice(0, 5000) }) readonly changeMinRangeValue = (event: Event) => { const value = (event.target as HTMLInputElement).value this.column().setFilterValue((old?: [number, number]) => { return [value, old?.[1]] }) } readonly changeMaxRangeValue = (event: Event) => { const value = (event.target as HTMLInputElement).value this.column().setFilterValue((old?: [number, number]) => { return [old?.[0], value] }) } } ================================================ FILE: examples/angular/filters/src/index.html ================================================ Selection ================================================ FILE: examples/angular/filters/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/filters/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/filters/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/filters/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/grouping/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/grouping/README.md ================================================ # Grouping This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/grouping/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "grouping": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "grouping:build:production" }, "development": { "buildTarget": "grouping:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/grouping/package.json ================================================ { "name": "tanstack-table-example-angular-grouping", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/grouping/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/grouping/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } }
@if (header.isPlaceholder) { } @else {
@if (header.column.getCanGroup()) { } {{ header }}
}
@if (cell.getIsGrouped()) { {{ cell }} {{ ' ' }}{{ row.subRows.length }} } @else if (cell.getIsAggregated()) { {{ aggregatedCell }} } @else if (cell.getIsPlaceholder()) { } @else { {{ cell }} }
Page
{{ table.store.state.pagination.pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:
{{ table.getRowModel().rows.length }} Rows
{{ stringifiedGrouping() }}
================================================ FILE: examples/angular/grouping/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, isFunction } from '@tanstack/angular-table' import { columns, injectTable } from './columns' import { makeData } from './makeData' import type { GroupingState, Updater } from '@tanstack/angular-table' @Component({ selector: 'app-root', standalone: true, imports: [FlexRender], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal(makeData(10000)) readonly grouping = signal([]) readonly stringifiedGrouping = computed(() => JSON.stringify(this.grouping(), null, 2), ) readonly table = injectTable(() => ({ data: this.data(), columns: columns, initialState: { pagination: { pageSize: 20, pageIndex: 0 }, }, state: { grouping: this.grouping(), }, onGroupingChange: (updaterOrValue: Updater) => { const groupingState = isFunction(updaterOrValue) ? updaterOrValue([...this.grouping()]) : updaterOrValue this.grouping.set(groupingState) }, })) onPageInputChange(event: any): void { const page = event.target.value ? Number(event.target.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any) { this.table.setPageSize(Number(event.target.value)) } refreshData() { this.data.set(makeData(10000)) } } ================================================ FILE: examples/angular/grouping/src/app/columns.ts ================================================ import { aggregationFns, columnFilteringFeature, columnGroupingFeature, createExpandedRowModel, createFilteredRowModel, createGroupedRowModel, createPaginatedRowModel, createTableHook, filterFns, rowExpandingFeature, rowPaginationFeature, } from '@tanstack/angular-table' import type { Person } from './makeData' export const { createAppColumnHelper, injectAppTable: injectTable } = createTableHook({ _features: { columnGroupingFeature, rowPaginationFeature, columnFilteringFeature, rowExpandingFeature, }, _rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns), expandedRowModel: createExpandedRowModel(), paginatedRowModel: createPaginatedRowModel(), filteredRowModel: createFilteredRowModel(filterFns), }, }) const columnHelper = createAppColumnHelper() export const columns = columnHelper.columns([ columnHelper.group({ header: 'Name', columns: columnHelper.columns([ columnHelper.accessor('firstName', { header: () => 'First Name', cell: (info) => info.getValue(), getGroupingValue: (row) => `${row.firstName} ${row.lastName}`, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', header: () => 'Last Name', cell: (info) => info.getValue(), }), ]), }), columnHelper.group({ header: 'Info', columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', aggregatedCell: ({ getValue }) => Math.round(getValue() * 100) / 100, aggregationFn: 'median', }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => `Visits`, aggregationFn: 'sum', aggregatedCell: ({ getValue }) => getValue().toLocaleString(), }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', cell: ({ getValue }) => Math.round(getValue() * 100) / 100 + '%', aggregationFn: 'mean', aggregatedCell: ({ getValue }) => Math.round(getValue() * 100) / 100 + '%', }), ]), }), ]), }), ]) ================================================ FILE: examples/angular/grouping/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array): Array { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/grouping/src/index.html ================================================ Grouping ================================================ FILE: examples/angular/grouping/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/grouping/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/grouping/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/grouping/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/remote-data/.gitignore ================================================ # See http://help.github.com/ignore-files/ for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/remote-data/README.md ================================================ # Basic This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.1.2. ## Development server Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. ## Code scaffolding Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. ## Build Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. ## Running unit tests Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). ## Running end-to-end tests Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. ## Further help To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. ================================================ FILE: examples/angular/remote-data/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "remote-data": { "cli": { "cache": { "enabled": false } }, "projectType": "application", "schematics": { "@schematics/angular:component": { "style": "scss" } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist/remote-data", "index": "src/index.html", "browser": "src/main.ts", "polyfills": [], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": ["src/favicon.ico", "src/assets"], "styles": ["src/styles.scss"], "scripts": [] }, "configurations": { "production": { "budgets": [], "outputHashing": "all", "outputMode": "server", "server": "src/main.server.ts", "ssr": { "entry": "src/server.ts" } }, "no-ssr": { "budgets": [], "outputHashing": "all", "prerender": false, "ssr": false }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true, "outputMode": "server", "server": "src/main.server.ts", "ssr": { "entry": "src/server.ts" } } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "buildTarget": "remote-data:build:production" }, "no-ssr": { "buildTarget": "remote-data:build:no-ssr" }, "development": { "buildTarget": "remote-data:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "buildTarget": "remote-data:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "polyfills": [], "tsConfig": "tsconfig.spec.json", "inlineStyleLanguage": "scss", "assets": ["src/favicon.ico", "src/assets"], "styles": ["src/styles.scss"], "scripts": [] } } } } }, "cli": { "analytics": false } } ================================================ FILE: examples/angular/remote-data/package.json ================================================ { "name": "tanstack-table-example-angular-remote-data", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "start:no-ssr": "ng serve --configuration=no-ssr", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "lint": "eslint ./src", "serve:ssr:remote-data": "node dist/remote-data/server/server.mjs" }, "private": true, "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/platform-browser-dynamic": "^21.1.1", "@angular/platform-server": "^21.1.1", "@angular/router": "^21.1.1", "@angular/ssr": "^21.1.2", "@tanstack/angular-table": "^9.0.0-alpha.17", "express": "^5.2.1", "rxjs": "~7.8.2" }, "devDependencies": { "@angular-devkit/build-angular": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "@types/express": "^5.0.6", "@types/node": "^25.0.10", "tslib": "^2.8.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/remote-data/src/app/app.config.server.ts ================================================ import { mergeApplicationConfig } from '@angular/core' import { provideServerRendering, withRoutes } from '@angular/ssr' import { appConfig } from './app.config' import { serverRoutes } from './app.routes.server' import type { ApplicationConfig } from '@angular/core' const serverConfig: ApplicationConfig = { providers: [provideServerRendering(withRoutes(serverRoutes))], } export const config = mergeApplicationConfig(appConfig, serverConfig) ================================================ FILE: examples/angular/remote-data/src/app/app.config.ts ================================================ import { provideClientHydration, withEventReplay, withHttpTransferCacheOptions, } from '@angular/platform-browser' import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), provideClientHydration( withEventReplay(), withHttpTransferCacheOptions({ includeHeaders: ['X-Total-Count'], }), ), ], } ================================================ FILE: examples/angular/remote-data/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } }
@if (!header.isPlaceholder) {
@if (header.column.getIsSorted() === 'asc') { 🔼 } @if (header.column.getIsSorted() === 'desc') { 🔽 }
}
@if (data.isLoading()) { Loading... }
Page
{{ table.store.state.pagination.pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:
================================================ FILE: examples/angular/remote-data/src/app/app.routes.server.ts ================================================ import { RenderMode } from '@angular/ssr' import type { ServerRoute } from '@angular/ssr' export const serverRoutes: Array = [ { path: '**', renderMode: RenderMode.Server, }, ] ================================================ FILE: examples/angular/remote-data/src/app/app.ts ================================================ import { HttpClient, HttpParams } from '@angular/common/http' import { ChangeDetectionStrategy, Component, inject, linkedSignal, signal, } from '@angular/core' import { ReactiveFormsModule } from '@angular/forms' import { FlexRender, createColumnHelper, globalFilteringFeature, injectTable, rowPaginationFeature, rowSortingFeature, tableFeatures, } from '@tanstack/angular-table' import { map } from 'rxjs' import { rxResource } from '@angular/core/rxjs-interop' import type { ColumnDef, PaginationState, SortingState, } from '@tanstack/angular-table' import type { WritableSignal } from '@angular/core' export type Todo = { userId: number id: number title: string completed: boolean } const _features = tableFeatures({ rowPaginationFeature, globalFilteringFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() type TodoResponse = { items: Array; totalCount: number } @Component({ selector: 'app-root', imports: [FlexRender, ReactiveFormsModule], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly client = inject(HttpClient) readonly pagination = signal({ pageSize: 10, pageIndex: 0, }) readonly sorting = signal([{ id: 'id', desc: false }]) readonly globalFilter = signal(null) readonly data = rxResource({ params: () => ({ page: this.pagination(), globalFilter: this.globalFilter(), sorting: this.sorting(), }), stream: ({ params: { page, globalFilter, sorting } }) => { let httpParams = new HttpParams({ fromObject: { _page: page.pageIndex + 1, _limit: page.pageSize, }, }) if (globalFilter) { httpParams = httpParams.set('title_like', globalFilter) } if (sorting.length) { const keys: Array = [] const orders: Array = [] for (const sort of sorting) { keys.push(sort.id) orders.push(sort.desc ? 'desc' : 'asc') } httpParams = httpParams .set('_sort', keys.join(',')) .set('_order', orders.join(',')) } return this.client .get< Array >(`https://jsonplaceholder.typicode.com/todos`, { params: httpParams, observe: 'response' }) .pipe( map((response) => { return { items: response.body ?? [], totalCount: Number(response.headers.get('X-Total-Count')), } satisfies TodoResponse }), ) }, }) readonly columns = [ columnHelper.accessor('id', { id: 'id', cell: (info) => info.getValue(), header: () => 'Id', footer: (props) => props.column.id, }), columnHelper.accessor('title', { id: 'title', cell: (info) => info.getValue(), header: () => 'Title', footer: (props) => props.column.id, }), columnHelper.accessor('completed', { id: 'completed', cell: (info) => (info.getValue() ? `✅` : `❌`), header: () => 'Completed', footer: (props) => props.column.id, }), ] as Array> // Keep previous value readonly dataWithLatest: WritableSignal = linkedSignal({ source: () => ({ value: this.data.value(), status: this.data.status(), }), computation: (source, previous) => { if (previous && source.status === 'loading') return previous.value return source.value ?? { items: [], totalCount: 0 } }, }) readonly table = injectTable(() => { const data = this.dataWithLatest() return { _features, data: data.items, columns: this.columns, state: { pagination: this.pagination(), globalFilter: this.globalFilter(), sorting: this.sorting(), }, manualFiltering: true, manualPagination: true, manualSorting: true, rowCount: data.totalCount, onPaginationChange: (updater) => typeof updater === 'function' ? this.pagination.update(updater) : this.pagination.set(updater), onSortingChange: (updater) => { typeof updater === 'function' ? this.sorting.update(updater) : this.sorting.set(updater) }, onGlobalFilterChange: (updater) => { typeof updater === 'function' ? this.globalFilter.update(updater) : this.globalFilter.set(updater) this.pagination.update((page) => ({ ...page, pageIndex: 0, })) }, } }) onPageInputChange(event: Event): void { const inputElement = event.target as HTMLInputElement const page = inputElement.value ? Number(inputElement.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any): void { this.table.setPageSize(Number(event.target.value)) } } ================================================ FILE: examples/angular/remote-data/src/index.html ================================================ Expanding ================================================ FILE: examples/angular/remote-data/src/main.server.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { config } from './app/app.config.server' import { App } from './app/app' import type { BootstrapContext } from '@angular/platform-browser' const bootstrap = (context: BootstrapContext) => bootstrapApplication(App, config, context) export default bootstrap ================================================ FILE: examples/angular/remote-data/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/remote-data/src/server.ts ================================================ import { join } from 'node:path' import { AngularNodeAppEngine, createNodeRequestHandler, isMainModule, writeResponseToNodeResponse, } from '@angular/ssr/node' import express from 'express' const browserDistFolder = join(import.meta.dirname, '../browser') const app = express() const angularApp = new AngularNodeAppEngine() /** * Example Express Rest API endpoints can be defined here. * Uncomment and define endpoints as necessary. * * Example: * ```ts * app.get('/api/{*splat}', (req, res) => { * // Handle API request * }); * ``` */ /** * Serve static files from /browser */ app.use( express.static(browserDistFolder, { maxAge: '1y', index: false, redirect: false, }), ) /** * Handle all other requests by rendering the Angular application. */ app.use((req, res, next) => { angularApp .handle(req) .then((response) => response ? writeResponseToNodeResponse(response, res) : next(), ) .catch(next) }) /** * Start the server if this module is the main entry point, or it is ran via PM2. * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. */ if (isMainModule(import.meta.url) || process.env['pm_id']) { const port = process.env['PORT'] || 4000 app.listen(port, (error) => { if (error) { throw error } console.log(`Node Express server listening on http://localhost:${port}`) }) } /** * Request handler used by the Angular CLI (for dev-server and during build) or Firebase Cloud Functions. */ export const reqHandler = createNodeRequestHandler(app) ================================================ FILE: examples/angular/remote-data/src/styles.scss ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tbody td { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/remote-data/tsconfig.app.json ================================================ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": ["node"] }, "files": ["src/main.ts", "src/main.server.ts", "src/server.ts"], "include": ["src/**/*.d.ts"] } ================================================ FILE: examples/angular/remote-data/tsconfig.json ================================================ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { "compileOnSave": false, "compilerOptions": { "baseUrl": "src", "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "esModuleInterop": true, "sourceMap": true, "declaration": false, "experimentalDecorators": true, "moduleResolution": "bundler", "importHelpers": true, "target": "ES2022", "module": "ES2022", "useDefineForClassFields": false, "lib": ["ES2022", "dom"] }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/row-dnd/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/row-dnd/README.md ================================================ # Row Drag and Drop This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/row-dnd/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "row-dnd": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "row-dnd:build:production" }, "development": { "buildTarget": "row-dnd:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/row-dnd/package.json ================================================ { "name": "tanstack-table-example-angular-row-dnd", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/cdk": "^21.1.1", "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/row-dnd/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/row-dnd/src/app/app.css ================================================ .cdk-drag-preview { box-sizing: border-box; box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); } .cdk-drag-placeholder { transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); } .cdk-drag-placeholder > td { background: #ccc; } .cdk-drag-animating { transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); } .cdk-drop-list-dragging tr[cdkdrag]:not(.cdk-drag-placeholder) { transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); } ================================================ FILE: examples/angular/row-dnd/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
{{ sortedIds() | json }}
================================================ FILE: examples/angular/row-dnd/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, columnSizingFeature, columnVisibilityFeature, flexRenderComponent, injectTable, rowPaginationFeature, tableFeatures, } from '@tanstack/angular-table' import { CdkDrag, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop' import { JsonPipe } from '@angular/common' import { DragHandleCell } from './drag-handle-cell/drag-handle-cell' import { makeData } from './makeData' import type { Person } from './makeData' import type { CdkDragDrop } from '@angular/cdk/drag-drop' import type { ColumnDef } from '@tanstack/angular-table' const _tableFeatures = tableFeatures({ rowPaginationFeature, columnSizingFeature, columnVisibilityFeature, }) const defaultColumns: Array> = [ { id: 'drag-handle', header: 'Move', cell: () => flexRenderComponent(DragHandleCell), size: 60, }, { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => `Last Name`, }, { accessorKey: 'age', header: () => 'Age', }, { accessorKey: 'visits', header: () => `Visits`, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] @Component({ selector: 'app-root', imports: [FlexRender, CdkDropList, CdkDrag, JsonPipe], templateUrl: './app.html', styleUrl: './app.css', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(20)) readonly table = injectTable(() => { return { _features: _tableFeatures, data: this.data(), columns: defaultColumns, getRowId: (row) => row.userId, debugTable: true, debugHeaders: true, debugColumns: true, } }) readonly sortedIds = computed(() => this.data().map((data) => data.userId)) drop(event: CdkDragDrop>) { const data = [...this.data()] moveItemInArray(data, event.previousIndex, event.currentIndex) this.data.set(data) } } ================================================ FILE: examples/angular/row-dnd/src/app/drag-handle-cell/drag-handle-cell.ts ================================================ import { ChangeDetectionStrategy, Component } from '@angular/core' import { CdkDragHandle } from '@angular/cdk/drag-drop' @Component({ selector: 'drag-handle-cell', template: ` `, imports: [CdkDragHandle], changeDetection: ChangeDetectionStrategy.OnPush, }) export class DragHandleCell {} ================================================ FILE: examples/angular/row-dnd/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { userId: string firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { userId: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/row-dnd/src/index.html ================================================ Row Drag and drop ================================================ FILE: examples/angular/row-dnd/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/row-dnd/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 4px 4px; background-color: white; } td button { padding: 1px 1rem; cursor: grab; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/row-dnd/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/row-dnd/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/row-selection/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/row-selection/README.md ================================================ # Row Selection This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/row-selection/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "row-selection": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "row-selection:build:production" }, "development": { "buildTarget": "row-selection:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/row-selection/package.json ================================================ { "name": "tanstack-table-example-angular-row-selection", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/cdk": "^21.1.1", "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/row-selection/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/row-selection/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getAllCells(); track cell.id) { } }
@if (!header.isPlaceholder) { {{ headerCell }} @if (header.column.getCanFilter()) {
} }
{{ renderCell }}
Page Rows ({{ table.getRowModel().rows.length }})
Page
{{ paginationState().pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:

{{ rowSelectionLength() }} of {{ table.getPreFilteredRowModel().rows.length }} Total Rows


{{ stringifiedRowSelection() }}
================================================ FILE: examples/angular/row-selection/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, } from '@angular/core' import { FlexRender, TanStackTable, flexRenderComponent, } from '@tanstack/angular-table' import { TableFilter } from './table-filter/table-filter' import { makeData } from './makeData' import { TableHeaderSelection, TableRowSelection, } from './selection-column/selection-column' import { createAppColumnHelper, injectTable } from './table' import type { Person } from './makeData' import type { RowSelectionState } from '@tanstack/angular-table' const columnHelper = createAppColumnHelper() @Component({ selector: 'app-root', standalone: true, imports: [TableFilter, FlexRender, TanStackTable], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { private readonly rowSelection = signal({}) readonly globalFilter = signal('') readonly data = signal(makeData(10_000)) readonly enableRowSelection = signal(true) readonly columns = columnHelper.columns([ columnHelper.display({ id: 'select', header: () => flexRenderComponent(TableHeaderSelection), cell: () => flexRenderComponent(TableRowSelection), }), columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, header: () => 'First name', }), columnHelper.accessor('lastName', { cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => `Age 🥳`, footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor((row) => row.visits, { id: 'visits', header: () => 'Visits', footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.status, { id: 'status', header: () => 'Status', footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.progress, { id: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) readonly table = injectTable(() => ({ data: this.data(), columns: this.columns, state: { rowSelection: this.rowSelection(), }, enableRowSelection: this.enableRowSelection(), // enable row selection for all rows // enableRowSelection: row => row.original.age > 18, // or enable row selection conditionally per row onRowSelectionChange: (updaterOrValue) => { this.rowSelection.set( typeof updaterOrValue === 'function' ? updaterOrValue(this.rowSelection()) : updaterOrValue, ) }, })) readonly paginationState = this.table.computed({ selector: (state) => state.pagination, }) readonly stringifiedRowSelection = computed(() => JSON.stringify(this.rowSelection(), null, 2), ) readonly rowSelectionLength = computed( () => Object.keys(this.rowSelection()).length, ) onPageInputChange(event: Event): void { const inputElement = event.target as HTMLInputElement const page = inputElement.value ? Number(inputElement.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any): void { this.table.setPageSize(Number(event.target.value)) } logSelectedFlatRows(): void { console.info( 'table.getSelectedRowModel().flatRows', this.table.getSelectedRowModel().flatRows, ) } refreshData(): void { this.data.set(makeData(10_000)) } toggleEnableRowSelection() { this.enableRowSelection.update((value) => !value) } } ================================================ FILE: examples/angular/row-selection/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/row-selection/src/app/selection-column/selection-column.ts ================================================ import { injectTableCellContext } from '@tanstack/angular-table' import { ChangeDetectionStrategy, Component, computed } from '@angular/core' import { injectFlexRenderCellContext, injectFlexRenderHeaderContext, } from '../table' @Component({ template: ` `, host: { class: 'px-1 block', }, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableHeaderSelection { context = injectFlexRenderHeaderContext() } @Component({ template: ` `, host: { class: 'px-1 block', }, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableRowSelection { readonly cell = injectTableCellContext() readonly row = computed(() => this.cell().row) readonly context = injectFlexRenderCellContext() } ================================================ FILE: examples/angular/row-selection/src/app/table-filter/table-filter.ts ================================================ import { Component, computed, input } from '@angular/core' import { injectTableContext } from '../table' import type { Column } from '@tanstack/angular-table' @Component({ selector: 'app-table-filter', template: ` @let columnType = this.columnType(); @if (columnType == 'number') {
} @else { } `, standalone: true, }) export class TableFilter { readonly column = input.required>() readonly table = injectTableContext() readonly columnType = computed(() => { return typeof this.table() .getPreFilteredRowModel() .flatRows[0]?.getValue(this.column().id) }) getMinValue() { const minValue = this.column().getFilterValue() return (minValue?.[0] ?? '') as string } getMaxValue() { const maxValue = this.column().getFilterValue() return (maxValue?.[1] ?? '') as string } updateMinFilterValue(newValue: string): void { this.column().setFilterValue((old: any) => { return [newValue, old?.[1]] }) } updateMaxFilterValue(newValue: string): void { this.column().setFilterValue((old: any) => [old?.[0], newValue]) } } ================================================ FILE: examples/angular/row-selection/src/app/table.ts ================================================ import { columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createTableHook, filterFns, rowPaginationFeature, rowSelectionFeature, tableFeatures, } from '@tanstack/angular-table' const _features = tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSelectionFeature, }) export const { injectAppTable: injectTable, injectTableContext, createAppColumnHelper, injectFlexRenderCellContext, injectFlexRenderHeaderContext, } = createTableHook({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, debugTable: true, }) ================================================ FILE: examples/angular/row-selection/src/index.html ================================================ Selection ================================================ FILE: examples/angular/row-selection/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/row-selection/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/row-selection/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/row-selection/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/row-selection-signal/.devcontainer/devcontainer.json ================================================ { "name": "Node.js", "image": "mcr.microsoft.com/devcontainers/javascript-node:18" } ================================================ FILE: examples/angular/row-selection-signal/.editorconfig ================================================ # Editor configuration, see https://editorconfig.org root = true [*] charset = utf-8 indent_style = space indent_size = 2 insert_final_newline = true trim_trailing_whitespace = true [*.ts] quote_type = single [*.md] max_line_length = off trim_trailing_whitespace = false ================================================ FILE: examples/angular/row-selection-signal/.gitignore ================================================ # See http://help.github.com/ignore-files/ for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/row-selection-signal/README.md ================================================ # Selection This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.1.2. ## Development server Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. ## Code scaffolding Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. ## Build Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. ## Running unit tests Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). ## Running end-to-end tests Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. ## Further help To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. ================================================ FILE: examples/angular/row-selection-signal/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "row-selection-signal": { "cli": { "cache": { "enabled": false } }, "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true, "style": "scss" }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "outputPath": "dist/row-selection-signal", "index": "src/index.html", "browser": "src/main.ts", "polyfills": [], "tsConfig": "tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": ["src/favicon.ico", "src/assets"], "styles": ["src/styles.scss"], "scripts": [] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kb", "maximumError": "1mb" }, { "type": "anyComponentStyle", "maximumWarning": "2kb", "maximumError": "4kb" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "row-selection-signal:build:production" }, "development": { "buildTarget": "row-selection-signal:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { "builder": "@angular/build:extract-i18n", "options": { "buildTarget": "row-selection-signal:build" } } } } }, "cli": { "analytics": false } } ================================================ FILE: examples/angular/row-selection-signal/package.json ================================================ { "name": "tanstack-table-example-angular-row-selection-signal", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "lint": "eslint ./src" }, "private": true, "dependencies": { "@angular/animations": "^21.1.1", "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/platform-browser-dynamic": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/row-selection-signal/src/app/app.component.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
@if (!header.isPlaceholder) { {{ headerCell }} @if (header.column.getCanFilter()) {
} }
{{ renderCell }}
Page Rows ({{ table.getRowModel().rows.length }})
Page
{{ table.store.state.pagination.pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:

{{ rowSelectionLength() }} of {{ table.getPreFilteredRowModel().rows.length }} Total Rows


{{ stringifiedRowSelection() }}
Age 🥳 ================================================ FILE: examples/angular/row-selection-signal/src/app/app.component.ts ================================================ import { ChangeDetectionStrategy, Component, computed, signal, viewChild, } from '@angular/core' import { FlexRenderDirective, columnFilteringFeature, columnVisibilityFeature, createFilteredRowModel, createPaginatedRowModel, filterFns, injectTable, rowPaginationFeature, rowSelectionFeature, tableFeatures, } from '@tanstack/angular-table' import { FilterComponent } from './filter' import { makeData } from './makeData' import { TableHeadSelectionComponent, TableRowSelectionComponent, } from './selection-column.component' import type { Person } from './makeData' import type { ColumnDef, RowSelectionState } from '@tanstack/angular-table' import type { TemplateRef } from '@angular/core' const _features = tableFeatures({ columnFilteringFeature, columnVisibilityFeature, rowPaginationFeature, rowSelectionFeature, }) @Component({ selector: 'app-root', imports: [FilterComponent, FlexRenderDirective], templateUrl: './app.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent { private readonly rowSelection = signal({}) readonly globalFilter = signal('') readonly data = signal(makeData(10_000)) readonly ageHeaderCell = viewChild.required>('ageHeaderCell') readonly columns: Array> = [ { id: 'select', header: () => TableHeadSelectionComponent, cell: () => TableRowSelectionComponent, }, { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, header: 'First name', }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => this.ageHeaderCell(), footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => 'Visits', footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] // TODO make this generic infer without passing in manually table = injectTable(() => ({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, columns: this.columns, data: this.data(), state: { rowSelection: this.rowSelection(), }, enableRowSelection: true, // enable row selection for all rows // enableRowSelection: row => row.original.age > 18, // or enable row selection conditionally per row onRowSelectionChange: (updaterOrValue) => { this.rowSelection.set( typeof updaterOrValue === 'function' ? updaterOrValue(this.rowSelection()) : updaterOrValue, ) }, debugTable: true, })) readonly stringifiedRowSelection = computed(() => JSON.stringify(this.rowSelection(), null, 2), ) readonly rowSelectionLength = computed( () => Object.keys(this.rowSelection()).length, ) onPageInputChange(event: Event): void { const inputElement = event.target as HTMLInputElement const page = inputElement.value ? Number(inputElement.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any): void { this.table.setPageSize(Number(event.target.value)) } logSelectedFlatRows(): void { console.info( 'table.getSelectedRowModel().flatRows', this.table.getSelectedRowModel().flatRows, ) } refreshData(): void { this.data.set(makeData(10_000)) } } ================================================ FILE: examples/angular/row-selection-signal/src/app/app.config.ts ================================================ import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [], } ================================================ FILE: examples/angular/row-selection-signal/src/app/filter.ts ================================================ import { Component, input } from '@angular/core' import type { OnInit } from '@angular/core' import type { Column, RowData, Table } from '@tanstack/angular-table' @Component({ selector: 'app-table-filter', template: ` @if (columnType) { @if (columnType == 'number') {
} @else { } }`, }) export class FilterComponent implements OnInit { column = input.required>() table = input.required>() columnType!: string ngOnInit() { this.columnType = typeof this.table() .getPreFilteredRowModel() .flatRows[0]?.getValue(this.column().id) } getMinValue() { const minValue = this.column().getFilterValue() return (minValue?.[0] ?? '') as string } getMaxValue() { const maxValue = this.column().getFilterValue() return (maxValue?.[1] ?? '') as string } updateMinFilterValue(newValue: string): void { this.column().setFilterValue((old: any) => { return [newValue, old?.[1]] }) } updateMaxFilterValue(newValue: string): void { this.column().setFilterValue((old: any) => [old?.[0], newValue]) } } ================================================ FILE: examples/angular/row-selection-signal/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/row-selection-signal/src/app/selection-column.component.ts ================================================ import { ChangeDetectionStrategy, Component, input } from '@angular/core' import type { Row, RowData, Table } from '@tanstack/angular-table' @Component({ template: ` `, host: { class: 'px-1 block', }, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableHeadSelectionComponent { // Your component should also reflect the fields you use as props in flexRenderer directive. // Define the fields as input you want to use in your component // ie. In this case, you are passing HeaderContext object as props in flexRenderer directive. // You can define and use the table field, which is defined in HeaderContext. // Please take note that only signal based input is supported. // column = input.required>() // header = input.required>() table = input.required>() } @Component({ template: ` `, host: { class: 'px-1 block', }, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) export class TableRowSelectionComponent { row = input.required>() } ================================================ FILE: examples/angular/row-selection-signal/src/assets/.gitkeep ================================================ ================================================ FILE: examples/angular/row-selection-signal/src/index.html ================================================ Selection ================================================ FILE: examples/angular/row-selection-signal/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { AppComponent } from './app/app.component' bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/row-selection-signal/src/styles.scss ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/row-selection-signal/tsconfig.app.json ================================================ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "files": ["src/main.ts"], "include": ["src/**/*.d.ts"] } ================================================ FILE: examples/angular/row-selection-signal/tsconfig.json ================================================ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { "compileOnSave": false, "compilerOptions": { "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "esModuleInterop": true, "sourceMap": true, "declaration": false, "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, "target": "ES2022", "module": "ES2022", "useDefineForClassFields": false, "lib": ["ES2022", "dom"] }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/row-selection-signal/tsconfig.spec.json ================================================ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": ["jasmine"] }, "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } ================================================ FILE: examples/angular/signal-input/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/signal-input/README.md ================================================ # Signal Input This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/signal-input/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "signal-input": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "signal-input:build:production" }, "development": { "buildTarget": "signal-input:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/signal-input/package.json ================================================ { "name": "tanstack-table-example-angular-signal-input", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/cdk": "^21.1.1", "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/signal-input/src/app/app.config.ts ================================================ import { provideBrowserGlobalErrorListeners } from '@angular/core' import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [provideBrowserGlobalErrorListeners()], } ================================================ FILE: examples/angular/signal-input/src/app/app.html ================================================
================================================ FILE: examples/angular/signal-input/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, signal } from '@angular/core' import { makeData } from './makeData' import { PersonTable } from './person-table/person-table' import type { PaginationState } from '@tanstack/angular-table' @Component({ selector: 'app-root', imports: [PersonTable], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { data = signal(makeData(10000)) pagination = signal({ pageIndex: 0, pageSize: 5, }) refreshData() { this.data.set(makeData(10000)) } previousPage(): void { this.pagination.update((pagination) => ({ ...pagination, pageIndex: pagination.pageIndex - 1, })) } nextPage(): void { this.pagination.update((pagination) => ({ ...pagination, pageIndex: pagination.pageIndex + 1, })) } } ================================================ FILE: examples/angular/signal-input/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/signal-input/src/app/person-table/person-table.html ================================================ @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
@if (!header.isPlaceholder) { {{ header }} }
{{ cell }}
Page
{{ table.store.state.pagination.pageIndex + 1 }} of {{ table.getPageCount() }}
| Go to page:
{{ table.getRowModel().rows.length }} Rows
================================================ FILE: examples/angular/signal-input/src/app/person-table/person-table.ts ================================================ import { ChangeDetectionStrategy, Component, input, model } from '@angular/core' import { FlexRender, columnVisibilityFeature, createPaginatedRowModel, injectTable, rowPaginationFeature, tableFeatures, } from '@tanstack/angular-table' import type { ColumnDef, PaginationState } from '@tanstack/angular-table' import type { Person } from '../makeData' const _features = tableFeatures({ rowPaginationFeature, columnVisibilityFeature, }) @Component({ selector: 'app-person-table', templateUrl: 'person-table.html', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FlexRender], }) export class PersonTable { readonly data = input.required>() readonly pagination = model.required() readonly columns: Array> = [ { accessorKey: 'firstName', header: 'First Name', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', header: () => `Last Name`, cell: (info) => info.getValue(), }, ] readonly table = injectTable(() => { return { _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, data: this.data(), columns: this.columns, state: { pagination: this.pagination(), }, onPaginationChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.pagination.update(updaterOrValue) : this.pagination.set(updaterOrValue) }, debugTable: true, } }) onPageInputChange(event: any): void { const page = event.target.value ? Number(event.target.value) - 1 : 0 this.table.setPageIndex(page) } onPageSizeChange(event: any) { this.table.setPageSize(Number(event.target.value)) } } ================================================ FILE: examples/angular/signal-input/src/index.html ================================================ Signal Input ================================================ FILE: examples/angular/signal-input/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/signal-input/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/signal-input/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/signal-input/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/angular/sub-components/.gitignore ================================================ # See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. # Compiled output /dist /tmp /out-tsc /bazel-out # Node /node_modules npm-debug.log yarn-error.log # IDEs and editors .idea/ .project .classpath .c9/ *.launch .settings/ *.sublime-workspace # Visual Studio Code .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/mcp.json .history/* # Miscellaneous /.angular/cache .sass-cache/ /connect.lock /coverage /libpeerconnection.log testem.log /typings __screenshots__/ # System files .DS_Store Thumbs.db ================================================ FILE: examples/angular/sub-components/README.md ================================================ # Sub components This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.1.0. ## Development server To start a local development server, run: ```bash ng serve ``` Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. ## Code scaffolding Angular CLI includes powerful code scaffolding tools. To generate a new component, run: ```bash ng generate component component-name ``` For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: ```bash ng generate --help ``` ## Building To build the project run: ```bash ng build ``` This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. ## Running unit tests To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test ``` ## Running end-to-end tests For end-to-end (e2e) testing, run: ```bash ng e2e ``` Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. ================================================ FILE: examples/angular/sub-components/angular.json ================================================ { "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "cli": { "packageManager": "pnpm", "analytics": false, "cache": { "enabled": false } }, "newProjectRoot": "projects", "projects": { "sub-components": { "projectType": "application", "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "inlineStyle": true, "skipTests": true }, "@schematics/angular:class": { "skipTests": true }, "@schematics/angular:directive": { "skipTests": true }, "@schematics/angular:guard": { "skipTests": true }, "@schematics/angular:interceptor": { "skipTests": true }, "@schematics/angular:pipe": { "skipTests": true }, "@schematics/angular:resolver": { "skipTests": true }, "@schematics/angular:service": { "skipTests": true } }, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { "builder": "@angular/build:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json", "assets": [ { "glob": "**/*", "input": "public" } ], "styles": ["src/styles.css"] }, "configurations": { "production": { "budgets": [ { "type": "initial", "maximumWarning": "500kB", "maximumError": "1MB" }, { "type": "anyComponentStyle", "maximumWarning": "4kB", "maximumError": "8kB" } ], "outputHashing": "all" }, "development": { "optimization": false, "extractLicenses": false, "sourceMap": true } }, "defaultConfiguration": "production" }, "serve": { "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "sub-components:build:production" }, "development": { "buildTarget": "sub-components:build:development" } }, "defaultConfiguration": "development" } } } } } ================================================ FILE: examples/angular/sub-components/package.json ================================================ { "name": "tanstack-table-example-angular-sub-components", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "lint": "eslint ./src" }, "private": true, "packageManager": "pnpm@10.28.2", "dependencies": { "@angular/common": "^21.1.1", "@angular/compiler": "^21.1.1", "@angular/core": "^21.1.1", "@angular/forms": "^21.1.1", "@angular/platform-browser": "^21.1.1", "@angular/router": "^21.1.1", "@faker-js/faker": "^10.2.0", "@tanstack/angular-table": "^9.0.0-alpha.17", "rxjs": "~7.8.2", "tslib": "^2.8.1" }, "devDependencies": { "@angular/build": "^21.1.2", "@angular/cli": "^21.1.2", "@angular/compiler-cli": "^21.1.1", "typescript": "5.9.3" } } ================================================ FILE: examples/angular/sub-components/src/app/app.config.ts ================================================ import type { ApplicationConfig } from '@angular/core' export const appConfig: ApplicationConfig = { providers: [], } ================================================ FILE: examples/angular/sub-components/src/app/app.html ================================================
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } @if (row.getIsExpanded()) { } }
@if (!header.isPlaceholder) {
}
    
      {{ row.original | json }}
    
  
================================================ FILE: examples/angular/sub-components/src/app/app.ts ================================================ import { ChangeDetectionStrategy, Component, signal } from '@angular/core' import { FlexRender, columnVisibilityFeature, createExpandedRowModel, flexRenderComponent, injectTable, rowExpandingFeature, tableFeatures, } from '@tanstack/angular-table' import { ReactiveFormsModule } from '@angular/forms' import { JsonPipe } from '@angular/common' import { makeData } from './makeData' import { ExpandableCell, ExpanderCell } from './expandable-cell' import { SubComponent } from './sub-component/sub-component' import type { Person } from './makeData' import type { ColumnDef, ExpandedState } from '@tanstack/angular-table' const _features = tableFeatures({ rowExpandingFeature, columnVisibilityFeature, }) const columns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { id: 'expander', header: () => null, cell: ({ row }) => { if (!row.getCanExpand()) { return '🔵' } return flexRenderComponent(ExpanderCell, { inputs: { expanded: row.getIsExpanded(), }, outputs: { click: row.getToggleExpandedHandler(), }, }) }, }, { accessorKey: 'firstName', header: 'First Name', cell: () => flexRenderComponent(ExpandableCell), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => 'Last Name', footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => 'Visits', footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] @Component({ selector: 'app-root', imports: [FlexRender, ReactiveFormsModule, JsonPipe, SubComponent], templateUrl: './app.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class App { readonly data = signal>(makeData(10)) readonly expanded = signal({}) readonly table = injectTable(() => ({ _features, _rowModels: { expandedRowModel: createExpandedRowModel(), }, data: this.data(), columns, state: { expanded: this.expanded(), }, onExpandedChange: (updater) => typeof updater === 'function' ? this.expanded.update(updater) : this.expanded.set(updater), getRowCanExpand: () => true, })) } ================================================ FILE: examples/angular/sub-components/src/app/expandable-cell.ts ================================================ import { ChangeDetectionStrategy, Component, input, output, } from '@angular/core' import { injectFlexRenderContext } from '@tanstack/angular-table' import type { CellContext, RowData } from '@tanstack/angular-table' @Component({ standalone: true, template: ` `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class ExpanderCell { readonly expanded = input.required() readonly click = output() } @Component({ standalone: true, template: `
{{ context.getValue() }}
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ` :host { > div { padding-left: calc(2rem * var(--depth, 1)); } } `, }) export class ExpandableCell { readonly context = injectFlexRenderContext>() get row() { return this.context.row } } ================================================ FILE: examples/angular/sub-components/src/app/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/angular/sub-components/src/app/sub-component/sub-component.ts ================================================ import { Component, input } from '@angular/core' import { JsonPipe } from '@angular/common' import type { Row } from '@tanstack/angular-table' @Component({ selector: 'app-sub', template: `
    
      {{ row().original | json }}
    
  
`, imports: [JsonPipe], }) export class SubComponent { readonly row = input.required>() } ================================================ FILE: examples/angular/sub-components/src/index.html ================================================ Sub componentss ================================================ FILE: examples/angular/sub-components/src/main.ts ================================================ import { bootstrapApplication } from '@angular/platform-browser' import { appConfig } from './app/app.config' import { App } from './app/app' bootstrapApplication(App, appConfig).catch((err) => console.error(err)) ================================================ FILE: examples/angular/sub-components/src/styles.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/angular/sub-components/tsconfig.app.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", "types": [] }, "include": ["src/**/*.ts"], "exclude": ["src/**/*.spec.ts"] } ================================================ FILE: examples/angular/sub-components/tsconfig.json ================================================ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, "experimentalDecorators": true, "importHelpers": true, "target": "ES2022", "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true } } ================================================ FILE: examples/lit/basic/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/basic/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/basic/index.html ================================================ Vite App
================================================ FILE: examples/lit/basic/package.json ================================================ { "name": "tanstack-lit-table-example-basic", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src" }, "dependencies": { "@tanstack/lit-table": "^9.0.0-alpha.10", "@twind/core": "^1.1.3", "@twind/preset-autoprefix": "^1.0.7", "@twind/preset-tailwind": "^1.1.4", "@twind/with-web-components": "^1.1.3", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/basic/src/main.ts ================================================ import { customElement } from 'lit/decorators.js' import { LitElement, html } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { ColumnDef, TableController, flexRender, tableFeatures, } from '@tanstack/lit-table' import install from '@twind/with-web-components' import config from '../twind.config' const withTwind = install(config) // 1. Define what the shape of your data will be for each row type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } // 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 _features = tableFeatures({}) // const columnHelper = createColumnHelper() // 4. Define the columns for your table. This uses the new `ColumnDef` type to define columns. Alternatively, check out the createTableHelper/createColumnHelper util for an even more type-safe way to define columns. const columns: Array> = [ { accessorKey: 'firstName', // accessorKey method (most common for simple use-cases) header: 'First Name', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, // accessorFn used (alternative) along with a custom id id: 'lastName', header: () => html`Last Name`, cell: (info) => html`${info.getValue()}`, }, { accessorFn: (row) => Number(row.age), // accessorFn used to transform the data id: 'age', header: () => 'Age', cell: (info) => info.renderValue(), }, { accessorKey: 'visits', header: () => html`Visits`, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] const data: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'mor', lastName: 'kadosh', age: 31, visits: 30, status: 'In Relationship', progress: 90, }, ] @customElement('lit-table-example') @withTwind class LitTableExample extends LitElement { private tableController = new TableController(this) protected render(): unknown { const table = this.tableController.table( { _features, // new required option in V9. Tell the table which features you are importing and using (better tree-shaking) _rowModels: {}, // `Core` row model is now included by default, but you can still override it here columns, data, // add additional table options here debugTable: true, }, () => ({}), // selector - empty since we don't need any state ) return html` ${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html`${repeat( headerGroup.headers, (header) => header.id, (header) => html` `, )}`, )} ${repeat( table.getRowModel().rows, (row) => row.id, (row) => html` ${repeat( row.getAllCells(), (cell) => cell.id, (cell) => html` `, )} `, )} ${repeat( table.getFooterGroups(), (footerGroup) => footerGroup.id, (footerGroup) => html` ${repeat( footerGroup.headers, (header) => header.id, (header) => html` `, )} `, )}
${header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
${header.isPlaceholder ? null : flexRender( header.column.columnDef.footer, header.getContext(), )}
` } } ================================================ FILE: examples/lit/basic/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "emitDecoratorMetadata": true, "noEmit": true, "jsx": "react-jsx", "experimentalDecorators": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/basic/twind.config.ts ================================================ import { defineConfig } from '@twind/core' import presetAutoprefix from '@twind/preset-autoprefix' import presetTailwind from '@twind/preset-tailwind/base' export default defineConfig({ presets: [presetAutoprefix(), presetTailwind()], }) ================================================ FILE: examples/lit/basic/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/lit/column-sizing/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/column-sizing/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/column-sizing/index.html ================================================ Vite App
================================================ FILE: examples/lit/column-sizing/package.json ================================================ { "name": "tanstack-lit-table-example-column-sizing", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/lit-table": "^9.0.0-alpha.10", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/column-sizing/src/main.ts ================================================ import { customElement } from 'lit/decorators.js' import { LitElement, html } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { ColumnDef, TableController, columnResizingFeature, columnSizingFeature, flexRender, tableFeatures, } from '@tanstack/lit-table' import { Person, makeData } from './makeData' const _features = tableFeatures({ columnSizingFeature, columnResizingFeature, }) const columns: Array> = [ { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => html`Last Name`, }, { accessorKey: 'age', header: () => 'Age', }, { accessorKey: 'visits', header: () => html`Visits`, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, { accessorKey: 'rank', header: 'Rank', }, { accessorKey: 'createdAt', header: 'Created At', }, ] const data: Array = makeData(1000) @customElement('lit-table-example') class LitTableExample extends LitElement { private tableController = new TableController(this) protected render() { const table = this.tableController.table( { _features, _rowModels: {}, data, columns, columnResizeMode: 'onChange', columnResizeDirection: 'ltr', debugTable: true, debugHeaders: true, debugColumns: true, }, (state) => ({ columnSizing: state.columnSizing, columnResizing: state.columnResizing, }), ) return html` ${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html` ${headerGroup.headers.map( (header) => html` `, )} `, )} ${table .getRowModel() .rows.slice(0, 10) .map( (row) => html` ${row .getAllCells() .map( (cell) => html` `, )} `, )}
${flexRender( header.column.columnDef.header, header.getContext(), )} ${header.isPlaceholder ? null : html`
`}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
${JSON.stringify(table.state, null, 2)}
` } } ================================================ FILE: examples/lit/column-sizing/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string | undefined age: number visits: number | undefined progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), age: faker.number.int(40), visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], rank: faker.number.int(100), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/lit/column-sizing/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/filters/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/filters/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/filters/index.html ================================================ Vite App
================================================ FILE: examples/lit/filters/package.json ================================================ { "name": "tanstack-lit-table-example-filters", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/lit-table": "^9.0.0-alpha.10", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/filters/src/main.ts ================================================ import { customElement, property } from 'lit/decorators.js' import { LitElement, html } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { TableController, columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, flexRender, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/lit-table' import { makeData } from './makeData' import type { CellData, Column, ColumnDef, RowData, TableFeatures, } from '@tanstack/lit-table' import type { Person } from './makeData' const _features = tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }) const columns: Array> = [ { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => html`Last Name`, }, { accessorFn: (row) => `${row.firstName} ${row.lastName}`, id: 'fullName', header: 'Full Name', cell: (info) => info.getValue(), }, { accessorKey: 'age', header: () => 'Age', meta: { filterVariant: 'range', }, }, { accessorKey: 'visits', header: () => html`Visits`, meta: { filterVariant: 'range', }, }, { accessorKey: 'status', header: 'Status', meta: { filterVariant: 'select', }, }, { accessorKey: 'progress', header: 'Profile Progress', meta: { filterVariant: 'range', }, }, ] declare module '@tanstack/lit-table' { // allows us to define custom properties for our columns interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { filterVariant?: 'text' | 'range' | 'select' } } const data = makeData(50_000) @customElement('column-filter') class ColumnFilter extends LitElement { @property() private column!: Column private onChange(evt: InputEvent) { this.column.setFilterValue((evt.target as HTMLInputElement).value) } render() { const { filterVariant } = this.column.columnDef.meta ?? {} const columnFilterValue = this.column.getFilterValue() switch (filterVariant) { case 'select': return html` ` case 'range': return html`
` default: return html`` } return null } } @customElement('lit-table-example') class LitTableExample extends LitElement { private tableController = new TableController(this) protected render() { const table = this.tableController.table( { _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, data, columns, debugTable: true, debugHeaders: true, debugColumns: false, }, (state) => ({ columnFilters: state.columnFilters }), ) return html` ${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html` ${repeat( headerGroup.headers, (header) => header.id, (header) => html` `, )} `, )} ${table .getRowModel() .rows.slice(0, 10) .map( (row) => html` ${row .getAllCells() .map( (cell) => html` `, )} `, )}
${header.isPlaceholder ? null : html`
${flexRender( header.column.columnDef.header, header.getContext(), )} ${{ asc: ' 🔼', desc: ' 🔽' }[ header.column.getIsSorted() as string ] ?? null}
${header.column.getCanFilter() ? html`
` : null} `}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
Page ${table.store.state.pagination.pageIndex + 1} of ${table.getPageCount()}
${JSON.stringify(table.state.columnFilters, null, 2)}
` } } ================================================ FILE: examples/lit/filters/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/lit/filters/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "experimentalDecorators": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/filters/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/lit/row-selection/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/row-selection/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/row-selection/index.html ================================================ Vite App
================================================ FILE: examples/lit/row-selection/package.json ================================================ { "name": "tanstack-lit-table-example-row-selection", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/lit-table": "^9.0.0-alpha.10", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/row-selection/src/main.ts ================================================ import { customElement } from 'lit/decorators.js' import { LitElement, html } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { TableController, columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, filterFns, flexRender, rowPaginationFeature, rowSelectionFeature, tableFeatures, } from '@tanstack/lit-table' import { makeData } from './makeData' import type { ColumnDef } from '@tanstack/lit-table' import type { Person } from './makeData' const _features = tableFeatures({ rowSelectionFeature, columnFilteringFeature, rowPaginationFeature, }) const columns: Array> = [ { id: 'select', header: ({ table }) => html` `, cell: ({ row }) => html` `, }, { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => html`Last Name`, }, { accessorFn: (row) => `${row.firstName} ${row.lastName}`, id: 'fullName', header: 'Full Name', cell: (info) => info.getValue(), }, { accessorKey: 'age', header: () => 'Age', }, { accessorKey: 'visits', header: () => html`Visits`, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] const data = makeData(50_000) @customElement('lit-table-example') class LitTableExample extends LitElement { private tableController = new TableController(this) protected render() { const table = this.tableController.table( { _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, data, columns, enableRowSelection: true, debugTable: true, }, (state) => ({ rowSelection: state.rowSelection }), ) return html` ${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html` ${repeat( headerGroup.headers, (header) => header.id, (header) => html` `, )} `, )} ${table .getRowModel() .rows.slice(0, 10) .map( (row) => html` ${row .getAllCells() .map( (cell) => html` `, )} `, )}
${header.isPlaceholder ? null : html`
${flexRender( header.column.columnDef.header, header.getContext(), )}
`}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
Page ${table.store.state.pagination.pageIndex + 1} of ${table.getPageCount()}
` } } ================================================ FILE: examples/lit/row-selection/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string | undefined age: number visits: number | undefined progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), age: faker.number.int(40), visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], rank: faker.number.int(100), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/lit/row-selection/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "experimentalDecorators": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/row-selection/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/lit/sorting/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/sorting/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/sorting/index.html ================================================ Vite App
================================================ FILE: examples/lit/sorting/package.json ================================================ { "name": "tanstack-lit-table-example-sorting", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/lit-table": "^9.0.0-alpha.10", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/sorting/src/main.ts ================================================ import { customElement } from 'lit/decorators.js' import { LitElement, html } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { TableController, createSortedRowModel, flexRender, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/lit-table' import { Person, makeData } from './makeData' import type { ColumnDef, SortFn } from '@tanstack/lit-table' const _features = tableFeatures({ rowSortingFeature, }) const sortStatusFn: SortFn = (rowA, rowB, _columnId) => { const statusA = rowA.original.status const statusB = rowB.original.status const statusOrder = ['single', 'complicated', 'relationship'] return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB) } const columns: Array> = [ { accessorKey: 'firstName', cell: (info) => info.getValue(), // this column will sort in ascending order by default since it is a string column }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => html`Last Name`, sortUndefined: 'last', // force undefined values to the end sortDescFirst: false, // first sort order will be ascending (nullable values can mess up auto detection of sort order) }, { accessorKey: 'age', header: () => 'Age', // this column will sort in descending order by default since it is a number column }, { accessorKey: 'visits', header: () => html`Visits`, sortUndefined: 'last', // force undefined values to the end }, { accessorKey: 'status', header: 'Status', sortFn: sortStatusFn, // use our custom sorting function for this enum column }, { accessorKey: 'progress', header: 'Profile Progress', // enableSorting: false, //disable sorting for this column }, { accessorKey: 'rank', header: 'Rank', invertSorting: true, // invert the sorting order (golf score-like where smaller is better) }, { accessorKey: 'createdAt', header: 'Created At', // sortFn: 'datetime' //make sure table knows this is a datetime column (usually can detect if no null values) }, ] const data: Array = makeData(1000) @customElement('lit-table-example') class LitTableExample extends LitElement { private tableController = new TableController(this) protected render() { const table = this.tableController.table( { _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), }, columns, data, }, (state) => ({ sorting: state.sorting }), ) return html` ${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html` ${headerGroup.headers.map( (header) => html` `, )} `, )} ${table .getRowModel() .rows.slice(0, 10) .map( (row) => html` ${row .getAllCells() .map( (cell) => html` `, )} `, )}
${header.isPlaceholder ? null : html`
${flexRender( header.column.columnDef.header, header.getContext(), )} ${{ asc: ' 🔼', desc: ' 🔽' }[ header.column.getIsSorted() as string ] ?? null}
`}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
${JSON.stringify(table.state.sorting, null, 2)}
` } } ================================================ FILE: examples/lit/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string | undefined age: number visits: number | undefined progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), age: faker.number.int(40), visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], rank: faker.number.int(100), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/lit/sorting/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/sorting/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/lit/sorting-dynamic-data/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/sorting-dynamic-data/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/sorting-dynamic-data/index.html ================================================ Vite App
================================================ FILE: examples/lit/sorting-dynamic-data/package.json ================================================ { "name": "tanstack-lit-table-example-sorting-dynamic-data", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/lit-table": "^9.0.0-alpha.10", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/sorting-dynamic-data/src/main.ts ================================================ import { customElement } from 'lit/decorators.js' import { html, LitElement, PropertyValueMap } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { state } from 'lit/decorators/state.js' import { ColumnDef, flexRender, createSortedRowModel, TableController, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/lit-table' import type { SortFn } from '@tanstack/lit-table' import { makeData, Person } from './makeData' const _features = tableFeatures({ rowSortingFeature, }) const sortStatusFn: SortFn = ( rowA, rowB, _columnId, ) => { const statusA = rowA.original.status const statusB = rowB.original.status const statusOrder = ['single', 'complicated', 'relationship'] return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB) } const columns: ColumnDef[] = [ { accessorKey: 'firstName', cell: (info) => info.getValue(), //this column will sort in ascending order by default since it is a string column }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => html`Last Name`, sortUndefined: 'last', //force undefined values to the end sortDescFirst: false, //first sort order will be ascending (nullable values can mess up auto detection of sort order) }, { accessorKey: 'age', header: () => 'Age', //this column will sort in descending order by default since it is a number column }, { accessorKey: 'visits', header: () => html`Visits`, sortUndefined: 'last', //force undefined values to the end }, { accessorKey: 'status', header: 'Status', sortFn: sortStatusFn, //use our custom sorting function for this enum column }, { accessorKey: 'progress', header: 'Profile Progress', // enableSorting: false, //disable sorting for this column }, { accessorKey: 'rank', header: 'Rank', invertSorting: true, //invert the sorting order (golf score-like where smaller is better) }, { accessorKey: 'createdAt', header: 'Created At', // sortingFn: 'datetime' //make sure table knows this is a datetime column (usually can detect if no null values) }, ] const data: Person[] = makeData(1000) @customElement('lit-table-example') class LitTableExample extends LitElement { @state() private _multiplier: number = 1 @state() private _data: Person[] = new Array() private tableController = new TableController(this) constructor() { super() this._data = [...data] } protected willUpdate( _changedProperties: PropertyValueMap | Map, ): void { super.willUpdate(_changedProperties) if (_changedProperties.has('_multiplier')) { const newData: Person[] = data.map((d) => { const p: Person = { ...d, visits: d.visits ? d.visits * this._multiplier : undefined, } return p }) this._data.length = 0 this._data = newData } } protected render() { const table = this.tableController.table( { _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), }, columns, data: this._data, }, (state) => ({ sorting: state.sorting }), ) return html` ${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html` ${headerGroup.headers.map( (header) => html` `, )} `, )} ${table .getRowModel() .rows.slice(0, 10) .map( (row) => html` ${row .getVisibleCells() .map( (cell) => html` `, )} `, )}
${header.isPlaceholder ? null : html`
${flexRender( header.column.columnDef.header, header.getContext(), )} ${{ asc: ' 🔼', desc: ' 🔽' }[ header.column.getIsSorted() as string ] ?? null}
`}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
${JSON.stringify(table.state.sorting, null, 2)}
` } } ================================================ FILE: examples/lit/sorting-dynamic-data/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string | undefined age: number visits: number | undefined progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Person[] } const range = (len: number) => { const arr: number[] = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), age: faker.number.int(40), visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0]!, rank: faker.number.int(100), } } export function makeData(...lens: number[]) { const makeDataLevel = (depth = 0): Person[] => { const len = lens[depth]! return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/lit/sorting-dynamic-data/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/sorting-dynamic-data/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/lit/virtualized-rows/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/lit/virtualized-rows/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/lit/virtualized-rows/index.html ================================================ Vite App
================================================ FILE: examples/lit/virtualized-rows/package.json ================================================ { "name": "tanstack-lit-table-virtualized-rows", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/lit-table": "^9.0.0-alpha.10", "@tanstack/lit-virtual": "^3.13.19", "lit": "^3.3.2" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/lit/virtualized-rows/src/main.ts ================================================ import { customElement } from 'lit/decorators.js' import { LitElement, html } from 'lit' import { repeat } from 'lit/directives/repeat.js' import { TableController, columnSizingFeature, createSortedRowModel, flexRender, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/lit-table' import { styleMap } from 'lit/directives/style-map.js' import { Ref, createRef, ref } from 'lit/directives/ref.js' import { VirtualizerController } from '@tanstack/lit-virtual' import { Person, makeData } from './makeData.ts' import type { ColumnDef } from '@tanstack/lit-table' const _features = tableFeatures({ columnSizingFeature, rowSortingFeature, }) const columns: Array> = [ { accessorKey: 'id', header: 'ID', size: 60, }, { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => html`Last Name`, }, { accessorKey: 'age', header: () => 'Age', size: 50, }, { accessorKey: 'visits', header: () => html`Visits`, size: 50, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', size: 80, }, { accessorKey: 'createdAt', header: 'Created At', cell: (info) => info.getValue().toLocaleString(), size: 250, }, ] const data = makeData(50_000) @customElement('lit-table-example') class LitTableExample extends LitElement { private tableController = new TableController(this) private tableContainerRef: Ref = createRef() private rowVirtualizerController: VirtualizerController connectedCallback() { this.rowVirtualizerController = new VirtualizerController(this, { count: data.length, getScrollElement: () => this.tableContainerRef.value!, estimateSize: () => 33, overscan: 5, }) super.connectedCallback() } protected render() { const table = this.tableController.table( { _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), }, columns, data, }, () => ({}), // selector - empty since we don't need any state ) const { rows } = table.getRowModel() const virtualizer = this.rowVirtualizerController.getVirtualizer() return html`
(${data.length} rows)
${repeat( table.getHeaderGroups(), (headerGroup) => headerGroup.id, (headerGroup) => html` ${repeat( headerGroup.headers, (header) => header.id, (header) => html` `, )} `, )} ${repeat( this.rowVirtualizerController .getVirtualizer() .getVirtualItems(), (item) => item.key, (item) => { const row = rows[item.index] return html` this.rowVirtualizerController .getVirtualizer() .measureElement(node), )} > ${repeat( row.getAllCells(), (cell) => cell.id, (cell) => html` `, )} ` }, )}
${flexRender( header.column.columnDef.header, header.getContext(), )} ${{ asc: ' 🔼', desc: ' 🔽' }[ header.column.getIsSorted() as string ] ?? null}
${flexRender( cell.column.columnDef.cell, cell.getContext(), )}
` } } ================================================ FILE: examples/lit/virtualized-rows/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: number firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' createdAt: Date } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (index: number): Person => { return { id: index + 1, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(d), } }) } return makeDataLevel() } ================================================ FILE: examples/lit/virtualized-rows/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "emitDecoratorMetadata": true, "noEmit": true, "jsx": "react-jsx", "experimentalDecorators": true, "useDefineForClassFields": false, "strictPropertyInitialization": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/lit/virtualized-rows/twind.config.ts ================================================ import { defineConfig } from '@twind/core' import presetAutoprefix from '@twind/preset-autoprefix' import presetTailwind from '@twind/preset-tailwind/base' export default defineConfig({ presets: [presetAutoprefix(), presetTailwind()], }) ================================================ FILE: examples/lit/virtualized-rows/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/preact/basic/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/preact/basic/README.md ================================================ # `create-preact`

Get started using Preact and Vite!

## Getting Started - `npm run dev` - Starts a dev server at http://localhost:5173/ - `npm run build` - Builds for production, emitting to `dist/` - `npm run preview` - Starts a server at http://localhost:4173/ to test production build locally ================================================ FILE: examples/preact/basic/index.html ================================================ Vite + Preact
================================================ FILE: examples/preact/basic/package.json ================================================ { "name": "tanstack-table-example-preact-basic", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/preact-table": "^9.0.0-alpha.16", "preact": "^10.28.2" }, "devDependencies": { "@preact/preset-vite": "^2.10.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/preact/basic/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/preact/basic/src/main.tsx ================================================ import { render } from 'preact' import { useReducer, useState } from 'preact/hooks' import { tableFeatures, useTable } from '@tanstack/preact-table' import type { ColumnDef } from '@tanstack/preact-table' import './index.css' // This example uses the classic standalone `useTable` hook to create a table without the new `createTableHelper` util. // 1. Define what the shape of your data will be for each row type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 12, visits: 100, status: 'Single', progress: 70, }, ] // 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 _features = tableFeatures({}) // util method to create sharable TFeatures object/type // 4. Define the columns for your table. This uses the new `ColumnDef` type to define columns. Alternatively, check out the createTableHelper/createColumnHelper util for an even more type-safe way to define columns. const columns: Array> = [ { accessorKey: 'firstName', // accessorKey method (most common for simple use-cases) header: 'First Name', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, // accessorFn used (alternative) along with a custom id id: 'lastName', header: () => Last Name, cell: (info) => {info.getValue()}, }, { accessorFn: (row) => Number(row.age), // accessorFn used to transform the data id: 'age', header: () => 'Age', cell: (info) => { return info.renderValue() }, }, { accessorKey: 'visits', header: () => Visits, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] function App() { // 5. Store data with a stable reference const [data, _setData] = useState(() => [...defaultData]) const rerender = useReducer(() => ({}), {})[1] // 6. Create the table instance with required _features, columns, and data const table = useTable({ _features, // new required option in V9. Tell the table which features you are importing and using (better tree-shaking) _rowModels: {}, // `Core` row model is now included by default, but you can still override it here columns, data, // add additional table options here }) // 7. Render your table markup from the table instance APIs return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') render(, rootElement) ================================================ FILE: examples/preact/basic/tsconfig.json ================================================ { "compilerOptions": { "strictNullChecks": true, "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "noEmit": true, "allowJs": true, "checkJs": true, /* Preact Config */ "jsx": "react-jsx", "jsxImportSource": "preact", "skipLibCheck": true, "paths": { "react": ["./node_modules/preact/compat/"], "react-dom": ["./node_modules/preact/compat/"] } }, "include": ["node_modules/vite/client.d.ts", "src/**/*"], "exclude": ["dist/**/*", "node_modules"] } ================================================ FILE: examples/preact/basic/vite.config.ts ================================================ import { defineConfig } from 'vite' import preact from '@preact/preset-vite' // https://vitejs.dev/config/ export default defineConfig({ plugins: [preact()], }) ================================================ FILE: examples/preact/sorting/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/preact/sorting/README.md ================================================ # `create-preact`

Get started using Preact and Vite!

## Getting Started - `npm run dev` - Starts a dev server at http://localhost:5173/ - `npm run build` - Builds for production, emitting to `dist/` - `npm run preview` - Starts a server at http://localhost:4173/ to test production build locally ================================================ FILE: examples/preact/sorting/index.html ================================================ Vite + Preact
================================================ FILE: examples/preact/sorting/package.json ================================================ { "name": "tanstack-table-example-preact-sorting", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/preact-table": "^9.0.0-alpha.16", "preact": "^10.28.2" }, "devDependencies": { "@preact/preset-vite": "^2.10.3", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/preact/sorting/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/preact/sorting/src/main.tsx ================================================ import { render } from 'preact' import { useMemo, useReducer, useState } from 'preact/hooks' import './index.css' import { createSortedRowModel, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/preact-table' import { makeData } from './makeData' import type { ColumnDef, SortFn, SortingState } from '@tanstack/preact-table' import type { Person } from './makeData' const _features = tableFeatures({ rowSortingFeature, }) // custom sorting logic for one of our enum columns const sortStatusFn: SortFn = (rowA, rowB, _columnId) => { const statusA = rowA.original.status const statusB = rowB.original.status const statusOrder = ['single', 'complicated', 'relationship'] return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB) } function App() { const rerender = useReducer(() => ({}), {})[1] const columns = useMemo>>( () => [ { accessorKey: 'firstName', cell: (info) => info.getValue(), // this column will sort in ascending order by default since it is a string column }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, sortUndefined: 'last', // force undefined values to the end sortDescFirst: false, // first sort order will be ascending (nullable values can mess up auto detection of sort order) }, { accessorKey: 'age', header: () => 'Age', // this column will sort in descending order by default since it is a number column }, { accessorKey: 'visits', header: () => Visits, sortUndefined: 'last', // force undefined values to the end }, { accessorKey: 'status', header: 'Status', sortFn: sortStatusFn, // use our custom sorting function for this enum column }, { accessorKey: 'progress', header: 'Profile Progress', // enableSorting: false, // disable sorting for this column }, { accessorKey: 'rank', header: 'Rank', invertSorting: true, // invert the sorting order (golf score-like where smaller is better) }, { accessorKey: 'createdAt', header: 'Created At', // sortFn: 'datetime' //make sure table knows this is a datetime column (usually can detect if no null values) }, ], [], ) const [data, setData] = useState(() => makeData(1_000)) const refreshData = () => setData(() => makeData(100_000)) // stress test with 100k rows // optionally, manage sorting state in your own state management (although preact state causes more re-renders here than necessary) const [sorting, setSorting] = useState([]) console.log('sorting', sorting) const table = useTable( { _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), // client-side sorting }, columns, data, debugTable: true, state: { sorting, }, onSortingChange: setSorting, // no need to pass pageCount or rowCount with client-side pagination as it is calculated automatically // autoResetPageIndex: false, // turn off page index reset when sorting or filtering - default on/true // enableMultiSort: false, //Don't allow shift key to sort multiple columns - default on/true // enableSorting: false, // - default on/true // enableSortingRemoval: false, //Don't allow - default on/true // isMultiSortEvent: (e) => true, //Make all clicks multi-sort - default requires `shift` key // maxMultiSortColCount: 3, // only allow 3 columns to be sorted at once - default is Infinity }, // (state) => ({ state }), // uncomment to subscribe to the entire table state (this is how it worked in v8 by default) ) return ( ({ sorting: state.sorting })}> {(_state) => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table .getRowModel() .rows.slice(0, 10) .map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : (
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
{table.getRowModel().rows.length.toLocaleString()} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') render(, rootElement) ================================================ FILE: examples/preact/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string | undefined age: number visits: number | undefined progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), age: faker.number.int(40), visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], rank: faker.number.int(100), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/preact/sorting/tsconfig.json ================================================ { "compilerOptions": { "strictNullChecks": true, "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "noEmit": true, "allowJs": true, "checkJs": true, /* Preact Config */ "jsx": "react-jsx", "jsxImportSource": "preact", "skipLibCheck": true, "paths": { "react": ["./node_modules/preact/compat/"], "react-dom": ["./node_modules/preact/compat/"] } }, "include": ["node_modules/vite/client.d.ts", "src/**/*"], "exclude": ["dist/**/*", "node_modules"] } ================================================ FILE: examples/preact/sorting/vite.config.ts ================================================ import { defineConfig } from 'vite' import preact from '@preact/preset-vite' // https://vitejs.dev/config/ export default defineConfig({ plugins: [preact()], }) ================================================ FILE: examples/react/basic-external-state/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/basic-external-state/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/basic-external-state/index.html ================================================ Vite App
================================================ FILE: examples/react/basic-external-state/package.json ================================================ { "name": "tanstack-table-example-basic-external-state", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-store": "^0.9.2", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/basic-external-state/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/basic-external-state/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { createColumnHelper, createPaginatedRowModel, createSortedRowModel, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { PaginationState, SortingState } from '@tanstack/react-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const _features = tableFeatures({ rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { header: 'Last Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: 'Age', }), columnHelper.accessor('visits', { header: 'Visits', }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', }), ]) function App() { const [data] = React.useState(() => makeData(1000)) const rerender = React.useReducer(() => ({}), {})[1] // Manage sorting state with React.useState (although react state causes more re-renders here than necessary compared to using a store) const [sorting, setSorting] = React.useState([]) // Manage pagination state with React.useState (although react state causes more re-renders here than necessary compared to using a store) const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10, }) console.log('sorting', sorting) console.log('pagination', pagination) // Create the table and pass state + onChange handlers const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, state: { sorting, // connect our sorting state back down to the table pagination, // connect our pagination state back down to the table }, onSortingChange: setSorting, // raise sorting state changes to our own state management onPaginationChange: setPagination, // raise pagination state changes to our own state management }) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : (
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
Page
{pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{JSON.stringify({ sorting, pagination }, null, 2)}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/basic-external-state/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/basic-external-state/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/basic-external-state/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/basic-external-store/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/basic-external-store/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/basic-external-store/index.html ================================================ Vite App
================================================ FILE: examples/react/basic-external-store/package.json ================================================ { "name": "tanstack-table-example-basic-external-store", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-store": "^0.9.2", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/basic-external-store/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/basic-external-store/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { createStore, useStore } from '@tanstack/react-store' import { createColumnHelper, createPaginatedRowModel, createSortedRowModel, getInitialTableState, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const _features = tableFeatures({ rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { header: 'Last Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: 'Age', }), columnHelper.accessor('visits', { header: 'Visits', }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', }), ]) function App() { const [data] = React.useState(() => makeData(1000)) const rerender = React.useReducer(() => ({}), {})[1] // create our own TanStack Store in our own scope (This could just be a global store if defined outside of this component) const [myTableStore] = React.useState(() => createStore( getInitialTableState( _features, // get default initial state from features // custom initial state { sorting: [], pagination: { pageIndex: 0, pageSize: 10 }, }, ), ), ) // Subscribe to store state for reactive updates, custom selector available too const state = useStore(myTableStore, (state) => state) console.log('state', state) // Create the table and pass your store const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, store: myTableStore, debugTable: state.pagination.pageIndex > 2, }) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : (
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
Page
{state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{JSON.stringify(state, null, 2)}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/basic-external-store/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/basic-external-store/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/basic-external-store/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/basic-shadcn/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local !lib ================================================ FILE: examples/react/basic-shadcn/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/basic-shadcn/components.json ================================================ { "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": false, "tsx": true, "tailwind": { "config": "", "css": "src/index.css", "baseColor": "zinc", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, "iconLibrary": "lucide" } ================================================ FILE: examples/react/basic-shadcn/index.html ================================================ Vite App
================================================ FILE: examples/react/basic-shadcn/package.json ================================================ { "name": "tanstack-table-example-basic-shadcn", "version": "0.0.0", "type": "module", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.1.18", "@tanstack/react-table": "^9.0.0-alpha.19", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.563.0", "react": "^19.2.4", "react-dom": "^19.2.4", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/basic-shadcn/src/components/ui/button.tsx ================================================ import * as React from 'react' import { Slot } from '@radix-ui/react-slot' import { cva } from 'class-variance-authority' import type { VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0", { variants: { variant: { default: 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90', destructive: 'bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90', outline: 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground', secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', ghost: 'hover:bg-accent hover:text-accent-foreground', link: 'text-primary underline-offset-4 hover:underline', }, size: { default: 'h-9 px-4 py-2 has-[>svg]:px-3', sm: 'h-8 rounded-md px-3 has-[>svg]:px-2.5', lg: 'h-10 rounded-md px-6 has-[>svg]:px-4', icon: 'size-9', }, }, defaultVariants: { variant: 'default', size: 'default', }, }, ) function Button({ className, variant, size, asChild = false, ...props }: React.ComponentProps<'button'> & VariantProps & { asChild?: boolean }) { const Comp = asChild ? Slot : 'button' return ( ) } export { Button, buttonVariants } ================================================ FILE: examples/react/basic-shadcn/src/components/ui/table.tsx ================================================ import * as React from 'react' import { cn } from '@/lib/utils' function Table({ className, ...props }: React.ComponentProps<'table'>) { return (
) } function TableHeader({ className, ...props }: React.ComponentProps<'thead'>) { return ( ) } function TableBody({ className, ...props }: React.ComponentProps<'tbody'>) { return ( ) } function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) { return ( tr]:last:border-b-0', className, )} {...props} /> ) } function TableRow({ className, ...props }: React.ComponentProps<'tr'>) { return ( ) } function TableHead({ className, ...props }: React.ComponentProps<'th'>) { return ( ) } const DragAlongCell = ({ cell, }: { cell: Cell }) => { const { isDragging, setNodeRef, transform } = useSortable({ id: cell.column.id, }) const style: CSSProperties = { opacity: isDragging ? 0.8 : 1, position: 'relative', transform: CSS.Translate.toString(transform), // translate instead of transform to avoid squishing transition: 'width transform 0.2s ease-in-out', width: cell.column.getSize(), zIndex: isDragging ? 1 : 0, } return ( ) } function App() { const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), id: 'firstName', size: 150, }), columnHelper.accessor((row) => row.lastName, { cell: (info) => info.getValue(), header: () => Last Name, id: 'lastName', size: 150, }), columnHelper.accessor('age', { header: () => 'Age', id: 'age', size: 120, }), columnHelper.accessor('visits', { header: () => Visits, id: 'visits', size: 120, }), columnHelper.accessor('status', { header: 'Status', id: 'status', size: 150, }), columnHelper.accessor('progress', { header: 'Profile Progress', id: 'progress', size: 180, }), ]), [], ) const [data, setData] = React.useState(() => makeData(20)) const rerender = () => setData(() => makeData(20)) const table = useAppTable( { columns, data, initialState: { columnOrder: columns.map((c) => c.id!), }, }, (state) => state, ) // reorder columns after drag & drop function handleDragEnd(event: DragEndEvent) { const { active, over } = event if (over && active.id !== over.id) { table.setColumnOrder((prevColumnOrder) => { const oldIndex = prevColumnOrder.indexOf(active.id as string) const newIndex = prevColumnOrder.indexOf(over.id as string) return arrayMove(prevColumnOrder, oldIndex, newIndex) // this is just a splice util }) } } const sensors = useSensors( useSensor(MouseSensor, {}), useSensor(TouchSensor, {}), useSensor(KeyboardSensor, {}), ) return ( // NOTE: This provider creates div elements, so don't nest inside of
[role=checkbox]]:translate-y-[2px]', className, )} {...props} /> ) } function TableCell({ className, ...props }: React.ComponentProps<'td'>) { return ( [role=checkbox]]:translate-y-[2px]', className, )} {...props} /> ) } function TableCaption({ className, ...props }: React.ComponentProps<'caption'>) { return (
) } export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, } ================================================ FILE: examples/react/basic-shadcn/src/index.css ================================================ @import 'tailwindcss' source('../'); @plugin 'tailwindcss-animate'; @custom-variant dark (&:is(.dark *)); :root { --background: hsl(0 0% 100%); --foreground: hsl(240 10% 3.9%); --card: hsl(0 0% 100%); --card-foreground: hsl(240 10% 3.9%); --popover: hsl(0 0% 100%); --popover-foreground: hsl(240 10% 3.9%); --primary: hsl(240 5.9% 10%); --primary-foreground: hsl(0 0% 98%); --secondary: hsl(240 4.8% 95.9%); --secondary-foreground: hsl(240 5.9% 10%); --muted: hsl(240 4.8% 95.9%); --muted-foreground: hsl(240 3.8% 46.1%); --accent: hsl(240 4.8% 95.9%); --accent-foreground: hsl(240 5.9% 10%); --destructive: hsl(0 84.2% 60.2%); --destructive-foreground: hsl(0 0% 98%); --border: hsl(240 5.9% 90%); --input: hsl(240 5.9% 90%); --ring: hsl(240 10% 3.9%); --chart-1: hsl(12 76% 61%); --chart-2: hsl(173 58% 39%); --chart-3: hsl(197 37% 24%); --chart-4: hsl(43 74% 66%); --chart-5: hsl(27 87% 67%); --radius: 0.6rem; } .dark { --background: hsl(240 10% 3.9%); --foreground: hsl(0 0% 98%); --card: hsl(240 10% 3.9%); --card-foreground: hsl(0 0% 98%); --popover: hsl(240 10% 3.9%); --popover-foreground: hsl(0 0% 98%); --primary: hsl(0 0% 98%); --primary-foreground: hsl(240 5.9% 10%); --secondary: hsl(240 3.7% 15.9%); --secondary-foreground: hsl(0 0% 98%); --muted: hsl(240 3.7% 15.9%); --muted-foreground: hsl(240 5% 64.9%); --accent: hsl(240 3.7% 15.9%); --accent-foreground: hsl(0 0% 98%); --destructive: hsl(0 62.8% 30.6%); --destructive-foreground: hsl(0 0% 98%); --border: hsl(240 3.7% 15.9%); --input: hsl(240 3.7% 15.9%); --ring: hsl(240 4.9% 83.9%); --chart-1: hsl(220 70% 50%); --chart-2: hsl(160 60% 45%); --chart-3: hsl(30 80% 55%); --chart-4: hsl(280 65% 60%); --chart-5: hsl(340 75% 55%); } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --color-chart-1: var(--chart-1); --color-chart-2: var(--chart-2); --color-chart-3: var(--chart-3); --color-chart-4: var(--chart-4); --color-chart-5: var(--chart-5); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } } ================================================ FILE: examples/react/basic-shadcn/src/lib/utils.ts ================================================ import { clsx } from 'clsx' import { twMerge } from 'tailwind-merge' import type { ClassValue } from 'clsx' export function cn(...inputs: Array) { return twMerge(clsx(inputs)) } ================================================ FILE: examples/react/basic-shadcn/src/main.tsx ================================================ import * as React from 'react' import ReactDOM from 'react-dom/client' import { tableFeatures, useTable } from '@tanstack/react-table' import { Button } from './components/ui/button' import { Table, TableBody, TableCell, TableFooter, TableHeader, TableRow, } from './components/ui/table' import type { ColumnDef } from '@tanstack/react-table' import './index.css' // This example uses the classic standalone `useTable` hook to create a table without the new `createTableHelper` util. // 1. Define what the shape of your data will be for each row type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 12, visits: 100, status: 'Single', progress: 70, }, ] // 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 _features = tableFeatures({}) // util method to create sharable TFeatures object/type // 4. Define the columns for your table. This uses the new `ColumnDef` type to define columns. Alternatively, check out the createTableHelper/createColumnHelper util for an even more type-safe way to define columns. const columns: Array> = [ { accessorKey: 'firstName', // accessorKey method (most common for simple use-cases) header: 'First Name', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, // accessorFn used (alternative) along with a custom id id: 'lastName', header: () => Last Name, cell: (info) => {info.getValue()}, }, { accessorFn: (row) => Number(row.age), // accessorFn used to transform the data id: 'age', header: () => 'Age', cell: (info) => { return info.renderValue() }, }, { accessorKey: 'visits', header: () => Visits, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] function App() { // 5. Store data with a stable reference const [data, _setData] = React.useState(() => [...defaultData]) const rerender = React.useReducer(() => ({}), {})[1] // 6. Create the table instance with required _features, columns, and data const table = useTable({ _features, // new required option in V9. Tell the table which features you are importing and using (better tree-shaking) _rowModels: {}, // `Core` row model is now included by default, but you can still override it here columns, data, // add additional table options here }) // 7. Render your table markup from the table instance APIs return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/basic-shadcn/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "baseUrl": ".", "paths": { "@/*": ["src/*"] } }, "include": ["src"] } ================================================ FILE: examples/react/basic-shadcn/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' import tailwindcss from '@tailwindcss/vite' import * as path from 'path' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), tailwindcss(), ], resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, }) ================================================ FILE: examples/react/basic-use-app-table/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/basic-use-app-table/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/basic-use-app-table/index.html ================================================ Vite App
================================================ FILE: examples/react/basic-use-app-table/package.json ================================================ { "name": "tanstack-table-example-basic-use-app-table", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/basic-use-app-table/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/basic-use-app-table/src/main.tsx ================================================ import * as React from 'react' import ReactDOM from 'react-dom/client' import { createTableHook } from '@tanstack/react-table' import './index.css' // This example uses the new `createTableHook` method to create a re-usable table hook factory 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 lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 28, visits: 100, status: 'Single', progress: 70, }, ] // 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 { useAppTable, createAppColumnHelper } = createTableHook({ _features: {}, _rowModels: {}, // client-side row models. `Core` row model is now included by default, but you can still override it here debugTable: true, }) // 4. Create a helper object to help define our columns const columnHelper = createAppColumnHelper() // 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, }), ]) function App() { // 6. 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 createTableHook call above const table = useAppTable({ columns, data, // add additional table options here or in the createTableHook call above }) // 8. Render your table markup from the table instance APIs return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/basic-use-app-table/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/basic-use-app-table/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/basic-use-legacy-table/index.html ================================================ TanStack Table - useLegacyTable Example
================================================ FILE: examples/react/basic-use-legacy-table/package.json ================================================ { "name": "tanstack-table-example-basic-use-legacy-table", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/basic-use-legacy-table/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/basic-use-legacy-table/src/main.tsx ================================================ /** * This example demonstrates the useLegacyTable hook which provides * a v8-style API for easier migration from TanStack Table v8 to v9. * * Key differences from the v9 useTable hook: * - No need to define _features - all stock features are included * - Uses v8-style get*RowModel() options instead of _rowModels * - Subscribes to all state automatically (like v8 behavior) * * NOTE: useLegacyTable is deprecated and intended only as a migration aid. * New code should use useTable with explicit _features and _rowModels. */ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { flexRender } from '@tanstack/react-table' import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, legacyCreateColumnHelper, useLegacyTable, } from '@tanstack/react-table/legacy' import { makeData } from './makeData' import type { CellData, ColumnFiltersState, PaginationState, RowData, SortingState, TableFeatures, } from '@tanstack/react-table' import type { LegacyColumn } from '@tanstack/react-table/legacy' // legacy types import type { Person } from './makeData' declare module '@tanstack/react-table' { // allows us to define custom properties for our columns interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { filterVariant?: 'text' | 'range' | 'select' } } const columnHelper = legacyCreateColumnHelper() function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }), columnHelper.accessor((row) => `${row.firstName} ${row.lastName}`, { id: 'fullName', header: 'Full Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: () => 'Age', meta: { filterVariant: 'range', }, }), columnHelper.accessor('visits', { header: () => Visits, meta: { filterVariant: 'range', }, }), columnHelper.accessor('status', { header: 'Status', meta: { filterVariant: 'select', }, }), columnHelper.accessor('progress', { header: 'Profile Progress', meta: { filterVariant: 'range', }, }), ]), [], ) const [data, setData] = React.useState>(() => makeData(5_000)) const refreshData = () => setData((_old) => makeData(50_000)) // stress test const [sorting, setSorting] = React.useState([]) const [columnFilters, setColumnFilters] = React.useState( [], ) const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10, }) // Using useLegacyTable with the v8-style API! // Notice how we use get*RowModel() options instead of _rowModels // and we don't need to define _features const table = useLegacyTable({ data, columns, // V8-style row model options (these are mapped to v9 _rowModels under the hood) getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), // client side filtering getSortedRowModel: getSortedRowModel(), // client side sorting getPaginationRowModel: getPaginationRowModel(), state: { columnFilters, pagination, sorting, }, onColumnFiltersChange: setColumnFilters, onPaginationChange: setPagination, onSortingChange: setSorting, // Debug options work the same debugTable: true, debugColumns: true, }) return (
Migration Example: This example uses the deprecated{' '} useLegacyTable hook with v8-style API. See the{' '} filters example {' '} for the recommended v9 approach.
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( <>
{/* With useLegacyTable, we use flexRender instead of table.FlexRender */} {flexRender( header.column.columnDef.header, header.getContext(), )} {{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
{header.column.getCanFilter() ? (
) : null} )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
Page
{pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{table.getPrePaginatedRowModel().rows.length} Rows

Current State:

          {JSON.stringify({ columnFilters, pagination, sorting }, null, 2)}
        
) } function Filter({ column }: { column: LegacyColumn }) { const columnFilterValue = column.getFilterValue() const { filterVariant } = column.columnDef.meta ?? {} return filterVariant === 'range' ? (
{/* See faceted column filters example for min max values functionality */} column.setFilterValue((old: [number, number] | undefined) => [ value, old?.[1], ]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number] | undefined) => [ old?.[0], value, ]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : filterVariant === 'select' ? ( ) : ( column.setFilterValue(value)} placeholder={`Search...`} type="text" value={(columnFilterValue ?? '') as string} /> // See faceted column filters example for datalist search suggestions ) } // A typical debounced input react component function DebouncedInput({ value: initialValue, onChange, debounce = 500, ...props }: { value: string | number onChange: (value: string | number) => void debounce?: number } & Omit, 'onChange'>) { const [value, setValue] = React.useState(initialValue) React.useEffect(() => { setValue(initialValue) }, [initialValue]) React.useEffect(() => { const timeout = setTimeout(() => { onChange(value) }, debounce) return () => clearTimeout(timeout) }, [value]) return ( setValue(e.target.value)} /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/basic-use-legacy-table/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/basic-use-legacy-table/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noErrorTruncation": true }, "include": ["src"] } ================================================ FILE: examples/react/basic-use-legacy-table/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/basic-use-table/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/basic-use-table/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/basic-use-table/index.html ================================================ Vite App
================================================ FILE: examples/react/basic-use-table/package.json ================================================ { "name": "tanstack-table-example-basic-use-table", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/basic-use-table/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/basic-use-table/src/main.tsx ================================================ import * as React from 'react' import ReactDOM from 'react-dom/client' import { tableFeatures, useTable } from '@tanstack/react-table' import type { ColumnDef } from '@tanstack/react-table' import './index.css' // This example uses the classic standalone `useTable` hook to create a table without the new `createTableHelper` util. // 1. Define what the shape of your data will be for each row type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 12, visits: 100, status: 'Single', progress: 70, }, ] // 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 _features = tableFeatures({}) // util method to create sharable TFeatures object/type // 4. Define the columns for your table. This uses the new `ColumnDef` type to define columns. Alternatively, check out the createTableHelper/createColumnHelper util for an even more type-safe way to define columns. const columns: Array> = [ { accessorKey: 'firstName', // accessorKey method (most common for simple use-cases) header: 'First Name', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, // accessorFn used (alternative) along with a custom id id: 'lastName', header: () => Last Name, cell: (info) => {info.getValue()}, }, { accessorFn: (row) => Number(row.age), // accessorFn used to transform the data id: 'age', header: () => 'Age', cell: (info) => { return info.renderValue() }, }, { accessorKey: 'visits', header: () => Visits, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] function App() { // 5. Store data with a stable reference const [data, _setData] = React.useState(() => [...defaultData]) const rerender = React.useReducer(() => ({}), {})[1] // 6. Create the table instance with required _features, columns, and data const table = useTable({ _features, // new required option in V9. Tell the table which features you are importing and using (better tree-shaking) _rowModels: {}, // `Core` row model is now included by default, but you can still override it here columns, data, // add additional table options here }) // 7. Render your table markup from the table instance APIs return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/basic-use-table/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/basic-use-table/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-dnd/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-dnd/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-dnd/index.html ================================================ Vite App
================================================ FILE: examples/react/column-dnd/package.json ================================================ { "name": "tanstack-table-example-column-dnd", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-dnd/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } th div { display: flex; flex-wrap: nowrap; align-items: center; } th button { padding: 1rem; cursor: grab; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/column-dnd/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { FlexRender, columnOrderingFeature, columnSizingFeature, createTableHook, } from '@tanstack/react-table' import { DndContext, KeyboardSensor, MouseSensor, TouchSensor, closestCenter, useSensor, useSensors, } from '@dnd-kit/core' import { restrictToHorizontalAxis } from '@dnd-kit/modifiers' import { SortableContext, arrayMove, horizontalListSortingStrategy, useSortable, } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { makeData } from './makeData' import type { DragEndEvent } from '@dnd-kit/core' import type { CSSProperties } from 'react' import type { Person } from './makeData' import type { Cell, Header } from '@tanstack/react-table' import './index.css' const { appFeatures, useAppTable, createAppColumnHelper } = createTableHook({ _features: { columnOrderingFeature, columnSizingFeature }, _rowModels: {}, debugTable: true, debugHeaders: true, debugColumns: true, }) const columnHelper = createAppColumnHelper() const DraggableTableHeader = ({ header, }: { header: Header }) => { const { attributes, isDragging, listeners, setNodeRef, transform } = useSortable({ id: header.column.id }) const style: CSSProperties = { opacity: isDragging ? 0.8 : 1, position: 'relative', transform: CSS.Translate.toString(transform), // translate instead of transform to avoid squishing transition: 'width transform 0.2s ease-in-out', whiteSpace: 'nowrap', width: header.column.getSize(), zIndex: isDragging ? 1 : 0, } return (
{header.isPlaceholder ? null : }
elements
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-dnd/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/column-dnd/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-dnd/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-groups/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-groups/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-groups/index.html ================================================ Vite App
================================================ FILE: examples/react/column-groups/package.json ================================================ { "name": "tanstack-table-example-column-groups", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-groups/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/column-groups/src/main.tsx ================================================ import * as React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const _features = tableFeatures({}) const columnHelper = createColumnHelper() // use new columnHelper.columns method to create columns with the same TValue generic so TypeScript doesn't complain when passing columns to useTable const columns = columnHelper.columns([ columnHelper.group({ id: 'hello', header: () => Hello, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) function App() { const [data, _setData] = React.useState(() => [...defaultData]) const rerender = React.useReducer(() => ({}), {})[1] const table = useTable({ _features, _rowModels: {}, columns, data, }) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-groups/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-groups/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-ordering/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-ordering/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-ordering/index.html ================================================ Vite App
================================================ FILE: examples/react/column-ordering/package.json ================================================ { "name": "tanstack-table-example-column-ordering", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-ordering/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/column-ordering/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { faker } from '@faker-js/faker' import { columnOrderingFeature, columnVisibilityFeature, createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Person } from './makeData' import './index.css' const _features = tableFeatures({ columnOrderingFeature, columnVisibilityFeature, }) const columnHelper = createColumnHelper() const defaultColumns = columnHelper.columns([ columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) function App() { const [data, setData] = React.useState(() => makeData(20)) const [columns] = React.useState(() => [...defaultColumns]) const rerender = () => setData(() => makeData(20)) const table = useTable({ _features, _rowModels: {}, columns, data, debugTable: true, debugHeaders: true, debugColumns: true, }) const randomizeColumns = () => { table.setColumnOrder( faker.helpers.shuffle(table.getAllLeafColumns().map((d) => d.id)), ) } return ( ({ // subscribe to only the column order and visibility state changes at root level columnOrder: state.columnOrder, columnVisibility: state.columnVisibility, })} > {(_state) => (
{table.getAllLeafColumns().map((column) => { return (
) })}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-ordering/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/column-ordering/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-ordering/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-pinning/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-pinning/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-pinning/index.html ================================================ Vite App
================================================ FILE: examples/react/column-pinning/package.json ================================================ { "name": "tanstack-table-example-column-pinning", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-pinning/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/column-pinning/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { faker } from '@faker-js/faker' import './index.css' import { columnOrderingFeature, columnPinningFeature, columnVisibilityFeature, createTableHook, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Person } from './makeData' // Create table hook with features const { useAppTable, createAppColumnHelper } = createTableHook({ _features: { columnVisibilityFeature, columnPinningFeature, columnOrderingFeature, }, _rowModels: {}, debugTable: true, debugHeaders: true, debugColumns: true, }) // Create column helper const columnHelper = createAppColumnHelper() // Define columns using columnHelper const columns = columnHelper.columns([ columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) function App() { const [data, setData] = React.useState(() => makeData(5000)) const rerender = () => setData(() => makeData(5000)) const table = useAppTable({ columns, data, }) const randomizeColumns = () => { table.setColumnOrder( faker.helpers.shuffle(table.getAllLeafColumns().map((d) => d.id)), ) } return ( ({ columnVisibility: state.columnVisibility, columnOrder: state.columnOrder, columnPinning: state.columnPinning, })} > {(_state) => (
{table.getAllLeafColumns().map((column) => { return (
) })}

This example using the non-split APIs. Columns are just reordered within 1 table instead of being split into 3 different tables.

{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table .getRowModel() .rows.slice(0, 20) .map((row) => { return ( {row.getVisibleCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( )}
{!header.isPlaceholder && header.column.getCanPin() && (
{header.column.getIsPinned() !== 'left' ? ( ) : null} {header.column.getIsPinned() ? ( ) : null} {header.column.getIsPinned() !== 'right' ? ( ) : null}
)}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-pinning/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/column-pinning/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-pinning/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-pinning-split/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-pinning-split/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-pinning-split/index.html ================================================ Vite App
================================================ FILE: examples/react/column-pinning-split/package.json ================================================ { "name": "tanstack-table-example-column-pinning-split", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-pinning-split/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/column-pinning-split/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { faker } from '@faker-js/faker' import './index.css' import { columnOrderingFeature, columnPinningFeature, columnVisibilityFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { ColumnDef } from '@tanstack/react-table' import type { Person } from './makeData' const _features = tableFeatures({ columnVisibilityFeature, columnPinningFeature, columnOrderingFeature, }) const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = React.useState(() => makeData(5000)) const [columns] = React.useState(() => [...defaultColumns]) const rerender = () => setData(() => makeData(5000)) const table = useTable({ _features, _rowModels: {}, columns, data, debugTable: true, debugHeaders: true, debugColumns: true, }) const randomizeColumns = () => { table.setColumnOrder( faker.helpers.shuffle(table.getAllLeafColumns().map((d) => d.id)), ) } return ( ({ columnVisibility: state.columnVisibility, columnOrder: state.columnOrder, columnPinning: state.columnPinning, })} > {(_state) => (
{table.getAllLeafColumns().map((column) => { return (
) })}

This example takes advantage of the "splitting" APIs. (APIs that have "left, "center", and "right" modifiers)

{table.getLeftHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table .getRowModel() .rows.slice(0, 20) .map((row) => { return ( {row.getLeftVisibleCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( )}
{!header.isPlaceholder && header.column.getCanPin() && (
{header.column.getIsPinned() !== 'left' ? ( ) : null} {header.column.getIsPinned() ? ( ) : null} {header.column.getIsPinned() !== 'right' ? ( ) : null}
)}
{table.getCenterHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table .getRowModel() .rows.slice(0, 20) .map((row) => { return ( {row.getCenterVisibleCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( )}
{!header.isPlaceholder && header.column.getCanPin() && (
{header.column.getIsPinned() !== 'left' ? ( ) : null} {header.column.getIsPinned() ? ( ) : null} {header.column.getIsPinned() !== 'right' ? ( ) : null}
)}
{table.getRightHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table .getRowModel() .rows.slice(0, 20) .map((row) => { return ( {row.getRightVisibleCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( )}
{!header.isPlaceholder && header.column.getCanPin() && (
{header.column.getIsPinned() !== 'left' ? ( ) : null} {header.column.getIsPinned() ? ( ) : null} {header.column.getIsPinned() !== 'right' ? ( ) : null}
)}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-pinning-split/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/column-pinning-split/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-pinning-split/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-pinning-sticky/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-pinning-sticky/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-pinning-sticky/index.html ================================================ Vite App
================================================ FILE: examples/react/column-pinning-sticky/package.json ================================================ { "name": "tanstack-table-example-column-pinning-sticky", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-pinning-sticky/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } .table-container { border: 1px solid lightgray; overflow-x: scroll; width: 100%; max-width: 960px; position: relative; } table { /* box-shadow and borders will not work with positon: sticky otherwise */ border-collapse: separate !important; border-spacing: 0; } th { background-color: lightgray; border-bottom: 1px solid lightgray; font-weight: bold; height: 30px; padding: 2px 4px; position: relative; text-align: center; } td { background-color: white; padding: 2px 4px; } .resizer { background: rgba(0, 0, 0, 0.5); cursor: col-resize; height: 100%; position: absolute; right: 0; top: 0; touch-action: none; user-select: none; width: 5px; } .resizer.isResizing { background: blue; opacity: 1; } ================================================ FILE: examples/react/column-pinning-sticky/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnOrderingFeature, columnPinningFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { faker } from '@faker-js/faker' import { makeData } from './makeData' import type { Column, ColumnDef } from '@tanstack/react-table' import type { CSSProperties } from 'react' import type { Person } from './makeData' import './index.css' const _features = tableFeatures({ columnOrderingFeature, columnPinningFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, }) // These are the important styles to make sticky column pinning work! // Apply styles like this using your CSS strategy of choice with this kind of logic to head cells, data cells, footer cells, etc. // View the index.css file for more needed styles such as border-collapse: separate const getCommonPinningStyles = ( column: Column, ): CSSProperties => { const isPinned = column.getIsPinned() const isLastLeftPinnedColumn = isPinned === 'left' && column.getIsLastColumn('left') const isFirstRightPinnedColumn = isPinned === 'right' && column.getIsFirstColumn('right') return { boxShadow: isLastLeftPinnedColumn ? '-4px 0 4px -4px gray inset' : isFirstRightPinnedColumn ? '4px 0 4px -4px gray inset' : undefined, left: isPinned === 'left' ? `${column.getStart('left')}px` : undefined, right: isPinned === 'right' ? `${column.getAfter('right')}px` : undefined, opacity: isPinned ? 0.95 : 1, position: isPinned ? 'sticky' : 'relative', width: column.getSize(), zIndex: isPinned ? 1 : 0, } } const defaultColumns: Array> = [ { accessorKey: 'firstName', id: 'firstName', header: 'First Name', cell: (info) => info.getValue(), footer: (props) => props.column.id, size: 180, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, size: 180, }, { accessorKey: 'age', id: 'age', header: 'Age', footer: (props) => props.column.id, size: 180, }, { accessorKey: 'visits', id: 'visits', header: 'Visits', footer: (props) => props.column.id, size: 180, }, { accessorKey: 'status', id: 'status', header: 'Status', footer: (props) => props.column.id, size: 180, }, { accessorKey: 'progress', id: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, size: 180, }, ] function App() { const [data, setData] = React.useState(() => makeData(30)) const [columns] = React.useState(() => [...defaultColumns]) const rerender = () => setData(() => makeData(30)) const table = useTable( { _features, _rowModels: {}, columns, data, debugTable: true, debugHeaders: true, debugColumns: true, columnResizeMode: 'onChange', }, (state) => state, ) const randomizeColumns = () => { table.setColumnOrder( faker.helpers.shuffle(table.getAllLeafColumns().map((d) => d.id)), ) } return ( ({ columnVisibility: state.columnVisibility, columnOrder: state.columnOrder, columnPinning: state.columnPinning, columnSizing: state.columnSizing, columnResizing: state.columnResizing, })} > {(_topLevelState) => (
{table.getAllLeafColumns().map((column) => { return (
) })}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { const { column } = header return ( ({ isResizingColumn: state.columnResizing.isResizingColumn === column.id, columnSize: state.columnSizing[column.id], })} > {() => ( )} ) })} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => { const { column } = cell return ( ({ isResizingColumn: state.columnResizing.isResizingColumn === column.id, columnSize: state.columnSizing[column.id], })} > {() => ( )} ) })} ))}
{header.isPlaceholder ? null : ( <> {' '} )} {/* Demo getIndex behavior */} {column.getIndex( column.getIsPinned() || 'center', )}
{!header.isPlaceholder && header.column.getCanPin() && (
{header.column.getIsPinned() !== 'left' ? ( ) : null} {header.column.getIsPinned() ? ( ) : null} {header.column.getIsPinned() !== 'right' ? ( ) : null}
)}
header.column.resetSize()} onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={`resizer ${ header.column.getIsResizing() ? 'isResizing' : '' }`} />
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-pinning-sticky/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/column-pinning-sticky/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-pinning-sticky/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-resizing/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-resizing/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-resizing/index.html ================================================ Vite App
================================================ FILE: examples/react/column-resizing/package.json ================================================ { "name": "tanstack-table-example-column-resizing", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-resizing/src/index.css ================================================ * { box-sizing: border-box; } html { font-family: sans-serif; font-size: 14px; } table, .divTable { border: 1px solid lightgray; width: fit-content; } .tr { display: flex; } tr, .tr { width: fit-content; height: 30px; } th, .th, td, .td { box-shadow: inset 0 0 0 1px lightgray; padding: 0.25rem; } th, .th { padding: 2px 4px; position: relative; font-weight: bold; text-align: center; height: 30px; } td, .td { height: 30px; } .resizer { position: absolute; top: 0; height: 100%; width: 5px; background: rgba(0, 0, 0, 0.5); cursor: col-resize; user-select: none; touch-action: none; } .resizer.ltr { right: 0; } .resizer.rtl { left: 0; } .resizer.isResizing { background: blue; opacity: 1; } @media (hover: hover) { .resizer { opacity: 0; } *:hover > .resizer { opacity: 1; } } ================================================ FILE: examples/react/column-resizing/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnResizingFeature, columnSizingFeature, createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' import type { ColumnResizeDirection, ColumnResizeMode, } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ columnResizingFeature, columnSizingFeature }) type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) function App() { const [data] = React.useState(() => [...defaultData]) const [columnResizeMode, setColumnResizeMode] = React.useState('onChange') const [columnResizeDirection, setColumnResizeDirection] = React.useState('ltr') const rerender = React.useReducer(() => ({}), {})[1] const table = useTable( { _features, _rowModels: {}, columns, data, columnResizeMode, columnResizeDirection, debugTable: true, debugHeaders: true, debugColumns: true, }, (state) => state, ) return (
{''}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
header.column.resetSize()} onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={`resizer ${ table.options.columnResizeDirection } ${header.column.getIsResizing() ? 'isResizing' : ''}`} style={{ transform: columnResizeMode === 'onEnd' && header.column.getIsResizing() ? `translateX(${ (table.options.columnResizeDirection === 'rtl' ? -1 : 1) * (table.store.state.columnResizing .deltaOffset ?? 0) }px)` : '', }} />
{'
(relative)'}
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder ? null : ( )}
header.column.resetSize()} onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={`resizer ${ table.options.columnResizeDirection } ${header.column.getIsResizing() ? 'isResizing' : ''}`} style={{ transform: columnResizeMode === 'onEnd' && header.column.getIsResizing() ? `translateX(${ (table.options.columnResizeDirection === 'rtl' ? -1 : 1) * (table.store.state.columnResizing .deltaOffset ?? 0) }px)` : '', }} />
))}
))}
{table.getRowModel().rows.map((row) => (
{row.getAllCells().map((cell) => (
))}
))}
{'
(absolute positioning)'}
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder ? null : ( )}
header.column.resetSize()} onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={`resizer ${ table.options.columnResizeDirection } ${header.column.getIsResizing() ? 'isResizing' : ''}`} style={{ transform: columnResizeMode === 'onEnd' && header.column.getIsResizing() ? `translateX(${ (table.options.columnResizeDirection === 'rtl' ? -1 : 1) * (table.store.state.columnResizing .deltaOffset ?? 0) }px)` : '', }} />
))}
))}
{table.getRowModel().rows.map((row) => (
{row.getAllCells().map((cell) => (
))}
))}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-resizing/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-resizing/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-resizing-performant/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-resizing-performant/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-resizing-performant/index.html ================================================ Vite App
================================================ FILE: examples/react/column-resizing-performant/package.json ================================================ { "name": "tanstack-table-example-column-resizing-performant", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-resizing-performant/src/index.css ================================================ * { box-sizing: border-box; } html { font-family: sans-serif; font-size: 14px; } table, .divTable { border: 1px solid lightgray; width: fit-content; } .tr { display: flex; } tr, .tr { width: fit-content; height: 30px; } th, .th, td, .td { box-shadow: inset 0 0 0 1px lightgray; padding: 0.25rem; } th, .th { padding: 2px 4px; position: relative; font-weight: bold; text-align: center; height: 30px; } td, .td { height: 30px; } .resizer { position: absolute; top: 0; height: 100%; right: 0; width: 5px; background: rgba(0, 0, 0, 0.5); cursor: col-resize; user-select: none; touch-action: none; } .resizer.isResizing { background: blue; opacity: 1; } @media (hover: hover) { .resizer { opacity: 0; } *:hover > .resizer { opacity: 1; } } ================================================ FILE: examples/react/column-resizing-performant/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnResizingFeature, columnSizingFeature, createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Table } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ columnSizingFeature, columnResizingFeature }) type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]) function App() { const [data, _setData] = React.useState(() => makeData(200)) const rerender = React.useReducer(() => ({}), {})[1] const table = useTable( { _features, _rowModels: {}, columns, data, defaultColumn: { minSize: 60, maxSize: 800, }, columnResizeMode: 'onChange', debugTable: true, debugHeaders: true, debugColumns: true, }, (state) => ({ columnSizing: state.columnSizing, columnResizing: state.columnResizing, }), ) /** * Instead of calling `column.getSize()` on every render for every header * and especially every data cell (very expensive), * we will calculate all column sizes at once at the root table level in a useMemo * and pass the column sizes down as CSS variables to the element. */ const columnSizeVars = React.useMemo(() => { const headers = table.getFlatHeaders() const colSizes: { [key: string]: number } = {} for (const header of headers) { colSizes[`--header-${header.id}-size`] = header.getSize() colSizes[`--col-${header.column.id}-size`] = header.column.getSize() } return colSizes }, [table.state.columnResizing, table.state.columnSizing]) // demo purposes const [enableMemo, setEnableMemo] = React.useState(true) return (
This example has artificially slow cell renders to simulate complex usage
state}> {(state) => (
            {JSON.stringify(state, null, 2)}
          
)}
({data.length} rows)
{/* Here in the
equivalent element (surrounds all table head and data cells), we will define our CSS variables for column sizes */}
element width: table.getTotalSize(), }} >
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder ? null : ( )}
header.column.resetSize()} onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={`resizer ${ header.column.getIsResizing() ? 'isResizing' : '' }`} />
))}
))}
{/* When resizing any column we will render this special memoized version of our table body */} {table.store.state.columnResizing.isResizingColumn && enableMemo ? ( ) : ( )}
) } // un-memoized normal table body component - see memoized version below function TableBody({ table }: { table: Table }) { return (
{table.getRowModel().rows.map((row) => (
{row.getAllCells().map((cell) => { // simulate expensive render for (const _ of Array(10000)) { Math.random() } return (
{cell.renderValue()}
) })}
))}
) } // special memoized wrapper for our table body that we will use during column resizing export const MemoizedTableBody = React.memo( TableBody, (prev, next) => prev.table.options.data === next.table.options.data, ) as typeof TableBody const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-resizing-performant/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/column-resizing-performant/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-resizing-performant/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-sizing/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-sizing/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-sizing/index.html ================================================ Vite App
================================================ FILE: examples/react/column-sizing/package.json ================================================ { "name": "tanstack-table-example-column-sizing", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-sizing/src/index.css ================================================ * { box-sizing: border-box; } html { font-family: sans-serif; font-size: 14px; } table, .divTable { border: 1px solid lightgray; width: fit-content; } .tr { display: flex; } tr, .tr { width: fit-content; height: 30px; } th, .th, td, .td { box-shadow: inset 0 0 0 1px lightgray; padding: 0.25rem; } th, .th { padding: 2px 4px; position: relative; font-weight: bold; text-align: center; height: 30px; } td, .td { height: 30px; } .resizer { position: absolute; top: 0; height: 100%; width: 5px; background: rgba(0, 0, 0, 0.5); cursor: col-resize; user-select: none; touch-action: none; } .resizer.ltr { right: 0; } .resizer.rtl { left: 0; } .resizer.isResizing { background: blue; opacity: 1; } @media (hover: hover) { .resizer { opacity: 0; } *:hover > .resizer { opacity: 1; } } ================================================ FILE: examples/react/column-sizing/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnSizingFeature, createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ columnSizingFeature }) type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const columnHelper = createColumnHelper() // This is not the Column Resizing Example, this is a simplified version that just sets static column sizes function App() { const [data] = React.useState(() => [...defaultData]) const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, size: 120, // initial size }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, size: 120, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, size: 100, }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, size: 80, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, size: 200, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, size: 200, }), ]), [], ) const rerender = React.useReducer(() => ({}), {})[1] const table = useTable( { _features, _rowModels: {}, columns, data, debugTable: true, debugHeaders: true, debugColumns: true, }, (state) => state, ) return (
{'Initial Column Sizes'}

{table.getAllColumns().map((column) => (
))}
{'
'}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{'
(relative)'}
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder ? null : ( )}
))}
))}
{table.getRowModel().rows.map((row) => (
{row.getAllCells().map((cell) => (
))}
))}
{'
(absolute positioning)'}
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder ? null : ( )}
))}
))}
{table.getRowModel().rows.map((row) => (
{row.getAllCells().map((cell) => (
))}
))}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-sizing/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-sizing/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/column-visibility/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/column-visibility/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/column-visibility/index.html ================================================ Vite App
================================================ FILE: examples/react/column-visibility/package.json ================================================ { "name": "tanstack-table-example-column-visibility", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/column-visibility/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/column-visibility/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnVisibilityFeature, createColumnHelper, tableFeatures, useTable, } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ columnVisibilityFeature }) type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.group({ header: 'Name', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), ]), }), columnHelper.group({ header: 'Info', footer: (props) => props.column.id, columns: columnHelper.columns([ columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.group({ header: 'More Info', columns: columnHelper.columns([ columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), }), ]), }), ]) function App() { const [data, _setData] = React.useState(() => [...defaultData]) const rerender = React.useReducer(() => ({}), {})[1] const table = useTable({ _features, _rowModels: {}, columns, data, debugTable: true, debugHeaders: true, debugColumns: true, }) return ( ({ columnVisibility: state.columnVisibility, })} > {(_state) => (
{table.getAllLeafColumns().map((column) => { return (
) })}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((header) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
{header.isPlaceholder ? null : ( )}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/column-visibility/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/column-visibility/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/composable-tables/README.md ================================================ # Large Table Example This example demonstrates the `createTableHook` composition pattern for TanStack Table v9, similar to TanStack Form's `createFormHook`. ## What This Demonstrates ### Single Source of Truth (`createTableHook`) The `hooks/table.ts` file sets up everything in one place: - **Features** - `_features` defines which table features are enabled - **Row Models** - Pre-configured sorted, filtered, and paginated row models - **Default Options** - Any table options can be set as defaults (except columns/data/store/state/initialState) - **Contexts** - Created internally, with `TFeatures` already baked in - **Context Hooks** - `useTableContext`, `useCellContext`, `useHeaderContext` - all typed! - **Pre-bound Components** - Table, cell, and header components - **Column Helper** - `createAppColumnHelper` pre-bound to your features ### No Generics Needed in Components Because `TFeatures` is baked into the context hooks at creation time, your custom components don't need type annotations: ```tsx // components/table-components.tsx function PaginationControls() { const table = useTableContext() // TFeatures already known! return s.pagination}>... } ``` ### Simplified Column Helper Since `TFeatures` is configured once in `createTableHook`, the `createAppColumnHelper` only needs `TData`: ```tsx // TFeatures already bound - only need TData! const columnHelper = createAppColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name' }), columnHelper.accessor('age', { header: 'Age' }), ]) ``` ### Simplified useAppTable Since `_features`, `_rowModels`, and default options are configured once in `createTableHook`, `useAppTable` only needs `columns` and `data`: ```tsx const table = useAppTable({ columns, data, // TData inferred from this }) ``` ### Pre-bound Components **Table Components** (accessible via `table.ComponentName`): - `PaginationControls` - Full pagination UI - `RowCount` - Row count display - `TableToolbar` - Header with title and actions **Cell Components** (accessible via `cell.ComponentName` in `AppCell`): - `TextCell` - Generic text renderer - `NumberCell` - Formatted number renderer - `StatusCell` - Status badge - `ProgressCell` - Progress bar - `RowActionsCell` - Row action buttons (view, edit, delete) **Header Components** (accessible via `header.ComponentName` in `AppHeader`): - `SortIndicator` - Sort direction icon - `ColumnFilter` - Filter input **Footer Components** (accessible via `footer.ComponentName` in `AppFooter`): - `FooterColumnId` - Display the column ID - `FooterSum` - Sum aggregation for numeric columns ### App Wrapper Components The `useAppTable` hook returns these wrapper components: - `AppTable` - Root wrapper providing table context - `AppCell` - Cell wrapper with pre-bound cellComponents - `AppHeader` - Header wrapper with pre-bound headerComponents - `AppFooter` - Footer wrapper with pre-bound headerComponents ### Subscribe Integration All App wrapper components support an optional `selector` prop for optimized re-renders: ```tsx // Without selector - children is a function receiving the entity {(cell) => } // With selector - children receives both entity and selected state state.columnFilters}> {(cell, filters) => {filters.length} filters} // AppTable with selector state.pagination}> {(pagination) =>
Page {pagination.pageIndex + 1}
}
``` This wraps the children in a `Subscribe` component for fine-grained reactivity. ## File Structure ``` src/ ├── hooks/ │ └── table.ts # createTableHook setup with features, row models, and components ├── components/ │ ├── cell-components.tsx # TextCell, NumberCell, StatusCell, ProgressCell, RowActionsCell │ ├── header-components.tsx # SortIndicator, ColumnFilter │ └── table-components.tsx # PaginationControls, RowCount, TableToolbar ├── main.tsx # App entry point with table component ├── makeData.ts # Mock data generator └── index.css # Styles ``` ## Running the Example ```bash cd examples/react/large-table pnpm install pnpm dev ``` ================================================ FILE: examples/react/composable-tables/index.html ================================================ TanStack Table - Large Table Example with createTableHook
================================================ FILE: examples/react/composable-tables/package.json ================================================ { "name": "tanstack-table-example-composable-tables", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-store": "^0.9.2", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/composable-tables/src/components/cell-components.tsx ================================================ /** * Cell-level components that use useCellContext * * These components can be used via the pre-bound cellComponents * in AppCell children, e.g., */ import { useCellContext } from '../hooks/table' /** * Generic text cell renderer */ export function TextCell() { const cell = useCellContext() return {cell.getValue()} } /** * Number cell with locale formatting */ export function NumberCell() { const cell = useCellContext() return {cell.getValue().toLocaleString()} } /** * Status badge cell for status column */ export function StatusCell() { const cell = useCellContext<'relationship' | 'complicated' | 'single'>() const status = cell.getValue() return {status} } /** * Progress bar cell */ export function ProgressCell() { const cell = useCellContext() const progress = cell.getValue() return (
) } /** * Row actions cell - actions for the current row */ export function RowActionsCell() { const cell = useCellContext() const row = cell.row return (
) } /** * Price cell with currency formatting */ export function PriceCell() { const cell = useCellContext() return ( $ {cell.getValue().toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, })} ) } /** * Category badge cell */ export function CategoryCell() { const cell = useCellContext<'electronics' | 'clothing' | 'food' | 'books'>() const category = cell.getValue() return {category} } ================================================ FILE: examples/react/composable-tables/src/components/header-components.tsx ================================================ /** * Header-level components that use useHeaderContext * * These components can be used via the pre-bound headerComponents * in AppHeader children, e.g., */ import { useHeaderContext } from '../hooks/table' /** * Sort indicator showing current sort direction */ export function SortIndicator() { const header = useHeaderContext() const sorted = header.column.getIsSorted() if (!sorted) return null return ( {sorted === 'asc' ? '🔼' : '🔽'} ) } /** * Column filter input */ export function ColumnFilter() { const header = useHeaderContext() if (!header.column.getCanFilter()) return null const columnFilterValue = header.column.getFilterValue() return (
e.stopPropagation()}> header.column.setFilterValue(e.target.value)} placeholder={`Filter ${header.column.id}...`} />
) } /** * Footer showing the column ID */ export function FooterColumnId() { const header = useHeaderContext() return {header.column.id} } /** * Footer showing a summary/aggregation for numeric columns */ export function FooterSum() { const header = useHeaderContext() const table = header.getContext().table const rows = table.getFilteredRowModel().rows // Calculate sum for numeric columns const sum = rows.reduce((acc, row) => { const value = row.getValue(header.column.id) return acc + (typeof value === 'number' ? value : 0) }, 0) return ( {sum > 0 ? sum.toLocaleString() : '—'} ) } ================================================ FILE: examples/react/composable-tables/src/components/table-components.tsx ================================================ /** * Table-level components that use useTableContext * * These components can be used via the pre-bound tableComponents * directly on the table object, e.g., */ import { useTableContext } from '../hooks/table' /** * Pagination controls for the table */ export function PaginationControls() { const table = useTableContext() return ( state.pagination}> {(pagination) => (
Page{' '} {pagination.pageIndex + 1} of{' '} {table.getPageCount().toLocaleString()} | Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} />
)}
) } /** * Row count display */ export function RowCount() { const table = useTableContext() return (
Showing {table.getRowModel().rows.length.toLocaleString()} of{' '} {table.getRowCount().toLocaleString()} rows
) } /** * Table toolbar with title and actions */ export function TableToolbar({ title, onRefresh, }: { title: string onRefresh?: () => void }) { const table = useTableContext() return (

{title}

{onRefresh && }
) } ================================================ FILE: examples/react/composable-tables/src/hooks/table.ts ================================================ /** * Custom table hook setup using createTableHook * * This file creates a custom useAppTable hook with pre-bound components. * Features, row models, and default options are defined once here and shared across all tables. * Context hooks and a pre-bound createAppColumnHelper are also exported. */ import { columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, createTableHook, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/react-table' // Import table-level components import { PaginationControls, RowCount, TableToolbar, } from '../components/table-components' // Import cell-level components import { CategoryCell, NumberCell, PriceCell, ProgressCell, RowActionsCell, StatusCell, TextCell, } from '../components/cell-components' // Import header/footer-level components (both use useHeaderContext) import { ColumnFilter, FooterColumnId, FooterSum, SortIndicator, } from '../components/header-components' /** * Create the custom table hook with all pre-bound components. * This exports: * - createAppColumnHelper: Create column definitions with TFeatures already bound * - useAppTable: Hook for creating tables with TFeatures baked in * - useTableContext: Access table instance in tableComponents * - useCellContext: Access cell instance in cellComponents * - useHeaderContext: Access header instance in headerComponents */ export const { createAppColumnHelper, useAppTable, useTableContext, useCellContext, useHeaderContext, } = createTableHook({ // Features are set once here and shared across all tables _features: tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }), // Row models are set once here _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, // set any default table options here too getRowId: (row) => row.id, // Register table-level components (accessible via table.ComponentName) tableComponents: { PaginationControls, RowCount, TableToolbar, }, // Register cell-level components (accessible via cell.ComponentName in AppCell) cellComponents: { TextCell, NumberCell, StatusCell, ProgressCell, RowActionsCell, PriceCell, CategoryCell, }, // Register header/footer-level components (accessible via header.ComponentName in AppHeader/AppFooter) headerComponents: { SortIndicator, ColumnFilter, FooterColumnId, FooterSum, }, }) ================================================ FILE: examples/react/composable-tables/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; border-collapse: collapse; width: 100%; } tbody { border-bottom: 1px solid lightgray; } th, td { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 8px 12px; text-align: left; } th { background-color: #f5f5f5; font-weight: 600; } tfoot { color: gray; } tfoot th { font-weight: normal; } .table-container { padding: 16px; max-width: 1200px; margin: 0 auto; } .pagination { display: flex; align-items: center; gap: 8px; margin-top: 16px; flex-wrap: wrap; } .pagination button { border: 1px solid #ccc; border-radius: 4px; padding: 4px 8px; cursor: pointer; background: white; } .pagination button:disabled { opacity: 0.5; cursor: not-allowed; } .pagination input { border: 1px solid #ccc; border-radius: 4px; padding: 4px; width: 64px; } .pagination select { border: 1px solid #ccc; border-radius: 4px; padding: 4px; } .sort-indicator { margin-left: 4px; } .column-filter { margin-top: 4px; } .column-filter input { border: 1px solid #ccc; border-radius: 4px; padding: 4px; width: 100%; font-size: 12px; } .sortable-header { cursor: pointer; user-select: none; } .sortable-header:hover { background-color: #e8e8e8; } .row-actions { display: flex; gap: 4px; } .row-actions button { border: 1px solid #ccc; border-radius: 4px; padding: 2px 8px; cursor: pointer; background: white; font-size: 12px; } .row-actions button:hover { background-color: #f0f0f0; } .status-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; } .status-badge.relationship { background-color: #d4edda; color: #155724; } .status-badge.complicated { background-color: #fff3cd; color: #856404; } .status-badge.single { background-color: #cce5ff; color: #004085; } .progress-bar { width: 100%; height: 8px; background-color: #e9ecef; border-radius: 4px; overflow: hidden; } .progress-bar-fill { height: 100%; background-color: #007bff; transition: width 0.2s; } .table-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 8px; } .table-toolbar h2 { margin: 0; } .table-toolbar button { border: 1px solid #ccc; border-radius: 4px; padding: 8px 16px; cursor: pointer; background: white; } .table-toolbar button:hover { background-color: #f0f0f0; } .row-count { color: #666; font-size: 14px; margin-top: 8px; } .app { padding: 16px; } .app h1 { text-align: center; margin-bottom: 8px; } .description { text-align: center; color: #666; margin-bottom: 32px; } .description code { background-color: #f5f5f5; padding: 2px 6px; border-radius: 4px; font-size: 13px; } .table-divider { height: 48px; border-bottom: 1px solid #e0e0e0; margin: 32px auto; max-width: 1200px; } .category-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; text-transform: capitalize; } .category-badge.electronics { background-color: #e3f2fd; color: #1565c0; } .category-badge.clothing { background-color: #fce4ec; color: #c2185b; } .category-badge.food { background-color: #e8f5e9; color: #2e7d32; } .category-badge.books { background-color: #fff8e1; color: #f57c00; } .price { font-weight: 600; color: #2e7d32; } ================================================ FILE: examples/react/composable-tables/src/main.tsx ================================================ import * as React from 'react' import { useCallback, useMemo, useState } from 'react' import ReactDOM from 'react-dom/client' import { createAppColumnHelper, useAppTable } from './hooks/table' import { makeData, makeProductData } from './makeData' import type { Person, Product } from './makeData' import './index.css' // Import cell components directly - they use useCellContext internally // Create column helpers with TFeatures already bound - only need TData! const personColumnHelper = createAppColumnHelper() const productColumnHelper = createAppColumnHelper() // Users Table Component - Original implementation function UsersTable() { // Data state const [data, setData] = useState(() => makeData(1000)) // Refresh data callback const refreshData = useCallback(() => { setData(makeData(1000)) }, []) // Define columns using the column helper const columns = useMemo( () => // NOTE: You must use `createAppColumnHelper` instead of `createColumnHelper` when using pre-bound components like personColumnHelper.columns([ personColumnHelper.accessor('firstName', { header: 'First Name', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('lastName', { header: 'Last Name', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('age', { header: 'Age', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('visits', { header: 'Visits', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('progress', { header: 'Progress', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.display({ id: 'actions', header: 'Actions', cell: ({ cell }) => , }), ]), [], ) // Create the table - _features and _rowModels are already configured! const table = useAppTable( { columns, data, debugTable: true, // more table options }, // (state) => state, // alternatively, subscribe to the entire state instead of using table.Subscribe or selectors down below ) return ( // Main selector on AppTable - selects all needed state in one place ({ // subscribe to specific states for re-rendering if you are optimizing for maximum performance pagination: state.pagination, sorting: state.sorting, columnFilters: state.columnFilters, })} > {({ sorting, columnFilters }) => (
{/* Table toolbar using pre-bound component */} {/* Table element */} {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((h) => ( {(header) => ( )} ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((c) => ( {(cell) => ( )} ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((f) => ( {(footer) => { const columnId = footer.column.id const hasFilter = columnFilters.some( (cf) => cf.id === columnId, ) return ( ) }} ))} ))}
{header.isPlaceholder ? null : ( <> {/* Show sort order number when multiple columns sorted */} {sorting.length > 1 && sorting.findIndex( (s) => s.id === header.column.id, ) > -1 && ( {sorting.findIndex( (s) => s.id === header.column.id, ) + 1} )} )}
{/* Cell components are pre-bound via AppCell */}
{footer.isPlaceholder ? null : ( <> {/* Use FooterSum for numeric columns, FooterColumnId for others */} {columnId === 'age' || columnId === 'visits' || columnId === 'progress' ? ( <> {hasFilter && ( {' '} (filtered) )} ) : columnId === 'actions' ? null : ( <> {hasFilter && ( {' '} ✓ )} )} )}
{/* Pagination using pre-bound component */} {/* Row count using pre-bound component */}
)}
) } // Products Table Component - New implementation using same hook and components function ProductsTable() { // Data state const [data, setData] = useState(() => makeProductData(500)) // Refresh data callback const refreshData = useCallback(() => { setData(makeProductData(500)) }, []) // Define columns using the column helper - different structure than Users table const columns = useMemo( () => productColumnHelper.columns([ productColumnHelper.accessor('name', { header: 'Product Name', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('category', { header: 'Category', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('price', { header: 'Price', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('stock', { header: 'In Stock', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('rating', { header: 'Rating', footer: (props) => props.column.id, cell: ({ cell }) => , }), ]), [], ) // Create the table using the same useAppTable hook const table = useAppTable({ columns, data, getRowId: (row) => row.id, }) return ( ({ pagination: state.pagination, sorting: state.sorting, columnFilters: state.columnFilters, })} > {({ sorting, columnFilters }) => (
{/* Table toolbar using the same pre-bound component */} {/* Table element */} {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((h) => ( {(header) => ( )} ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((c) => ( {(cell) => ( )} ))} ))} {table.getFooterGroups().map((footerGroup) => ( {footerGroup.headers.map((f) => ( {(footer) => { const columnId = footer.column.id const hasFilter = columnFilters.some( (cf) => cf.id === columnId, ) return ( ) }} ))} ))}
{header.isPlaceholder ? null : ( <> {sorting.length > 1 && sorting.findIndex( (s) => s.id === header.column.id, ) > -1 && ( {sorting.findIndex( (s) => s.id === header.column.id, ) + 1} )} )}
{/* Cell components are pre-bound via AppCell */}
{footer.isPlaceholder ? null : ( <> {/* Use FooterSum for numeric columns, FooterColumnId for others */} {columnId === 'price' || columnId === 'stock' || columnId === 'rating' ? ( <> {hasFilter && ( {' '} (filtered) )} ) : ( <> {hasFilter && ( {' '} ✓ )} )} )}
{/* Pagination using the same pre-bound component */} {/* Row count using the same pre-bound component */}
)}
) } function App() { return (

Composable Tables Example

Both tables below use the same useAppTable hook and shareable components, but with different data types and column configurations.

{/* Original Users Table */}
{/* New Products Table */}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/composable-tables/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } export type Product = { id: string name: string category: 'electronics' | 'clothing' | 'food' | 'books' price: number stock: number rating: number } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } const newProduct = (): Product => { return { id: faker.string.uuid(), name: faker.commerce.productName(), category: faker.helpers.shuffle([ 'electronics', 'clothing', 'food', 'books', ])[0], price: parseFloat(faker.commerce.price({ min: 5, max: 500 })), stock: faker.number.int({ min: 0, max: 200 }), rating: faker.number.int({ min: 0, max: 100 }), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } export function makeProductData(count: number): Array { return range(count).map(() => newProduct()) } ================================================ FILE: examples/react/composable-tables/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/composable-tables/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], }) ================================================ FILE: examples/react/custom-plugin/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/custom-plugin/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/custom-plugin/index.html ================================================ Vite App
================================================ FILE: examples/react/custom-plugin/package.json ================================================ { "name": "tanstack-table-example-custom-plugin", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/custom-plugin/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } tr { border-bottom: 1px solid lightgray; } button:disabled { opacity: 0.5; } ================================================ FILE: examples/react/custom-plugin/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnFilteringFeature, createColumnHelper, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, functionalUpdate, makeStateUpdater, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Column, OnChangeFn, ReactTable, TableFeature, Updater, } from '@tanstack/react-table' import type { Person } from './makeData' // TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features // define types for our new feature's custom state export type DensityState = 'sm' | 'md' | 'lg' export interface TableState_Density { density: DensityState } // 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 export interface Table_Density { setDensity: (updater: Updater) => void toggleDensity: (value?: DensityState) => void } interface DensityPluginConstructors { Table: Table_Density TableOptions: TableOptions_Density TableState: TableState_Density } // Here is all of the actual javascript code for our new feature export const densityPlugin: TableFeature = { // define the new feature's initial state getInitialState: (initialState) => { return { density: 'md', ...initialState, // must come last } }, // define the new feature's default options getDefaultTableOptions: (table) => { return { enableDensity: true, onDensityChange: makeStateUpdater('density', table), } }, // if you need to add a default column definition... // getDefaultColumnDef: () => {}, // 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.toggleDensity = (value) => { table.setDensity?.((old) => { if (value) return value return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options }) } }, // if you need to add row instance APIs... // constructRowAPIs: (row) => {}, // if you need to add cell instance APIs... // constructCellAPIs: (cell) => {}, // if you need to add column instance APIs... // constructColumnAPIs: (column) => {}, // if you need to add header instance APIs... // constructHeaderAPIs: (header) => {}, } // end of custom feature code // app code const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, densityPlugin, // pass in our plugin just like any other stock feature }) const columnHelper = createColumnHelper() function App() { const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), [], ) const [data, _setData] = React.useState(() => makeData(1000)) const [density, setDensity] = React.useState('md') const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, 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 (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{{ 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
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } function Filter({ column, table, }: { column: Column table: ReactTable }) { const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) const columnFilterValue = column.getFilterValue() return typeof firstValue === 'number' ? (
column.setFilterValue((old: [number, number]) => [ e.target.value, old[1], ]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number]) => [ old[0], e.target.value, ]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : ( column.setFilterValue(e.target.value)} placeholder={`Search...`} className="w-36 border shadow rounded" /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/custom-plugin/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/custom-plugin/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/custom-plugin/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/expanding/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/expanding/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/expanding/index.html ================================================ Vite App
================================================ FILE: examples/react/expanding/package.json ================================================ { "name": "tanstack-table-example-expanding", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/expanding/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/expanding/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnFilteringFeature, createColumnHelper, createExpandedRowModel, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, rowExpandingFeature, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { HTMLProps } from 'react' import type { Person } from './makeData' import type { Column, Table } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ columnFilteringFeature, rowExpandingFeature, rowPaginationFeature, rowSortingFeature, rowSelectionFeature, }) const columnHelper = createColumnHelper() function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { header: ({ table }) => ( <> {' '} {' '} First Name ), cell: ({ row, getValue }) => (
{' '} {row.getCanExpand() ? ( ) : ( '🔵' )}{' '} {getValue()}
), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, filterFn: 'between', }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), [], ) const [data, setData] = React.useState(() => makeData(100, 5, 3)) const refreshData = () => setData(() => makeData(100, 5, 3)) const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel(), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, columns, data, getSubRows: (row) => row.subRows, // filterFromLeafRows: true, // maxLeafRowFilterDepth: 0, debugTable: true, }) return ( ({ expanded: state.expanded, pagination: state.pagination, })} > {(state) => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : (
{header.column.getCanFilter() ? (
) : null}
)}
Page
{state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{table.getRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } function Filter({ column, table, }: { column: Column table: Table }) { const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) const columnFilterValue = column.getFilterValue() return typeof firstValue === 'number' ? (
column.setFilterValue((old: [number, number] | undefined) => [ e.target.value, old?.[1], ]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number] | undefined) => [ old?.[0], e.target.value, ]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : ( column.setFilterValue(e.target.value)} placeholder={`Search...`} className="w-36 border shadow rounded" /> ) } function IndeterminateCheckbox({ indeterminate, className = '', ...rest }: { indeterminate?: boolean } & HTMLProps) { const ref = React.useRef(null!) React.useEffect(() => { if (typeof indeterminate === 'boolean') { ref.current.indeterminate = !rest.checked && indeterminate } }, [ref, indeterminate]) return ( ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/expanding/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/expanding/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/expanding/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/filters/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/filters/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/filters/index.html ================================================ Vite App
================================================ FILE: examples/react/filters/package.json ================================================ { "name": "tanstack-table-example-filters", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/match-sorter-utils": "^9.0.0-alpha.4", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/filters/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/filters/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnFilteringFeature, createColumnHelper, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { CellData, Column, RowData, TableFeatures, } from '@tanstack/react-table' import type { Person } from './makeData' declare module '@tanstack/react-table' { // allows us to define custom properties for our columns interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { filterVariant?: 'text' | 'range' | 'select' } } const _features = tableFeatures({ columnFilteringFeature, rowSortingFeature, rowPaginationFeature, }) const columnHelper = createColumnHelper() function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }), columnHelper.accessor((row) => `${row.firstName} ${row.lastName}`, { id: 'fullName', header: 'Full Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: () => 'Age', meta: { filterVariant: 'range', }, }), columnHelper.accessor('visits', { header: () => Visits, meta: { filterVariant: 'range', }, }), columnHelper.accessor('status', { header: 'Status', meta: { filterVariant: 'select', }, }), columnHelper.accessor('progress', { header: 'Profile Progress', meta: { filterVariant: 'range', }, }), ]), [], ) const [data, setData] = React.useState>(() => makeData(5_000)) const refreshData = () => setData((_old) => makeData(50_000)) // stress test const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), // client side filtering sortedRowModel: createSortedRowModel(sortFns), // client side sorting paginatedRowModel: createPaginatedRowModel(), }, columns, data, debugTable: true, debugColumns: true, }) return ( ({ columnFilters: state.columnFilters, pagination: state.pagination, sorting: state.sorting, })} > {(state) => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( <>
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
{header.column.getCanFilter() ? (
) : null} )}
Page
{state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{table.getPrePaginatedRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } function Filter({ column, }: { column: Column }) { const columnFilterValue = column.getFilterValue() const { filterVariant } = column.columnDef.meta ?? {} return filterVariant === 'range' ? (
{/* See faceted column filters example for min max values functionality */} column.setFilterValue((old: [number, number] | undefined) => [ value, old?.[1], ]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number] | undefined) => [ old?.[0], value, ]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : filterVariant === 'select' ? ( ) : ( column.setFilterValue(value)} placeholder={`Search...`} type="text" value={(columnFilterValue ?? '') as string} /> // See faceted column filters example for datalist search suggestions ) } // A typical debounced input react component function DebouncedInput({ value: initialValue, onChange, debounce = 500, ...props }: { value: string | number onChange: (value: string | number) => void debounce?: number } & Omit, 'onChange'>) { const [value, setValue] = React.useState(initialValue) React.useEffect(() => { setValue(initialValue) }, [initialValue]) React.useEffect(() => { const timeout = setTimeout(() => { onChange(value) }, debounce) return () => clearTimeout(timeout) }, [value]) return ( setValue(e.target.value)} /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/filters/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/filters/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noErrorTruncation": true }, "include": ["src"] } ================================================ FILE: examples/react/filters/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/filters-faceted/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/filters-faceted/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/filters-faceted/index.html ================================================ Vite App
================================================ FILE: examples/react/filters-faceted/package.json ================================================ { "name": "tanstack-table-example-filters-faceted", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/match-sorter-utils": "^9.0.0-alpha.4", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/filters-faceted/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/filters-faceted/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnFacetingFeature, columnFilteringFeature, createColumnHelper, createFacetedMinMaxValues, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { CellData, Column, RowData, TableFeatures, } from '@tanstack/react-table' import type { Person } from './makeData' const _features = tableFeatures({ columnFacetingFeature, columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() declare module '@tanstack/react-table' { // allows us to define custom properties for our columns interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { filterVariant?: 'text' | 'range' | 'select' } } function App() { const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }), columnHelper.accessor('age', { header: () => 'Age', meta: { filterVariant: 'range', }, }), columnHelper.accessor('visits', { header: () => Visits, meta: { filterVariant: 'range', }, }), columnHelper.accessor('status', { header: 'Status', meta: { filterVariant: 'select', }, }), columnHelper.accessor('progress', { header: 'Profile Progress', meta: { filterVariant: 'range', }, }), ]), [], ) const [data, setData] = React.useState>(() => makeData(5_000)) const refreshData = () => setData((_old) => makeData(100_000)) // stress test const rerender = React.useReducer(() => ({}), {})[1] const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), // client-side filtering paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), facetedRowModel: createFacetedRowModel(), // client-side faceting facetedMinMaxValues: createFacetedMinMaxValues(), // generate min/max values for range filter facetedUniqueValues: createFacetedUniqueValues(), // generate unique values for select filter/autocomplete }, columns, data, debugTable: true, debugHeaders: true, debugColumns: false, }) return ( ({ columnFilters: state.columnFilters, pagination: state.pagination, })} > {(state) => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( <>
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
{header.column.getCanFilter() ? (
) : null} )}
Page
{state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{table.getPrePaginatedRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } function Filter({ column }: { column: Column }) { const { filterVariant } = column.columnDef.meta ?? {} const columnFilterValue = column.getFilterValue() const minMaxValues = column.getFacetedMinMaxValues() const sortedUniqueValues = React.useMemo( () => filterVariant === 'range' ? [] : Array.from(column.getFacetedUniqueValues().keys()) .sort() .slice(0, 5000), [column.getFacetedUniqueValues(), filterVariant], ) return filterVariant === 'range' ? (
column.setFilterValue((old: [number, number] | undefined) => [ value, old?.[1], ]) } placeholder={`Min ${ minMaxValues?.[0] !== undefined ? `(${minMaxValues[0]})` : '' }`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number] | undefined) => [ old?.[0], value, ]) } placeholder={`Max ${minMaxValues?.[1] ? `(${minMaxValues[1]})` : ''}`} className="w-24 border shadow rounded" />
) : filterVariant === 'select' ? ( ) : ( <> {/* Autocomplete suggestions from faceted values feature */} {sortedUniqueValues.map((value: any) => ( column.setFilterValue(value)} placeholder={`Search... (${column.getFacetedUniqueValues().size})`} className="w-36 border shadow rounded" list={column.id + 'list'} />
) } // A typical debounced input react component function DebouncedInput({ value: initialValue, onChange, debounce = 500, ...props }: { value: string | number onChange: (value: string | number) => void debounce?: number } & Omit, 'onChange'>) { const [value, setValue] = React.useState(initialValue) React.useEffect(() => { setValue(initialValue) }, [initialValue]) React.useEffect(() => { const timeout = setTimeout(() => { onChange(value) }, debounce) return () => clearTimeout(timeout) }, [value]) return ( setValue(e.target.value)} /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/filters-faceted/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/filters-faceted/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/filters-faceted/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/filters-fuzzy/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/filters-fuzzy/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/filters-fuzzy/index.html ================================================ Vite App
================================================ FILE: examples/react/filters-fuzzy/package.json ================================================ { "name": "tanstack-table-example-filters-fuzzy", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/match-sorter-utils": "^9.0.0-alpha.4", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/filters-fuzzy/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/filters-fuzzy/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnFilteringFeature, createColumnHelper, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, globalFilteringFeature, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { compareItems, rankItem } from '@tanstack/match-sorter-utils' import { makeData } from './makeData' import type { Person } from './makeData' import type { Column, FilterFn, SortFn } from '@tanstack/react-table' // A TanStack fork of Kent C. Dodds' match-sorter library that provides ranking information import type { RankingInfo } from '@tanstack/match-sorter-utils' const _features = tableFeatures({ columnFilteringFeature, globalFilteringFeature, rowSortingFeature, rowPaginationFeature, }) const columnHelper = createColumnHelper() // Define a custom fuzzy filter function that will apply ranking info to rows (using match-sorter utils) const fuzzyFilter: FilterFn = ( row, columnId, value, addMeta, ) => { // Rank the item const itemRank = rankItem(row.getValue(columnId), value) // Store the itemRank info addMeta?.({ itemRank, }) // Return if the item should be filtered in/out return itemRank.passed } // Define a custom fuzzy sort function that will sort by rank if the row has ranking information const fuzzySort: SortFn = (rowA, rowB, columnId) => { let dir = 0 // Only sort by rank if the column has ranking information // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (rowA.columnFiltersMeta[columnId]) { dir = compareItems( rowA.columnFiltersMeta[columnId].itemRank!, rowB.columnFiltersMeta[columnId].itemRank!, ) } // Provide an alphanumeric fallback for when the item ranks are equal return dir === 0 ? sortFns.alphanumeric(rowA, rowB, columnId) : dir } declare module '@tanstack/react-table' { // add fuzzy filter to the filterFns interface FilterFns { fuzzy: FilterFn } interface FilterMeta { itemRank?: RankingInfo } } function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('id', { filterFn: 'equalsString', // note: normal non-fuzzy filter column - exact match required }), columnHelper.accessor('firstName', { cell: (info) => info.getValue(), filterFn: 'includesStringSensitive', // note: normal non-fuzzy filter column - case sensitive }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, filterFn: 'includesString', // note: normal non-fuzzy filter column - case insensitive }), columnHelper.accessor((row) => `${row.firstName} ${row.lastName}`, { id: 'fullName', header: 'Full Name', cell: (info) => info.getValue(), filterFn: 'fuzzy', // using our custom fuzzy filter function // filterFn: fuzzyFilter, //or just define with the function sortFn: fuzzySort, // sort by fuzzy rank (falls back to alphanumeric) }), ]), [], ) const [data, setData] = React.useState>(() => makeData(5_000)) const refreshData = () => setData((_old) => makeData(50_000)) // stress test const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel({ ...filterFns, fuzzy: fuzzyFilter, }), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, columns, data, globalFilterFn: 'fuzzy', // apply fuzzy filter to the global filter (most common use case for fuzzy filter) debugTable: true, debugHeaders: true, debugColumns: false, }) // apply the fuzzy sort if the fullName column is being filtered React.useEffect(() => { if (table.store.state.columnFilters[0]?.id === 'fullName') { if (table.store.state.sorting[0]?.id !== 'fullName') { table.setSorting([{ id: 'fullName', desc: false }]) } } }, [table.store.state.columnFilters[0]?.id]) return ( ({ columnFilters: state.columnFilters, globalFilter: state.globalFilter, pagination: state.pagination, })} > {(state) => (
table.setGlobalFilter(String(value))} className="p-2 font-lg shadow border border-block" placeholder="Search all columns..." />
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( <>
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
{header.column.getCanFilter() ? (
) : null} )}
Page
{state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{table.getPrePaginatedRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } function Filter({ column }: { column: Column }) { const columnFilterValue = column.getFilterValue() return ( column.setFilterValue(value)} placeholder={`Search...`} className="w-36 border shadow rounded" /> ) } // A typical debounced input react component function DebouncedInput({ value: initialValue, onChange, debounce = 500, ...props }: { value: string | number onChange: (value: string | number) => void debounce?: number } & Omit, 'onChange'>) { const [value, setValue] = React.useState(initialValue) React.useEffect(() => { setValue(initialValue) }, [initialValue]) React.useEffect(() => { const timeout = setTimeout(() => { onChange(value) }, debounce) return () => clearTimeout(timeout) }, [value]) return ( setValue(e.target.value)} /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/filters-fuzzy/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: number firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (num: number): Person => { return { id: num, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((index): Person => { return { ...newPerson(index), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/filters-fuzzy/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/filters-fuzzy/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/grouping/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/grouping/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/grouping/index.html ================================================ Vite App
================================================ FILE: examples/react/grouping/package.json ================================================ { "name": "tanstack-table-example-grouping", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/grouping/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/grouping/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { aggregationFns, columnFilteringFeature, columnGroupingFeature, createExpandedRowModel, createFilteredRowModel, createGroupedRowModel, createPaginatedRowModel, createSortedRowModel, createTableHook, filterFns, rowExpandingFeature, rowPaginationFeature, rowSortingFeature, sortFns, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Person } from './makeData' // this example happens to use the createTableHook pattern, but it is not required const { useAppTable, createAppColumnHelper } = createTableHook({ _features: { columnFilteringFeature, columnGroupingFeature, rowExpandingFeature, rowPaginationFeature, rowSortingFeature, }, _rowModels: { expandedRowModel: createExpandedRowModel(), filteredRowModel: createFilteredRowModel(filterFns), groupedRowModel: createGroupedRowModel(aggregationFns), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, }) const columnHelper = createAppColumnHelper() function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), /** * override the value used for row grouping * (otherwise, defaults to the value derived from accessorKey / accessorFn) */ getGroupingValue: (row) => `${row.firstName} ${row.lastName}`, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', header: () => Last Name, cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: () => 'Age', aggregatedCell: ({ getValue }) => Math.round(getValue() * 100) / 100, aggregationFn: 'median', }), columnHelper.accessor('visits', { header: () => Visits, aggregationFn: 'sum', aggregatedCell: ({ getValue }) => getValue().toLocaleString(), }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', cell: ({ getValue }) => Math.round(getValue() * 100) / 100 + '%', aggregationFn: 'mean', aggregatedCell: ({ getValue }) => Math.round(getValue() * 100) / 100 + '%', }), ]), [], ) const [data, setData] = React.useState(() => makeData(10_000)) const refreshData = () => setData(() => makeData(100_000)) // stress test const table = useAppTable( { columns, data, debugTable: true, }, (state) => state, // subscribe to all state changes ) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : (
{header.column.getCanGroup() ? ( // If the header can be grouped, let's add a toggle ) : null}{' '}
)}
{cell.getIsGrouped() ? ( // If it's a grouped cell, add an expander and row count <> ) : cell.getIsAggregated() ? ( // If the cell is aggregated, use the Aggregated // renderer for cell ) : cell.getIsPlaceholder() ? null : ( // For cells with repeated values, render null // Otherwise, just render the regular cell )}
Page
{table.state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
{table.getRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/grouping/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/grouping/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/grouping/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/kitchen-sink-shadcn/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local !lib ================================================ FILE: examples/react/kitchen-sink-shadcn/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/kitchen-sink-shadcn/components.json ================================================ { "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", "rsc": false, "tsx": true, "tailwind": { "config": "tailwind.config.ts", "css": "src/index.css", "baseColor": "zinc", "cssVariables": true, "prefix": "" }, "aliases": { "components": "@/components", "utils": "@/lib/utils", "ui": "@/components/ui", "lib": "@/lib", "hooks": "@/hooks" }, "iconLibrary": "lucide" } ================================================ FILE: examples/react/kitchen-sink-shadcn/index.html ================================================ Vite App
================================================ FILE: examples/react/kitchen-sink-shadcn/package.json ================================================ { "name": "tanstack-table-example-kitchen-sink-shadcn", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc", "shadcn": "pnpm dlx shadcn@latest" }, "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@faker-js/faker": "^10.2.0", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-progress": "^1.1.8", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.18", "@tanstack/react-table": "^9.0.0-alpha.19", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "1.1.1", "date-fns": "^4.1.0", "lucide-react": "^0.563.0", "react": "^19.2.4", "react-day-picker": "9.13.0", "react-dom": "^19.2.4", "tailwind-merge": "^3.4.0", "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "tailwindcss": "^4.1.18", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/data-table/data-table-filter-list.tsx ================================================ 'use client' import * as React from 'react' import { format } from 'date-fns' import { CalendarIcon, Check, ChevronsUpDown, ListFilter, Trash2, } from 'lucide-react' import type { ExtendedColumnFilter, FilterOperator, JoinOperator, TableFilterFeatures, } from '@/types' import type { Column, ColumnMeta, RowData, Table, TableFeatures, } from '@tanstack/react-table' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Calendar } from '@/components/ui/calendar' import { getFilterOperators } from '@/lib/data-table' import { cn } from '@/lib/utils' import { Faceted, FacetedBadgeList, FacetedContent, FacetedEmpty, FacetedGroup, FacetedInput, FacetedItem, FacetedList, FacetedTrigger, } from '@/components/ui/faceted' import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command' // TODO: column.getFacetedUniqueValues() is broken rn, remove this once it's fixed function createManualFacetedValues( table: Table, TData>, columnId: string, ): Map { const facetedValues = new Map() const rows = table.getPreFilteredRowModel().flatRows for (const row of rows) { const value = row.getValue(columnId) if (value !== undefined && value !== null) { const count = facetedValues.get(value) ?? 0 facetedValues.set(value, count + 1) } } return facetedValues } function getColumnOptions< TFeatures extends TableFeatures, TData extends RowData, >({ column, table, }: { column: Column, TData> table: Table, TData> }): Array<{ label: string; value: string; count?: number }> { const customOptions = column.columnDef.meta?.options if (customOptions) return customOptions let uniqueValues: Map try { uniqueValues = column.getFacetedUniqueValues() if (!(uniqueValues instanceof Map)) { uniqueValues = createManualFacetedValues(table, column.id) } } catch (_err) { uniqueValues = createManualFacetedValues(table, column.id) } return Array.from(uniqueValues.entries()).map(([value, count]) => ({ label: String(value), value: String(value), count, })) } interface DataTableFilterListProps< TFeatures extends TableFeatures, TData extends RowData, > { table: Table, TData> columnFilters: Array onColumnFiltersChange: (filters: Array) => void } export function DataTableFilterList< TFeatures extends TableFeatures, TData extends RowData, >({ table, columnFilters, onColumnFiltersChange, }: DataTableFilterListProps) { const id = React.useId() const labelId = React.useId() const descriptionId = React.useId() const listId = React.useId() const [open, setOpen] = React.useState(false) const filterableColumns = React.useMemo( () => table.getAllColumns().filter((column) => column.getCanFilter()), [table], ) const getColumnFilterVariant = React.useCallback( ( column: Column, TData>, ): ColumnMeta['variant'] => { if (column.columnDef.meta?.variant) { return column.columnDef.meta.variant } const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) if (Array.isArray(firstValue)) return 'multi-select' if (typeof firstValue === 'number') return 'number' if (firstValue instanceof Date) return 'date' if (column.columnDef.meta?.variant === 'select') return 'select' return 'text' }, [table], ) const onFilterAddImpl = React.useCallback( (columnId: string): ExtendedColumnFilter | null => { const column = filterableColumns.find((col) => col.id === columnId) if (!column) return null const filterVariant = getColumnFilterVariant(column) const operators = getFilterOperators(filterVariant ?? 'text') const defaultOperator = operators[0].value return { id: columnId, value: filterVariant === 'multi-select' ? [] : '', operator: defaultOperator, filterId: crypto.randomUUID(), joinOperator: 'and', } }, [filterableColumns, getColumnFilterVariant], ) const onFilterAdd = React.useCallback(() => { const firstFilterableColumn = filterableColumns[0] const newFilter = onFilterAddImpl(firstFilterableColumn.id) if (newFilter) { onColumnFiltersChange([...columnFilters, newFilter]) } }, [columnFilters, onFilterAddImpl, filterableColumns, onColumnFiltersChange]) const onFilterUpdate = React.useCallback( ( filterId: string, updates: Partial>, ) => { const newFilters = columnFilters.map((filter) => { if (filter.filterId === filterId) { if (updates.id) { const newColumn = filterableColumns.find( (col) => col.id === updates.id, ) if (newColumn) { const filterVariant = getColumnFilterVariant(newColumn) const operators = getFilterOperators(filterVariant ?? 'text') const defaultOperator = operators[0].value return { ...filter, ...updates, operator: defaultOperator, value: filterVariant === 'multi-select' ? [] : '', } } } if (updates.operator && filter.value) { const column = filterableColumns.find((col) => col.id === filter.id) if (column && getColumnFilterVariant(column) === 'date') { const currentValue = filter.value if ( updates.operator === 'inRange' && !Array.isArray(currentValue) ) { return { ...filter, ...updates, value: [currentValue, undefined], } } else if ( updates.operator !== 'inRange' && Array.isArray(currentValue) ) { return { ...filter, ...updates, value: currentValue[0] ?? '', } } } } return { ...filter, ...updates } } return filter }) onColumnFiltersChange(newFilters) }, [ columnFilters, filterableColumns, getColumnFilterVariant, getFilterOperators, onColumnFiltersChange, ], ) const onFilterRemove = React.useCallback( (filterId: string) => { const newFilters = columnFilters.filter((filter) => { return filter.filterId !== filterId }) onColumnFiltersChange(newFilters) }, [columnFilters, onColumnFiltersChange], ) const onFilterInputRender = React.useCallback( ({ column, operator, filterId, inputId, }: { column: Column, TData> operator: FilterOperator filterId: string inputId: string }) => { const filterVariant = getColumnFilterVariant(column) ?? 'text' const currentFilter = columnFilters.find( (filter) => filter.filterId === filterId, ) const columnLabel = column.columnDef.meta?.label ?? column.id switch (filterVariant) { case 'date': if (operator === 'inRange') { const currentValue = Array.isArray(currentFilter?.value) ? currentFilter.value : [currentFilter?.value, undefined] const dateRange = currentValue[0] || currentValue[1] ? { from: currentValue[0] ? new Date(currentValue[0]) : undefined, to: currentValue[1] ? new Date(currentValue[1]) : undefined, } : undefined return (
{ document.getElementById(inputId)?.focus({ preventScroll: true, }) }} > { if (filterId) { onFilterUpdate(filterId, { value: [ date?.from ? date.from.toISOString() : undefined, date?.to ? date.to.toISOString() : undefined, ], operator, }) } }} numberOfMonths={2} initialFocus />
) } const selectedDate = currentFilter?.value ? new Date(currentFilter.value as string) : undefined return ( { document.getElementById(inputId)?.focus({ preventScroll: true, }) }} > { if (filterId) { onFilterUpdate(filterId, { value: date ? date.toISOString() : undefined, operator, }) } }} initialFocus /> ) case 'number': if (operator === 'inRange') { const currentValue = Array.isArray(currentFilter?.value) ? currentFilter.value : [currentFilter?.value, undefined] return (
{ if (filterId) { onFilterUpdate(filterId, { value: [ event.target.value === '' ? undefined : Number(event.target.value), currentValue[1] ?? undefined, ], operator, }) } }} /> { if (filterId) { onFilterUpdate(filterId, { value: [ currentValue[0] ?? undefined, event.target.value === '' ? undefined : Number(event.target.value), ], operator, }) } }} />
) } return ( { if (filterId) { onFilterUpdate(filterId, { value: event.target.value === '' ? '' : Number(event.target.value), operator, }) } }} /> ) case 'select': const selectOptions = getColumnOptions({ column, table }) return ( { if (filterId) { onFilterUpdate(filterId, { value }) } }} > No options found. {selectOptions.map((option) => ( {option.label} {option.count && ( {option.count} )} ))} ) case 'multi-select': const multiSelectOptions = getColumnOptions({ column, table }) const selectedValues = Array.isArray(currentFilter?.value) ? currentFilter.value : [] return ( { if (filterId) { onFilterUpdate(filterId, { value }) } }} > No options found. {multiSelectOptions.map((option) => ( {option.label} {option.count && ( {option.count} )} ))} ) default: if (operator === 'isEmpty' || operator === 'isNotEmpty') { return (
) } return ( { if (filterId) { onFilterUpdate(filterId, { value: event.target.value, operator, }) } }} /> ) } }, [getColumnFilterVariant, columnFilters, onFilterUpdate], ) const onFilterRender = React.useCallback( ({ filter, index }: { filter: ExtendedColumnFilter; index: number }) => { const column = table.getColumn(filter.id) if (!column || !filter.filterId) return null const filterVariant = getColumnFilterVariant(column) ?? 'text' const operators = getFilterOperators(filterVariant) const filterItemId = `${id}-filter-${filter.filterId}` const triggerId = `${filterItemId}-trigger` const joinOperatorListboxId = `${filterItemId}-join-operator-listbox` const fieldListboxId = `${filterItemId}-field-listbox` const operatorListboxId = `${filterItemId}-operator-listbox` const inputId = `${filterItemId}-input` return (
{index === 0 ? ( Where ) : index === 1 ? ( ) : ( {filter.joinOperator} )} document .getElementById(triggerId) ?.focus({ preventScroll: true }) } > No column found. {filterableColumns.map((col) => ( { if (!filter.filterId) return onFilterUpdate(filter.filterId, { id: value }) }} > {col.columnDef.meta?.label ?? col.id} ))} {onFilterInputRender({ column, operator: filter.operator ?? 'includesString', filterId: filter.filterId, inputId, })}
) }, [ table, filterableColumns, getColumnFilterVariant, onFilterInputRender, onFilterUpdate, onFilterRemove, ], ) return (

Filters

0 && 'sr-only', )} > {columnFilters.length > 0 ? 'Modify filters to refine your results.' : 'Add filters to refine your results.'}

{columnFilters.length > 0 && (
{columnFilters.map((filter, index) => onFilterRender({ filter, index }), )}
)}
{columnFilters.length > 0 && ( )}
) } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/data-table/data-table-pagination.tsx ================================================ 'use client' import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, } from 'lucide-react' import type { RowData, Table, TableFeatures } from '@tanstack/react-table' import { Button } from '@/components/ui/button' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' interface DataTablePaginationProps { table: Table, RowData> pageSizeOptions?: Array } export function DataTablePagination({ table, pageSizeOptions = [10, 20, 30, 40, 50], }: DataTablePaginationProps) { return (
{table.getFilteredSelectedRowModel().rows.length} of{' '} {table.getFilteredRowModel().rows.length} row(s) selected.

Rows per page

Page {table.store.state.pagination.pageIndex + 1} of{' '} {table.getPageCount()}
) } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/data-table/data-table-sort-list.tsx ================================================ 'use client' import * as React from 'react' import { ArrowDownUp, Check, ChevronsUpDown, GripVertical, Trash2, } from 'lucide-react' import type { ColumnSort, RowData, SortDirection, SortingState, Table, TableFeatures, } from '@tanstack/react-table' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, } from '@/components/ui/sortable' import { cn } from '@/lib/utils' interface DataTableSortListProps< TFeatures extends TableFeatures, TData extends RowData, > { table: Table, TData> sorting: SortingState onSortingChange: (sorting: SortingState) => void } export function DataTableSortList< TFeatures extends TableFeatures, TData extends RowData, >({ table, sorting, onSortingChange, }: DataTableSortListProps) { const labelId = React.useId() const descriptionId = React.useId() const listId = React.useId() const [open, setOpen] = React.useState(false) const sortableColumns = React.useMemo( () => table.getAllColumns().filter((column) => column.getCanSort()), [table], ) const onColumnSelect = React.useCallback( (currentSortId: string, newColumnId: string) => { const newSorting = sorting.map((s) => s.id === currentSortId ? { ...s, id: newColumnId } : s, ) table.setSorting(newSorting) }, [sorting, table], ) const onSortAdd = React.useCallback(() => { const firstAvailableColumn = sortableColumns.find( (col) => !sorting.some((s) => s.id === col.id), ) if (firstAvailableColumn) { table.setSorting([ ...sorting, { id: firstAvailableColumn.id, desc: false }, ]) } }, [sorting, sortableColumns, table]) const onSortUpdate = React.useCallback( (sortId: string, updates: Partial>) => { const newSorting = sorting.map((s) => s.id === sortId ? { ...s, ...updates } : s, ) table.setSorting(newSorting) }, [sorting, table], ) const onSortRemove = React.useCallback( (sortId: string) => { const newSorting = sorting.filter((s) => s.id !== sortId) table.setSorting(newSorting) }, [sorting, table], ) return ( item.id} >

{sorting.length > 0 ? 'Sort by' : 'No sorting applied'}

0 && 'sr-only', )} > {sorting.length > 0 ? 'Modify sorting to organize your results.' : 'Add sorting to organize your results.'}

{sorting.length > 0 ? (
{sorting.map((sort, index) => { const columnTitle = sortableColumns.find((col) => col.id === sort.id)?.columnDef .meta?.label ?? sort.id const sortItemId = `${listId}-item-${sort.id}` const triggerId = `${listId}-${index}-trigger` const fieldListboxId = `${sortItemId}-field-listbox` const operatorListboxId = `${sortItemId}-operator-listbox` return (
document .getElementById(triggerId) ?.focus({ preventScroll: true }) } > No column found. {sortableColumns .filter( (column) => !sorting.some( (s) => s.id === column.id && s.id !== sort.id, ), ) .map((column) => ( onColumnSelect(sort.id, column.id) } > {column.columnDef.meta?.label ?? column.id} ))}
) })}
) : null}
{sorting.length > 0 && ( )}
) } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/data-table/data-table-view-options.tsx ================================================ 'use client' import * as React from 'react' import { Check, ChevronsUpDown, GripVertical, Settings2 } from 'lucide-react' import type { ColumnOrderState, RowData, Table, TableFeatures, } from '@tanstack/react-table' import { Button } from '@/components/ui/button' import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from '@/components/ui/command' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' import { cn } from '@/lib/utils' import { Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, } from '@/components/ui/sortable' interface DataTableViewOptionsProps< TFeatures extends TableFeatures, TRowData extends RowData, > { table: Table, TRowData> columnOrder: ColumnOrderState onColumnOrderChange: (columnOrder: ColumnOrderState) => void } export function DataTableViewOptions< TFeatures extends TableFeatures, TRowData extends RowData, >({ table, columnOrder, onColumnOrderChange, }: DataTableViewOptionsProps) { const triggerRef = React.useRef(null) return ( triggerRef.current?.focus()} > No columns found. {table .getAllColumns() .sort((a, b) => { const aIndex = columnOrder.indexOf(a.id) const bIndex = columnOrder.indexOf(b.id) return aIndex - bIndex }) .filter( (column) => typeof column.accessorFn !== 'undefined', ) .map((column) => ( column.toggleVisibility(!column.getIsVisible()) } > {column.columnDef.meta?.label ?? column.id} ))}
table.toggleAllColumnsVisible(false)} className="w-full justify-center border" > Hide All table.toggleAllColumnsVisible(true)} className="w-full justify-center border" > Show All
) } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/badge.tsx ================================================ import * as React from 'react' import { cva } from 'class-variance-authority' import type { VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' const badgeVariants = cva( 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2', { variants: { variant: { default: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80', secondary: 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80', destructive: 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80', outline: 'text-foreground', }, }, defaultVariants: { variant: 'default', }, }, ) export interface BadgeProps extends React.HTMLAttributes, VariantProps {} function Badge({ className, variant, ...props }: BadgeProps) { return (
) } export { Badge, badgeVariants } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/button.tsx ================================================ import * as React from 'react' import { Slot } from '@radix-ui/react-slot' import { cva } from 'class-variance-authority' import type { VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' const buttonVariants = cva( 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', { variants: { variant: { default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90', destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90', outline: 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground', secondary: 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80', ghost: 'hover:bg-accent hover:text-accent-foreground', link: 'text-primary underline-offset-4 hover:underline', }, size: { default: 'h-9 px-4 py-2', sm: 'h-8 rounded-md px-3 text-xs', lg: 'h-10 rounded-md px-8', icon: 'h-9 w-9', }, }, defaultVariants: { variant: 'default', size: 'default', }, }, ) export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { asChild?: boolean } const Button = React.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { const Comp = asChild ? Slot : 'button' return ( ) }, ) Button.displayName = 'Button' export { Button, buttonVariants } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/calendar.tsx ================================================ 'use client' import * as React from 'react' import { ChevronLeft, ChevronRight } from 'lucide-react' import { DayPicker } from 'react-day-picker' import { cn } from '@/lib/utils' import { buttonVariants } from '@/components/ui/button' export type CalendarProps = React.ComponentProps function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) { return ( .day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md' : '[&:has([aria-selected])]:rounded-md', ), day: cn( buttonVariants({ variant: 'ghost' }), 'h-8 w-8 p-0 font-normal aria-selected:opacity-100', ), day_range_start: 'day-range-start', day_range_end: 'day-range-end', day_selected: 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground', day_today: 'bg-accent text-accent-foreground', day_outside: 'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground', day_disabled: 'text-muted-foreground opacity-50', day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground', day_hidden: 'invisible', ...classNames, }} components={{ Chevron: ({ orientation, className, ...props }) => { const Icon = orientation === 'left' || orientation === 'right' ? orientation === 'left' ? ChevronLeft : ChevronRight : ChevronLeft return }, }} {...props} /> ) } Calendar.displayName = 'Calendar' export { Calendar } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/checkbox.tsx ================================================ import * as React from 'react' import * as CheckboxPrimitive from '@radix-ui/react-checkbox' import { Check } from 'lucide-react' import { cn } from '@/lib/utils' const Checkbox = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Checkbox.displayName = CheckboxPrimitive.Root.displayName export { Checkbox } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/command.tsx ================================================ import * as React from 'react' import { Command as CommandPrimitive } from 'cmdk' import { Search } from 'lucide-react' import type { DialogProps } from '@radix-ui/react-dialog' import { cn } from '@/lib/utils' import { Dialog, DialogContent } from '@/components/ui/dialog' const Command = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) Command.displayName = CommandPrimitive.displayName const CommandDialog = ({ children, ...props }: DialogProps) => { return ( {children} ) } const CommandInput = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => (
)) CommandInput.displayName = CommandPrimitive.Input.displayName const CommandList = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandList.displayName = CommandPrimitive.List.displayName const CommandEmpty = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => ( )) CommandEmpty.displayName = CommandPrimitive.Empty.displayName const CommandGroup = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandGroup.displayName = CommandPrimitive.Group.displayName const CommandSeparator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandSeparator.displayName = CommandPrimitive.Separator.displayName const CommandItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) CommandItem.displayName = CommandPrimitive.Item.displayName const CommandShortcut = ({ className, ...props }: React.HTMLAttributes) => { return ( ) } CommandShortcut.displayName = 'CommandShortcut' export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/dialog.tsx ================================================ 'use client' import * as React from 'react' import * as DialogPrimitive from '@radix-ui/react-dialog' import { X } from 'lucide-react' import { cn } from '@/lib/utils' const Dialog = DialogPrimitive.Root const DialogTrigger = DialogPrimitive.Trigger const DialogPortal = DialogPrimitive.Portal const DialogClose = DialogPrimitive.Close const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogOverlay.displayName = DialogPrimitive.Overlay.displayName const DialogContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} Close )) DialogContent.displayName = DialogPrimitive.Content.displayName const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => (
) DialogHeader.displayName = 'DialogHeader' const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => (
) DialogFooter.displayName = 'DialogFooter' const DialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogTitle.displayName = DialogPrimitive.Title.displayName const DialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogDescription.displayName = DialogPrimitive.Description.displayName export { Dialog, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/dropdown-menu.tsx ================================================ 'use client' import * as React from 'react' import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' import { Check, ChevronRight, Circle } from 'lucide-react' import { cn } from '@/lib/utils' const DropdownMenu = DropdownMenuPrimitive.Root const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger const DropdownMenuGroup = DropdownMenuPrimitive.Group const DropdownMenuPortal = DropdownMenuPrimitive.Portal const DropdownMenuSub = DropdownMenuPrimitive.Sub const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup const DropdownMenuSubTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, children, ...props }, ref) => ( {children} )) DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName const DropdownMenuSubContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName const DropdownMenuContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( )) DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName const DropdownMenuItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( svg]:size-4 [&>svg]:shrink-0', inset && 'pl-8', className, )} {...props} /> )) DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName const DropdownMenuCheckboxItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, checked, ...props }, ref) => ( {children} )) DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName const DropdownMenuRadioItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )) DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName const DropdownMenuLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { inset?: boolean } >(({ className, inset, ...props }, ref) => ( )) DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName const DropdownMenuSeparator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { return ( ) } DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/faceted.tsx ================================================ 'use client' import { Check, ChevronsUpDown } from 'lucide-react' import * as React from 'react' import { Badge } from '@/components/ui/badge' import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from '@/components/ui/command' import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover' import { composeEventHandlers, useComposedRefs } from '@/lib/composition' import { cn } from '@/lib/utils' const FACETED_NAME = 'Faceted' const TRIGGER_NAME = 'FacetedTrigger' const BADGE_LIST_NAME = 'FacetedBadgeList' const CONTENT_NAME = 'FacetedContent' const INPUT_NAME = 'FacetedInput' const LIST_NAME = 'FacetedList' const EMPTY_NAME = 'FacetedEmpty' const GROUP_NAME = 'FacetedGroup' const ITEM_NAME = 'FacetedItem' const SEPARATOR_NAME = 'FacetedSeparator' const ERRORS = { [FACETED_NAME]: `\`${FACETED_NAME}\` must be used as root component`, [TRIGGER_NAME]: `\`${TRIGGER_NAME}\` must be within \`${FACETED_NAME}\``, [BADGE_LIST_NAME]: `\`${BADGE_LIST_NAME}\` must be within \`${FACETED_NAME}\``, [CONTENT_NAME]: `\`${CONTENT_NAME}\` must be within \`${FACETED_NAME}\``, [INPUT_NAME]: `\`${INPUT_NAME}\` must be within \`${FACETED_NAME}\``, [LIST_NAME]: `\`${LIST_NAME}\` must be within \`${FACETED_NAME}\``, [EMPTY_NAME]: `\`${EMPTY_NAME}\` must be within \`${FACETED_NAME}\``, [GROUP_NAME]: `\`${GROUP_NAME}\` must be within \`${FACETED_NAME}\``, [ITEM_NAME]: `\`${ITEM_NAME}\` must be within \`${FACETED_NAME}\``, [SEPARATOR_NAME]: `\`${SEPARATOR_NAME}\` must be within \`${FACETED_NAME}\``, } type FacetedValue = Multiple extends true ? Array : string interface FacetedContextValue { triggerRef: React.RefObject value?: FacetedValue onItemSelect?: (value: string) => void multiple?: Multiple } const FacetedContext = React.createContext | null>( null, ) function useFacetedContext(name: keyof typeof ERRORS) { const context = React.useContext(FacetedContext) if (!context) { throw new Error(ERRORS[name]) } return context } interface FacetedProps< Multiple extends boolean = false, > extends React.ComponentPropsWithoutRef { value?: FacetedValue onValueChange?: (value: FacetedValue | undefined) => void children?: React.ReactNode multiple?: Multiple } function Faceted( props: FacetedProps, ) { const { value, onValueChange, children, multiple = false as Multiple, ...facetedProps } = props const [open, setOpen] = React.useState(false) const triggerRef = React.useRef(null) const onItemSelect = React.useCallback( (selectedValue: string) => { if (!onValueChange) return if (multiple) { const currentValue: Array = Array.isArray(value) ? value : [] const newValue = currentValue.includes(selectedValue) ? currentValue.filter((v) => v !== selectedValue) : [...currentValue, selectedValue] onValueChange(newValue as FacetedValue) } else { if (value === selectedValue) { onValueChange(undefined) } else { onValueChange(selectedValue as FacetedValue) } requestAnimationFrame(() => { setOpen(false) }) } }, [multiple, onValueChange, value], ) const contextValue = React.useMemo>( () => ({ value, onItemSelect, multiple, triggerRef }), [value, onItemSelect, multiple], ) return ( {children} ) } Faceted.displayName = FACETED_NAME const FacetedTrigger = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >((props, forwardedRef) => { const { className, children, ...triggerProps } = props const context = useFacetedContext(TRIGGER_NAME) const composedRef = useComposedRefs(forwardedRef, context.triggerRef) return ( { // prevent implicit pointer capture const target = event.target if (!(target instanceof Element)) return if (target.hasPointerCapture(event.pointerId)) { target.releasePointerCapture(event.pointerId) } // Only prevent default if we're not clicking on the input // This allows text selection in the input while still preventing focus stealing elsewhere if ( event.button === 0 && event.ctrlKey === false && event.pointerType === 'mouse' && !(event.target instanceof HTMLInputElement) ) { event.preventDefault() } }, )} > {children} ) }) FacetedTrigger.displayName = TRIGGER_NAME interface FacetedBadgeListProps extends React.ComponentPropsWithoutRef<'div'> { options?: Array<{ label: string; value: string }> max?: number badgeClassName?: string placeholder?: string } const FacetedBadgeList = React.forwardRef< HTMLDivElement, FacetedBadgeListProps >((props, forwardedRef) => { const { options = [], max = 2, placeholder = 'Select options...', className, badgeClassName, ...badgeListProps } = props const context = useFacetedContext(BADGE_LIST_NAME) const values = Array.isArray(context.value) ? context.value : context.value ? [context.value] : [] const getLabel = React.useCallback( (value: string) => { const option = options.find((opt) => opt.value === value) return option?.label ?? value }, [options], ) if (values.length === 0) { return (
{placeholder}
) } return (
{values.length > max ? ( {values.length} selected ) : ( values.map((value) => ( {value ? getLabel(value) : ''} )) )}
) }) FacetedBadgeList.displayName = BADGE_LIST_NAME const FacetedContent = React.forwardRef< React.ComponentRef, React.ComponentPropsWithoutRef >((props, forwardedRef) => { const { className, children, ...contentProps } = props const context = useFacetedContext(CONTENT_NAME) return ( context.triggerRef.current?.focus({ preventScroll: true }), )} > {children} ) }) FacetedContent.displayName = CONTENT_NAME const FacetedInput = CommandInput FacetedInput.displayName = INPUT_NAME const FacetedList = CommandList FacetedList.displayName = LIST_NAME const FacetedEmpty = CommandEmpty FacetedEmpty.displayName = EMPTY_NAME const FacetedGroup = CommandGroup FacetedGroup.displayName = GROUP_NAME interface FacetedItemProps extends React.ComponentPropsWithoutRef< typeof CommandItem > { value: string } const FacetedItem = React.forwardRef< React.ComponentRef, FacetedItemProps >((props, ref) => { const { className, children, value, onSelect, ...itemProps } = props const context = useFacetedContext(ITEM_NAME) const isSelected = context.multiple ? Array.isArray(context.value) && context.value.includes(value) : context.value === value const onItemSelect = React.useCallback( (currentValue: string) => { if (onSelect) { onSelect(currentValue) } else if (context.onItemSelect) { context.onItemSelect(currentValue) } }, [onSelect, context.onItemSelect], ) return ( onItemSelect(value)} {...itemProps} ref={ref} > {children} ) }) FacetedItem.displayName = ITEM_NAME const FacetedSeparator = CommandSeparator FacetedSeparator.displayName = SEPARATOR_NAME export { Faceted, FacetedBadgeList, FacetedContent, FacetedEmpty, FacetedGroup, FacetedInput, FacetedItem, FacetedList, FacetedSeparator, FacetedTrigger, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/input.tsx ================================================ import * as React from 'react' import { cn } from '@/lib/utils' const Input = React.forwardRef>( ({ className, type, ...props }, ref) => { return ( ) }, ) Input.displayName = 'Input' export { Input } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/popover.tsx ================================================ import * as React from 'react' import * as PopoverPrimitive from '@radix-ui/react-popover' import { cn } from '@/lib/utils' const Popover = PopoverPrimitive.Root const PopoverTrigger = PopoverPrimitive.Trigger const PopoverAnchor = PopoverPrimitive.Anchor const PopoverContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( )) PopoverContent.displayName = PopoverPrimitive.Content.displayName export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/progress.tsx ================================================ import * as React from 'react' import * as ProgressPrimitive from '@radix-ui/react-progress' import { cn } from '@/lib/utils' const Progress = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, value, ...props }, ref) => ( )) Progress.displayName = ProgressPrimitive.Root.displayName export { Progress } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/select.tsx ================================================ import * as React from 'react' import * as SelectPrimitive from '@radix-ui/react-select' import { Check, ChevronDown, ChevronUp } from 'lucide-react' import { cn } from '@/lib/utils' const Select = SelectPrimitive.Root const SelectGroup = SelectPrimitive.Group const SelectValue = SelectPrimitive.Value const SelectTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( span]:line-clamp-1', className, )} {...props} > {children} )) SelectTrigger.displayName = SelectPrimitive.Trigger.displayName const SelectScrollUpButton = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName const SelectScrollDownButton = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName const SelectContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, position = 'popper', ...props }, ref) => ( {children} )) SelectContent.displayName = SelectPrimitive.Content.displayName const SelectLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SelectLabel.displayName = SelectPrimitive.Label.displayName const SelectItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )) SelectItem.displayName = SelectPrimitive.Item.displayName const SelectSeparator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) SelectSeparator.displayName = SelectPrimitive.Separator.displayName export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/sortable.tsx ================================================ 'use client' import * as React from 'react' import * as ReactDOM from 'react-dom' import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, TouchSensor, closestCenter, closestCorners, defaultDropAnimationSideEffects, useSensor, useSensors, } from '@dnd-kit/core' import { restrictToHorizontalAxis, restrictToParentElement, restrictToVerticalAxis, } from '@dnd-kit/modifiers' import { SortableContext, arrayMove, horizontalListSortingStrategy, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { Slot } from '@radix-ui/react-slot' import type { Announcements, DndContextProps, DragEndEvent, DraggableSyntheticListeners, DropAnimation, ScreenReaderInstructions, UniqueIdentifier, } from '@dnd-kit/core' import type { SortableContextProps } from '@dnd-kit/sortable' import { composeEventHandlers, useComposedRefs } from '@/lib/composition' import { cn } from '@/lib/utils' const orientationConfig = { vertical: { modifiers: [restrictToVerticalAxis, restrictToParentElement], strategy: verticalListSortingStrategy, collisionDetection: closestCenter, }, horizontal: { modifiers: [restrictToHorizontalAxis, restrictToParentElement], strategy: horizontalListSortingStrategy, collisionDetection: closestCenter, }, mixed: { modifiers: [restrictToParentElement], strategy: undefined, collisionDetection: closestCorners, }, } const ROOT_NAME = 'Sortable' const CONTENT_NAME = 'SortableContent' const ITEM_NAME = 'SortableItem' const ITEM_HANDLE_NAME = 'SortableItemHandle' const OVERLAY_NAME = 'SortableOverlay' const SORTABLE_ERROR = { [ROOT_NAME]: `\`${ROOT_NAME}\` components must be within \`${ROOT_NAME}\``, [CONTENT_NAME]: `\`${CONTENT_NAME}\` must be within \`${ROOT_NAME}\``, [ITEM_NAME]: `\`${ITEM_NAME}\` must be within \`${CONTENT_NAME}\``, [ITEM_HANDLE_NAME]: `\`${ITEM_HANDLE_NAME}\` must be within \`${ITEM_NAME}\``, [OVERLAY_NAME]: `\`${OVERLAY_NAME}\` must be within \`${ROOT_NAME}\``, } as const interface SortableRootContextValue { id: string items: Array modifiers: DndContextProps['modifiers'] strategy: SortableContextProps['strategy'] activeId: UniqueIdentifier | null setActiveId: (id: UniqueIdentifier | null) => void getItemValue: (item: T) => UniqueIdentifier flatCursor: boolean } const SortableRootContext = React.createContext | null>(null) SortableRootContext.displayName = ROOT_NAME function useSortableContext(name: keyof typeof SORTABLE_ERROR) { const context = React.useContext(SortableRootContext) if (!context) { throw new Error(SORTABLE_ERROR[name]) } return context } interface GetItemValue { /** * Callback that returns a unique identifier for each sortable item. Required for array of objects. * @example getItemValue={(item) => item.id} */ getItemValue: (item: T) => UniqueIdentifier } type SortableProps = DndContextProps & { value: Array onValueChange?: (items: Array) => void onMove?: ( event: DragEndEvent & { activeIndex: number; overIndex: number }, ) => void strategy?: SortableContextProps['strategy'] orientation?: 'vertical' | 'horizontal' | 'mixed' flatCursor?: boolean } & (T extends object ? GetItemValue : Partial>) function Sortable(props: SortableProps) { const { id = React.useId(), value, onValueChange, modifiers, strategy, onMove, orientation = 'vertical', flatCursor = false, getItemValue: getItemValueProp, accessibility, ...sortableProps } = props const [activeId, setActiveId] = React.useState(null) const sensors = useSensors( useSensor(MouseSensor), useSensor(TouchSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }), ) const config = React.useMemo( () => orientationConfig[orientation], [orientation], ) const getItemValue = React.useCallback( (item: T): UniqueIdentifier => { if (typeof item === 'object' && !getItemValueProp) { throw new Error('getItemValue is required when using array of objects.') } return getItemValueProp ? getItemValueProp(item) : (item as UniqueIdentifier) }, [getItemValueProp], ) const onDragEnd = React.useCallback( (event: DragEndEvent) => { const { active, over } = event if (over && active.id !== over.id) { const activeIndex = value.findIndex( (item) => getItemValue(item) === active.id, ) const overIndex = value.findIndex( (item) => getItemValue(item) === over.id, ) if (onMove) { onMove({ ...event, activeIndex, overIndex }) } else { onValueChange?.(arrayMove(value, activeIndex, overIndex)) } } setActiveId(null) }, [value, onValueChange, onMove, getItemValue], ) const announcements: Announcements = { onDragStart({ active }) { const activeValue = active.id.toString() return `Grabbed sortable item "${activeValue}". Current position is ${active.data.current?.sortable.index + 1} of ${value.length}. Use arrow keys to move, space to drop.` }, onDragOver({ active, over }) { if (over) { const overIndex = over.data.current?.sortable.index ?? 0 const activeIndex = active.data.current?.sortable.index ?? 0 const moveDirection = overIndex > activeIndex ? 'down' : 'up' const activeValue = active.id.toString() return `Sortable item "${activeValue}" moved ${moveDirection} to position ${overIndex + 1} of ${value.length}.` } return 'Sortable item is no longer over a droppable area. Press escape to cancel.' }, onDragEnd({ active, over }) { const activeValue = active.id.toString() if (over) { const overIndex = over.data.current?.sortable.index ?? 0 return `Sortable item "${activeValue}" dropped at position ${overIndex + 1} of ${value.length}.` } return `Sortable item "${activeValue}" dropped. No changes were made.` }, onDragCancel({ active }) { const activeIndex = active.data.current?.sortable.index ?? 0 const activeValue = active.id.toString() return `Sorting cancelled. Sortable item "${activeValue}" returned to position ${activeIndex + 1} of ${value.length}.` }, onDragMove({ active, over }) { if (over) { const overIndex = over.data.current?.sortable.index ?? 0 const activeIndex = active.data.current?.sortable.index ?? 0 const moveDirection = overIndex > activeIndex ? 'down' : 'up' const activeValue = active.id.toString() return `Sortable item "${activeValue}" is moving ${moveDirection} to position ${overIndex + 1} of ${value.length}.` } return 'Sortable item is no longer over a droppable area. Press escape to cancel.' }, } const screenReaderInstructions: ScreenReaderInstructions = React.useMemo( () => ({ draggable: ` To pick up a sortable item, press space or enter. While dragging, use the ${orientation === 'vertical' ? 'up and down' : orientation === 'horizontal' ? 'left and right' : 'arrow'} keys to move the item. Press space or enter again to drop the item in its new position, or press escape to cancel. `, }), [orientation], ) const items = React.useMemo(() => { return value.map((item) => getItemValue(item)) }, [value, getItemValue]) const contextValue = React.useMemo( () => ({ id, items, modifiers: modifiers ?? config.modifiers, strategy: strategy ?? config.strategy, activeId, setActiveId, getItemValue, flatCursor, }), [ id, items, modifiers, strategy, config.modifiers, config.strategy, activeId, getItemValue, flatCursor, ], ) return ( } > setActiveId(active.id), )} onDragEnd={composeEventHandlers(sortableProps.onDragEnd, onDragEnd)} onDragCancel={composeEventHandlers(sortableProps.onDragCancel, () => setActiveId(null), )} accessibility={{ announcements, screenReaderInstructions, ...accessibility, }} {...sortableProps} /> ) } const SortableContentContext = React.createContext(false) SortableContentContext.displayName = CONTENT_NAME interface SortableContentProps extends React.ComponentPropsWithoutRef<'div'> { strategy?: SortableContextProps['strategy'] children: React.ReactNode asChild?: boolean withoutSlot?: boolean } const SortableContent = React.forwardRef( (props, forwardedRef) => { const { strategy: strategyProp, asChild, withoutSlot, children, ...contentProps } = props const context = useSortableContext(CONTENT_NAME) const ContentSlot = asChild ? Slot : 'div' return ( {withoutSlot ? ( children ) : ( {children} )} ) }, ) SortableContent.displayName = CONTENT_NAME interface SortableItemContextValue { id: string attributes: React.HTMLAttributes listeners: DraggableSyntheticListeners | undefined setActivatorNodeRef: (node: HTMLElement | null) => void isDragging?: boolean disabled?: boolean } const SortableItemContext = React.createContext(null) SortableItemContext.displayName = ITEM_NAME interface SortableItemProps extends React.ComponentPropsWithoutRef<'div'> { value: UniqueIdentifier asHandle?: boolean asChild?: boolean disabled?: boolean } const SortableItem = React.forwardRef( (props, forwardedRef) => { const { value, style, asHandle, asChild, disabled, className, ...itemProps } = props const inSortableContent = React.useContext(SortableContentContext) const inSortableOverlay = React.useContext(SortableOverlayContext) if (!inSortableContent && !inSortableOverlay) { throw new Error(SORTABLE_ERROR[ITEM_NAME]) } if (value === '') { throw new Error(`\`${ITEM_NAME}\` value cannot be an empty string`) } const context = useSortableContext(ITEM_NAME) const id = React.useId() const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging, } = useSortable({ id: value, disabled }) const composedRef = useComposedRefs(forwardedRef, (node) => { if (disabled) return setNodeRef(node) if (asHandle) setActivatorNodeRef(node) }) const composedStyle = React.useMemo(() => { return { transform: CSS.Translate.toString(transform), transition, ...style, } }, [transform, transition, style]) const itemContext = React.useMemo( () => ({ id, attributes, listeners, setActivatorNodeRef, isDragging, disabled, }), [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled], ) const ItemSlot = asChild ? Slot : 'div' return ( ) }, ) SortableItem.displayName = ITEM_NAME interface SortableItemHandleProps extends React.ComponentPropsWithoutRef<'button'> { asChild?: boolean } const SortableItemHandle = React.forwardRef< HTMLButtonElement, SortableItemHandleProps >((props, forwardedRef) => { const { asChild, disabled, className, ...itemHandleProps } = props const itemContext = React.useContext(SortableItemContext) if (!itemContext) { throw new Error(SORTABLE_ERROR[ITEM_HANDLE_NAME]) } const context = useSortableContext(ITEM_HANDLE_NAME) const isDisabled = disabled ?? itemContext.disabled const composedRef = useComposedRefs(forwardedRef, (node) => { if (!isDisabled) return itemContext.setActivatorNodeRef(node) }) const HandleSlot = asChild ? Slot : 'button' return ( ) }) SortableItemHandle.displayName = ITEM_HANDLE_NAME const SortableOverlayContext = React.createContext(false) SortableOverlayContext.displayName = OVERLAY_NAME const dropAnimation: DropAnimation = { sideEffects: defaultDropAnimationSideEffects({ styles: { active: { opacity: '0.4', }, }, }), } interface SortableOverlayProps extends Omit< React.ComponentPropsWithoutRef, 'children' > { container?: HTMLElement | DocumentFragment | null children?: | ((params: { value: UniqueIdentifier }) => React.ReactNode) | React.ReactNode } function SortableOverlay(props: SortableOverlayProps) { const { container: containerProp, children, ...overlayProps } = props const context = useSortableContext(OVERLAY_NAME) const [mounted, setMounted] = React.useState(false) React.useLayoutEffect(() => setMounted(true), []) const container = containerProp ?? (mounted ? globalThis.document.body : null) if (!container) return null return ReactDOM.createPortal( {context.activeId ? typeof children === 'function' ? children({ value: context.activeId }) : children : null} , container, ) } const Root = Sortable const Content = SortableContent const Item = SortableItem const ItemHandle = SortableItemHandle const Overlay = SortableOverlay export { Content, Item, ItemHandle, Overlay, // Root, Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/table.tsx ================================================ import * as React from 'react' import { cn } from '@/lib/utils' const Table = React.forwardRef< HTMLTableElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
)) Table.displayName = 'Table' const TableHeader = React.forwardRef< HTMLTableSectionElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) TableHeader.displayName = 'TableHeader' const TableBody = React.forwardRef< HTMLTableSectionElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) TableBody.displayName = 'TableBody' const TableFooter = React.forwardRef< HTMLTableSectionElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( tr]:last:border-b-0', className, )} {...props} /> )) TableFooter.displayName = 'TableFooter' const TableRow = React.forwardRef< HTMLTableRowElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( )) TableRow.displayName = 'TableRow' const TableHead = React.forwardRef< HTMLTableCellElement, React.ThHTMLAttributes >(({ className, ...props }, ref) => ( {row.getAllCells().map((cell) => ( ))} ) } // Table Component function App() { const columns = React.useMemo( () => columnHelper.columns([ // Create a dedicated drag handle column. Alternatively, you could just set up dnd events on the rows themselves. columnHelper.display({ id: 'drag-handle', header: 'Move', cell: ({ row }) => , size: 60, }), columnHelper.accessor('firstName', { cell: (info) => info.getValue(), id: 'firstName', }), columnHelper.accessor((row) => row.lastName, { cell: (info) => info.getValue(), header: () => Last Name, id: 'lastName', }), columnHelper.accessor('age', { header: () => 'Age', id: 'age', }), columnHelper.accessor('visits', { header: () => Visits, id: 'visits', }), columnHelper.accessor('status', { header: 'Status', id: 'status', }), columnHelper.accessor('progress', { header: 'Profile Progress', id: 'progress', }), ]), [], ) const [data, setData] = React.useState(() => makeData(20)) const dataIds = React.useMemo>( () => data.map(({ userId }) => userId), [data], ) const rerender = () => setData(() => makeData(20)) const table = useAppTable( { columns, data, getRowId: (row) => row.userId, // required because row indexes will change }, (state) => state, ) // reorder rows after drag & drop function handleDragEnd(event: DragEndEvent) { const { active, over } = event if (over && active.id !== over.id) { setData((data) => { const oldIndex = dataIds.indexOf(active.id) const newIndex = dataIds.indexOf(over.id) return arrayMove(data, oldIndex, newIndex) // this is just a splice util }) } } const sensors = useSensors( useSensor(MouseSensor, {}), useSensor(TouchSensor, {}), useSensor(KeyboardSensor, {}), ) return ( // NOTE: This provider creates div elements, so don't nest inside of
[role=checkbox]]:translate-y-[2px]', className, )} {...props} /> )) TableHead.displayName = 'TableHead' const TableCell = React.forwardRef< HTMLTableCellElement, React.TdHTMLAttributes >(({ className, ...props }, ref) => ( [role=checkbox]]:translate-y-[2px]', className, )} {...props} /> )) TableCell.displayName = 'TableCell' const TableCaption = React.forwardRef< HTMLTableCaptionElement, React.HTMLAttributes >(({ className, ...props }, ref) => (
)) TableCaption.displayName = 'TableCaption' export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/components/ui/tooltip.tsx ================================================ import * as React from 'react' import * as TooltipPrimitive from '@radix-ui/react-tooltip' import { cn } from '@/lib/utils' const TooltipProvider = TooltipPrimitive.Provider const Tooltip = TooltipPrimitive.Root const TooltipTrigger = TooltipPrimitive.Trigger const TooltipContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( )) TooltipContent.displayName = TooltipPrimitive.Content.displayName export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/lib/composition.ts ================================================ import * as React from 'react' /** * A utility to compose multiple event handlers into a single event handler. * Run originalEventHandler first, then ourEventHandler unless prevented. */ function composeEventHandlers( originalEventHandler?: (event: E) => void, ourEventHandler?: (event: E) => void, { checkForDefaultPrevented = true } = {}, ) { return function handleEvent(event: E) { originalEventHandler?.(event) if ( checkForDefaultPrevented === false || !(event as unknown as Event).defaultPrevented ) { return ourEventHandler?.(event) } } } /** * @see https://github.com/radix-ui/primitives/blob/main/packages/react/compose-refs/src/compose-refs.tsx */ type PossibleRef = React.Ref | undefined /** * Set a given ref to a given value. * This utility takes care of different types of refs: callback refs and RefObject(s). */ function setRef(ref: PossibleRef, value: T) { if (typeof ref === 'function') { return ref(value) } if (ref !== null && ref !== undefined) { ref.current = value } } /** * A utility to compose multiple refs together. * Accepts callback refs and RefObject(s). */ function composeRefs(...refs: Array>): React.RefCallback { return (node) => { let hasCleanup = false const cleanups = refs.map((ref) => { const cleanup = setRef(ref, node) if (!hasCleanup && typeof cleanup === 'function') { hasCleanup = true } return cleanup }) // React <19 will log an error to the console if a callback ref returns a // value. We don't use ref cleanups internally so this will only happen if a // user's ref callback returns a value, which we only expect if they are // using the cleanup functionality added in React 19. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (hasCleanup) { return () => { for (let i = 0; i < cleanups.length; i++) { const cleanup = cleanups[i] if (typeof cleanup === 'function') { cleanup() } else { setRef(refs[i], null) } } } } } } /** * A custom hook that composes multiple refs. * Accepts callback refs and RefObject(s). */ function useComposedRefs( ...refs: Array> ): React.RefCallback { return React.useCallback(composeRefs(...refs), refs) } export { composeEventHandlers, composeRefs, useComposedRefs } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/lib/data-table.ts ================================================ import { filterFn_arrIncludes, filterFn_equals, filterFn_equalsString, filterFn_greaterThan, filterFn_greaterThanOrEqualTo, filterFn_includesString, filterFn_lessThan, filterFn_lessThanOrEqualTo, } from '@tanstack/react-table' import type { ExtendedColumnFilter, FilterOperator, JoinOperator, TableFilterFeatures, } from '@/types' import type { FilterFn, Row, RowData, TableFeatures, } from '@tanstack/react-table' function isFalsy(val: unknown) { return ( val === undefined || val === null || val === '' || (Array.isArray(val) && val.length === 0) ) } function isValidDate(value: unknown): boolean { if (value instanceof Date) return !isNaN(value.getTime()) if (typeof value === 'string') return !isNaN(Date.parse(value)) return false } function toDate(value: unknown): Date | null { if (value instanceof Date) return value if (typeof value === 'string') { const date = new Date(value) return !isNaN(date.getTime()) ? date : null } return null } function isSameDay(date1: Date, date2: Date): boolean { const date1Str = date1.toISOString().split('T')[0] const date2Str = date2.toISOString().split('T')[0] return date1Str === date2Str } const filterFn_enhancedEquals: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { const rowValue = row.getValue(columnId) if (Array.isArray(filterValue)) { return filterFn_arrIncludes(row, columnId, filterValue) } if (isValidDate(rowValue) && isValidDate(filterValue)) { const rowDate = toDate(rowValue) const filterDate = toDate(filterValue) if (rowDate && filterDate) { return isSameDay(rowDate, filterDate) } } return filterFn_equals(row, columnId, filterValue) } filterFn_enhancedEquals.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_enhancedGreaterThan: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { const rowValue = row.getValue(columnId) if (isValidDate(rowValue) && isValidDate(filterValue)) { const rowDate = toDate(rowValue) const filterDate = toDate(filterValue) if (rowDate && filterDate) { return rowDate.getTime() > filterDate.getTime() } } return filterFn_greaterThan(row, columnId, filterValue) } filterFn_enhancedGreaterThan.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_enhancedGreaterThanOrEqualTo: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { const rowValue = row.getValue(columnId) if (isValidDate(rowValue) && isValidDate(filterValue)) { const rowDate = toDate(rowValue) const filterDate = toDate(filterValue) if (rowDate && filterDate) { return rowDate.getTime() >= filterDate.getTime() } } return filterFn_greaterThanOrEqualTo(row, columnId, filterValue) } filterFn_enhancedGreaterThanOrEqualTo.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_enhancedLessThan: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { const rowValue = row.getValue(columnId) if (isValidDate(rowValue) && isValidDate(filterValue)) { const rowDate = toDate(rowValue) const filterDate = toDate(filterValue) if (rowDate && filterDate) { return rowDate.getTime() < filterDate.getTime() } } return filterFn_lessThan(row, columnId, filterValue) } filterFn_enhancedLessThan.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_enhancedLessThanOrEqualTo: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { const rowValue = row.getValue(columnId) if (isValidDate(rowValue) && isValidDate(filterValue)) { const rowDate = toDate(rowValue) const filterDate = toDate(filterValue) if (rowDate && filterDate) { return rowDate.getTime() <= filterDate.getTime() } } return filterFn_lessThanOrEqualTo(row, columnId, filterValue) } filterFn_enhancedLessThanOrEqualTo.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_startsWith: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: string, ) => { const value = String(row.getValue(columnId) ?? '').toLowerCase() return value.startsWith(filterValue.toLowerCase()) } filterFn_startsWith.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_endsWith: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: string, ) => { const value = String(row.getValue(columnId) ?? '').toLowerCase() return value.endsWith(filterValue.toLowerCase()) } filterFn_endsWith.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_isEmpty: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, ) => { const value = row.getValue(columnId) return ( value === undefined || value === null || value === '' || (Array.isArray(value) && value.length === 0) ) } filterFn_isEmpty.resolveFilterValue = (val: any) => isFalsy(val) const filterFn_inBetween: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { if (Array.isArray(filterValue)) { const [min, max] = filterValue const rowValue: unknown = row.getValue(columnId) if (min === undefined || min === '' || min === null) { return max === undefined || max === '' || max === null ? true : typeof rowValue === 'number' && typeof max === 'number' ? rowValue <= max : String(rowValue) <= String(max) } if (max === undefined || max === '' || max === null) { return typeof rowValue === 'number' && typeof min === 'number' ? rowValue >= min : String(rowValue) >= String(min) } if ( rowValue instanceof Date || (typeof rowValue === 'string' && !isNaN(Date.parse(rowValue))) ) { const dateValue = new Date(rowValue).getTime() const minDate = new Date(min as string | Date).getTime() const maxDate = new Date(max as string | Date).getTime() return dateValue >= minDate && dateValue <= maxDate } const numValue = Number(rowValue) return ( !isNaN(numValue) && numValue >= Number(min) && numValue <= Number(max) ) } return true } filterFn_inBetween.autoRemove = (val: any) => isFalsy(val) const filterFn_isRelativeToToday: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { const rowValue = row.getValue(columnId) if (!isValidDate(rowValue)) return false const rowDate = toDate(rowValue) if (!rowDate) return false rowDate.setHours(0, 0, 0, 0) const today = new Date() today.setHours(0, 0, 0, 0) const diffInDays = Math.floor( (rowDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24), ) if (typeof filterValue === 'number') { return diffInDays === filterValue } else if (typeof filterValue === 'string') { const numValue = parseInt(filterValue, 10) if (!isNaN(numValue)) { return diffInDays === numValue } } else if (Array.isArray(filterValue) && filterValue.length === 2) { const [min, max] = filterValue const minDays = typeof min === 'number' ? min : parseInt(min as string, 10) const maxDays = typeof max === 'number' ? max : parseInt(max as string, 10) if (!isNaN(minDays) && !isNaN(maxDays)) { return diffInDays >= minDays && diffInDays <= maxDays } } return false } filterFn_isRelativeToToday.autoRemove = (val: any) => isFalsy(val) export const dynamicFilterFn: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, TData>, columnId: string, filterValue: unknown, ) => { let operator: FilterOperator = 'includesString' let value = filterValue let joinOperator: JoinOperator = 'and' const filters: Array = row.table.store.state.columnFilters.filter((f) => f.id === columnId) if (!filters.length) return true if (filters[0].joinOperator) { joinOperator = filters[0].joinOperator } return filters.reduce((pass, filter, index) => { operator = filter.operator ?? 'includesString' value = filter.value if (isFalsy(value) && operator !== 'isEmpty' && operator !== 'isNotEmpty') { return pass } let result: boolean switch (operator) { case 'includesString': result = filterFn_includesString(row, columnId, value) break case 'notIncludesString': result = !filterFn_includesString(row, columnId, value) break case 'equalsString': result = filterFn_equalsString(row, columnId, value) break case 'notEqualsString': result = !filterFn_equalsString(row, columnId, value) break case 'startsWith': result = filterFn_startsWith(row, columnId, value) break case 'endsWith': result = filterFn_endsWith(row, columnId, value) break case 'isEmpty': result = filterFn_isEmpty(row, columnId, '') break case 'isNotEmpty': result = !filterFn_isEmpty(row, columnId, '') break case 'equals': result = filterFn_enhancedEquals(row, columnId, value) break case 'notEquals': result = !filterFn_enhancedEquals(row, columnId, value) break case 'greaterThan': result = filterFn_enhancedGreaterThan(row, columnId, value) break case 'greaterThanOrEqualTo': result = filterFn_enhancedGreaterThanOrEqualTo(row, columnId, value) break case 'lessThan': result = filterFn_enhancedLessThan(row, columnId, value) break case 'lessThanOrEqualTo': result = filterFn_enhancedLessThanOrEqualTo(row, columnId, value) break case 'inRange': result = filterFn_inBetween(row, columnId, value) break case 'isRelativeToToday': result = filterFn_isRelativeToToday(row, columnId, value) break default: result = filterFn_includesString(row, columnId, value) break } if (index === 0) return result return joinOperator === 'and' ? pass && result : pass || result }, true) } export function getFilterOperators(type: string): Array<{ label: string value: FilterOperator }> { switch (type) { case 'text': return [ { label: 'contains', value: 'includesString' }, { label: 'does not contain', value: 'notIncludesString' }, { label: 'starts with', value: 'startsWith' }, { label: 'ends with', value: 'endsWith' }, { label: 'is', value: 'equalsString' }, { label: 'is not', value: 'notEqualsString' }, { label: 'is empty', value: 'isEmpty' }, { label: 'is not empty', value: 'isNotEmpty' }, ] case 'number': return [ { label: 'is', value: 'equals' }, { label: 'is not', value: 'notEquals' }, { label: 'is less than', value: 'lessThan' }, { label: 'is less than or equal to', value: 'lessThanOrEqualTo' }, { label: 'is greater than', value: 'greaterThan' }, { label: 'is greater than or equal to', value: 'greaterThanOrEqualTo' }, { label: 'is between', value: 'inRange' }, ] case 'date': return [ { label: 'is', value: 'equals' }, { label: 'is not', value: 'notEquals' }, { label: 'is before', value: 'lessThan' }, { label: 'is on or before', value: 'lessThanOrEqualTo' }, { label: 'is after', value: 'greaterThan' }, { label: 'is on or after', value: 'greaterThanOrEqualTo' }, { label: 'is between', value: 'inRange' }, { label: 'is relative to today', value: 'isRelativeToToday' }, { label: 'is empty', value: 'isEmpty' }, { label: 'is not empty', value: 'isNotEmpty' }, ] case 'select': case 'multi-select': return [ { label: 'is', value: 'equals' }, { label: 'is not', value: 'notEquals' }, { label: 'is empty', value: 'isEmpty' }, { label: 'is not empty', value: 'isNotEmpty' }, ] default: return [ { label: 'contains', value: 'includesString' }, { label: 'does not contain', value: 'notIncludesString' }, { label: 'is', value: 'equalsString' }, { label: 'is not', value: 'notEqualsString' }, ] } } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/lib/make-data.ts ================================================ import { faker } from '@faker-js/faker' export const statuses = ['active', 'inactive', 'pending'] as const export const departments = [ 'engineering', 'marketing', 'finance', 'sales', 'hr', ] as const export interface Person { id: string firstName: string lastName: string age: number email: string status: (typeof statuses)[number] department: (typeof departments)[number] joinDate: Date subRows?: Array } function range(len: number) { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } function newPerson(): Person { return { id: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int({ min: 20, max: 65 }), email: faker.internet.email(), status: faker.helpers.arrayElement(statuses), department: faker.helpers.arrayElement(departments), joinDate: faker.date.past({ years: 5 }), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/lib/utils.ts ================================================ import { clsx } from 'clsx' import { twMerge } from 'tailwind-merge' import type { ClassValue } from 'clsx' export function cn(...inputs: Array) { return twMerge(clsx(inputs)) } export function formatDate( date: Date | string | number, opts: Intl.DateTimeFormatOptions = {}, ) { return new Intl.DateTimeFormat('en-US', { month: opts.month ?? 'long', day: opts.day ?? 'numeric', year: opts.year ?? 'numeric', ...opts, }).format(new Date(date)) } export function toSentenceCase(str: string) { return str .replace(/_/g, ' ') .replace(/([A-Z])/g, ' $1') .toLowerCase() .replace(/^\w/, (c) => c.toUpperCase()) .replace(/\s+/g, ' ') .trim() } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/main.tsx ================================================ 'use client' import * as React from 'react' import * as ReactDOM from 'react-dom/client' import '@/styles/globals.css' import { CheckCircle, ChevronDown, ChevronUp, Clock, Code, CreditCard, Megaphone, MoreHorizontal, ShoppingCart, Users, XCircle, } from 'lucide-react' import { columnFacetingFeature, columnFilteringFeature, columnOrderingFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, createCoreRowModel, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import type { Person } from '@/lib/make-data' import type { CellData, ColumnDef, ColumnSizingState, RowData, SortingState, TableFeatures, } from '@tanstack/react-table' import type { ExtendedColumnFilter } from '@/types' import { Button } from '@/components/ui/button' import { Checkbox } from '@/components/ui/checkbox' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { departments, makeData, statuses } from '@/lib/make-data' import { DataTablePagination } from '@/components/data-table/data-table-pagination' import { DataTableViewOptions } from '@/components/data-table/data-table-view-options' import { Badge } from '@/components/ui/badge' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { cn, formatDate, toSentenceCase } from '@/lib/utils' import { DataTableSortList } from '@/components/data-table/data-table-sort-list' import { DataTableFilterList } from '@/components/data-table/data-table-filter-list' import { dynamicFilterFn } from '@/lib/data-table' declare module '@tanstack/react-table' { interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { label?: string variant?: 'text' | 'number' | 'date' | 'boolean' | 'select' | 'multi-select' options?: Array<{ label: string; value: string; count?: number }> } } const _features = tableFeatures({ rowSortingFeature, rowPaginationFeature, rowSelectionFeature, columnFilteringFeature, columnFacetingFeature, columnOrderingFeature, columnVisibilityFeature, columnSizingFeature, columnResizingFeature, }) function App() { const rerender = React.useReducer(() => ({}), {})[1] const [rowSelection, setRowSelection] = React.useState({}) const [sorting, setSorting] = React.useState([]) const [columnFilters, setColumnFilters] = React.useState< Array >([]) const [columnVisibility, setColumnVisibility] = React.useState({}) const [columnSizing, setColumnSizing] = React.useState({}) const columns = React.useMemo>>( () => [ { id: 'select', header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value) } aria-label="Select all" className="translate-y-0.5" /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label="Select row" className="translate-y-0.5" /> ), maxSize: 30, enableSorting: false, enableHiding: false, enableResizing: false, }, { id: 'firstName', accessorKey: 'firstName', header: 'First Name', cell: (info) => String(info.getValue()), meta: { label: 'First Name', variant: 'text', }, }, { id: 'lastName', accessorFn: (row) => row.lastName, header: 'Last Name', cell: (info) => String(info.getValue()), meta: { label: 'Last Name', variant: 'text', }, }, { id: 'age', accessorKey: 'age', header: 'Age', cell: (info) => {String(info.getValue())}, meta: { label: 'Age', variant: 'number', }, }, { id: 'email', accessorKey: 'email', header: 'Email', cell: (info) => info.cell.getValue(), meta: { label: 'Email', variant: 'text', }, }, { id: 'status', accessorKey: 'status', header: 'Status', cell: (info) => { const status = info.getValue() const icons: Record = { active: , inactive: , pending: , } return ( {icons[status]} {toSentenceCase(status)} ) }, meta: { label: 'Status', variant: 'select', options: statuses.map((status) => ({ label: toSentenceCase(status), value: status, })), }, }, { id: 'department', accessorKey: 'department', header: 'Department', cell: (info) => { const department = info.getValue() const icons: Record = { engineering: , marketing: , sales: , hr: , finance: , } return ( {icons[department]} {toSentenceCase(department)} ) }, meta: { label: 'Department', variant: 'multi-select', options: departments.map((department) => ({ label: toSentenceCase(department), value: department, })), }, }, { id: 'joinDate', accessorKey: 'joinDate', header: 'Join Date', cell: (info) => formatDate(info.getValue()), meta: { label: 'Join Date', variant: 'date', }, }, { id: 'actions', enableHiding: false, cell: ({ row }) => { const person = row.original return ( Actions navigator.clipboard.writeText(person.id)} > Copy ID View details View profile ) }, maxSize: 30, enableResizing: false, }, ], [], ) const [data, setData] = React.useState(() => makeData(1_000)) const [columnOrder, setColumnOrder] = React.useState>(() => columns.map((c) => c.id ?? ''), ) const refreshData = () => setData(() => makeData(100_000)) // stress test const table = useTable( { _features, _rowModels: { coreRowModel: createCoreRowModel(), filteredRowModel: createFilteredRowModel(filterFns), facetedRowModel: createFacetedRowModel(), facetedUniqueValues: createFacetedUniqueValues(), paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, columns, data, defaultColumn: { minSize: 60, maxSize: 800, filterFn: dynamicFilterFn, }, state: { rowSelection, sorting, columnVisibility, columnOrder, columnSizing, columnFilters, }, onSortingChange: setSorting, onColumnVisibilityChange: setColumnVisibility, onColumnOrderChange: setColumnOrder, onColumnSizingChange: setColumnSizing, onColumnFiltersChange: setColumnFilters, getRowId: (row) => row.id, enableRowSelection: true, onRowSelectionChange: setRowSelection, columnResizeMode: 'onChange', debugTable: true, }, (state) => state, // subscribe to all re-renders ) const columnSizeVars = React.useMemo(() => { const headers = table.getFlatHeaders() const colSizes: { [key: string]: number } = {} for (const header of headers) { colSizes[`--header-${header.id}-size`] = header.getSize() colSizes[`--col-${header.column.id}-size`] = header.column.getSize() } return colSizes }, [table.store.state.columnSizing]) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers .filter((header) => header.column.getIsVisible()) .map((header) => { return ( {header.isPlaceholder ? null : (
{header.column.getIsSorted() && ( <> {header.column.getIsSorted() === 'asc' ? ( ) : ( )} )}
)} {header.column.getCanResize() && (
header.column.resetSize()} onMouseDown={header.getResizeHandler()} onTouchStart={header.getResizeHandler()} className={cn( 'absolute right-[-2px] z-10 top-1/2 h-6 w-[3px] -translate-y-1/2 cursor-e-resize select-none touch-none rounded-md transition-colors hover:bg-blue-600 before:absolute before:left-[-4px] before:right-[-4px] before:top-0 before:h-full before:content-[""]', header.column.getIsResizing() && 'bg-blue-600', )} /> )} ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getVisibleCells().map((cell) => { return ( ) })} ) })}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/kitchen-sink-shadcn/src/styles/globals.css ================================================ @import 'tailwindcss' source('../'); @plugin 'tailwindcss-animate'; @custom-variant dark (&:is(.dark *)); @theme inline { --color-background: hsl(var(--background)); --color-foreground: hsl(var(--foreground)); --color-card: hsl(var(--card)); --color-card-foreground: hsl(var(--card-foreground)); --color-popover: hsl(var(--popover)); --color-popover-foreground: hsl(var(--popover-foreground)); --color-primary: hsl(var(--primary)); --color-primary-foreground: hsl(var(--primary-foreground)); --color-secondary: hsl(var(--secondary)); --color-secondary-foreground: hsl(var(--secondary-foreground)); --color-muted: hsl(var(--muted)); --color-muted-foreground: hsl(var(--muted-foreground)); --color-accent: hsl(var(--accent)); --color-accent-foreground: hsl(var(--accent-foreground)); --color-destructive: hsl(var(--destructive)); --color-destructive-foreground: hsl(var(--destructive-foreground)); --color-border: hsl(var(--border)); --color-input: hsl(var(--input)); --color-ring: hsl(var(--ring)); --color-chart-1: hsl(var(--chart-1)); --color-chart-2: hsl(var(--chart-2)); --color-chart-3: hsl(var(--chart-3)); --color-chart-4: hsl(var(--chart-4)); --color-chart-5: hsl(var(--chart-5)); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } @layer base { :root { --background: hsl(0 0% 100%); --foreground: hsl(240 10% 3.9%); --card: hsl(0 0% 100%); --card-foreground: hsl(240 10% 3.9%); --popover: hsl(0 0% 100%); --popover-foreground: hsl(240 10% 3.9%); --primary: hsl(240 5.9% 10%); --primary-foreground: hsl(0 0% 98%); --secondary: hsl(240 4.8% 95.9%); --secondary-foreground: hsl(240 5.9% 10%); --muted: hsl(240 4.8% 95.9%); --muted-foreground: hsl(240 3.8% 46.1%); --accent: hsl(240 4.8% 95.9%); --accent-foreground: hsl(240 5.9% 10%); --destructive: hsl(0 84.2% 60.2%); --destructive-foreground: hsl(0 0% 98%); --border: hsl(240 5.9% 90%); --input: hsl(240 5.9% 90%); --ring: hsl(240 10% 3.9%); --chart-1: hsl(12 76% 61%); --chart-2: hsl(173 58% 39%); --chart-3: hsl(197 37% 24%); --chart-4: hsl(43 74% 66%); --chart-5: hsl(27 87% 67%); --radius: 0.5rem; } .dark { --background: hsl(240 10% 3.9%); --foreground: hsl(0 0% 98%); --card: hsl(240 10% 3.9%); --card-foreground: hsl(0 0% 98%); --popover: hsl(240 10% 3.9%); --popover-foreground: hsl(0 0% 98%); --primary: hsl(0 0% 98%); --primary-foreground: hsl(240 5.9% 10%); --secondary: hsl(240 3.7% 15.9%); --secondary-foreground: hsl(0 0% 98%); --muted: hsl(240 3.7% 15.9%); --muted-foreground: hsl(240 5% 64.9%); --accent: hsl(240 3.7% 15.9%); --accent-foreground: hsl(0 0% 98%); --destructive: hsl(0 62.8% 30.6%); --destructive-foreground: hsl(0 0% 98%); --border: hsl(240 3.7% 15.9%); --input: hsl(240 3.7% 15.9%); --ring: hsl(240 4.9% 83.9%); --chart-1: hsl(220 70% 50%); --chart-2: hsl(160 60% 45%); --chart-3: hsl(30 80% 55%); --chart-4: hsl(280 65% 60%); --chart-5: hsl(340 75% 55%); } } @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } } ================================================ FILE: examples/react/kitchen-sink-shadcn/src/types/index.ts ================================================ import type { ColumnFilter, TableFeatures, filterFns, } from '@tanstack/react-table' export type TableFilterFeatures = Pick< TFeatures, 'columnFilteringFeature' | 'columnFacetingFeature' > export type FilterOperator = | keyof typeof filterFns | 'notIncludesString' | 'notEqualsString' | 'notEquals' | 'greaterThan' | 'notGreaterThan' | 'greaterThanOrEqualTo' | 'notGreaterThanOrEqualTo' | 'lessThan' | 'notLessThan' | 'lessThanOrEqualTo' | 'notLessThanOrEqualTo' | 'isRelativeToToday' | 'inRange' | 'startsWith' | 'endsWith' | 'isEmpty' | 'isNotEmpty' export type JoinOperator = 'and' | 'or' export interface ExtendedColumnFilter extends ColumnFilter { filterId?: string operator?: FilterOperator joinOperator?: JoinOperator } ================================================ FILE: examples/react/kitchen-sink-shadcn/tailwind.config.ts ================================================ import type { Config } from 'tailwindcss' export default { darkMode: 'class', content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { extend: { borderRadius: { lg: 'var(--radius)', md: 'calc(var(--radius) - 2px)', sm: 'calc(var(--radius) - 4px)', }, colors: { background: 'hsl(var(--background))', foreground: 'hsl(var(--foreground))', card: { DEFAULT: 'hsl(var(--card))', foreground: 'hsl(var(--card-foreground))', }, popover: { DEFAULT: 'hsl(var(--popover))', foreground: 'hsl(var(--popover-foreground))', }, primary: { DEFAULT: 'hsl(var(--primary))', foreground: 'hsl(var(--primary-foreground))', }, secondary: { DEFAULT: 'hsl(var(--secondary))', foreground: 'hsl(var(--secondary-foreground))', }, muted: { DEFAULT: 'hsl(var(--muted))', foreground: 'hsl(var(--muted-foreground))', }, accent: { DEFAULT: 'hsl(var(--accent))', foreground: 'hsl(var(--accent-foreground))', }, destructive: { DEFAULT: 'hsl(var(--destructive))', foreground: 'hsl(var(--destructive-foreground))', }, border: 'hsl(var(--border))', input: 'hsl(var(--input))', ring: 'hsl(var(--ring))', chart: { '1': 'hsl(var(--chart-1))', '2': 'hsl(var(--chart-2))', '3': 'hsl(var(--chart-3))', '4': 'hsl(var(--chart-4))', '5': 'hsl(var(--chart-5))', }, }, }, }, // eslint-disable-next-line import/no-commonjs plugins: [require('tailwindcss-animate')], } satisfies Config ================================================ FILE: examples/react/kitchen-sink-shadcn/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, /* Paths */ "baseUrl": ".", "paths": { "@/*": ["./src/*"] } }, "include": ["src", "tailwind.config.ts", "vite.config.js"] } ================================================ FILE: examples/react/kitchen-sink-shadcn/vite.config.js ================================================ import path from 'node:path' import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' import tailwindcss from '@tailwindcss/vite' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), tailwindcss(), ], resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, }) ================================================ FILE: examples/react/pagination/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/pagination/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/pagination/index.html ================================================ Vite App
================================================ FILE: examples/react/pagination/package.json ================================================ { "name": "tanstack-table-example-pagination", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-store": "^0.9.2", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/pagination/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } button:disabled { opacity: 0.5; } ================================================ FILE: examples/react/pagination/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnFilteringFeature, createColumnHelper, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Column, ReactTable } from '@tanstack/react-table' import type { Person } from './makeData' const _features = tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), [], ) const [data, setData] = React.useState(() => makeData(1_000)) const refreshData = () => setData(() => makeData(100_000)) // stress test return ( <>
) } function MyTable({ data, columns, }: { data: Array columns: ReturnType }) { const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, debugTable: true, // no need to pass pageCount or rowCount with client-side pagination as it is calculated automatically // autoResetPageIndex: false, // turn off page index reset when sorting or filtering }) return ( ({ pagination: state.pagination, sorting: state.sorting, columnFilters: state.columnFilters, })} > {(state) => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null} {header.column.getCanFilter() ? (
) : null}
Page
{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
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } function Filter({ column, table, }: { column: Column table: ReactTable }) { const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) const columnFilterValue = column.getFilterValue() return typeof firstValue === 'number' ? (
e.stopPropagation()}> column.setFilterValue((old: [number, number]) => [ e.target.value, old[1], ]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number]) => [ old[0], e.target.value, ]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : ( column.setFilterValue(e.target.value)} onClick={(e) => e.stopPropagation()} placeholder={`Search...`} type="text" value={(columnFilterValue ?? '') as string} /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/pagination/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/pagination/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/pagination/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/row-dnd/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/row-dnd/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/row-dnd/index.html ================================================ Vite App
================================================ FILE: examples/react/row-dnd/package.json ================================================ { "name": "tanstack-table-example-row-dnd", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/row-dnd/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; background-color: white; } td button { padding: 1px 1rem; cursor: grab; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/row-dnd/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { FlexRender, columnSizingFeature, createTableHook, } from '@tanstack/react-table' import { DndContext, KeyboardSensor, MouseSensor, TouchSensor, closestCenter, useSensor, useSensors, } from '@dnd-kit/core' import { restrictToVerticalAxis } from '@dnd-kit/modifiers' import { SortableContext, arrayMove, useSortable, verticalListSortingStrategy, } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { makeData } from './makeData' import type { DragEndEvent, UniqueIdentifier } from '@dnd-kit/core' import type { CSSProperties } from 'react' import type { Person } from './makeData' import type { Row } from '@tanstack/react-table' import './index.css' const { appFeatures, useAppTable, createAppColumnHelper } = createTableHook({ _features: { columnSizingFeature }, _rowModels: {}, debugTable: true, debugHeaders: true, debugColumns: true, }) const columnHelper = createAppColumnHelper() // Cell Component const RowDragHandleCell = ({ rowId }: { rowId: string }) => { const { attributes, listeners } = useSortable({ id: rowId, }) return ( // Alternatively, you could set these attributes on the rows themselves ) } // Row Component const DraggableRow = ({ row }: { row: Row }) => { const { transform, transition, setNodeRef, isDragging } = useSortable({ id: row.original.userId, }) const style: CSSProperties = { transform: CSS.Translate.toString(transform), // translate instead of transform to avoid squishing transition: transition, opacity: isDragging ? 0.8 : 1, zIndex: isDragging ? 1 : 0, position: 'relative', } return ( // connect row ref to dnd-kit, apply important styles
elements
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( ))}
{header.isPlaceholder ? null : ( )}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/row-dnd/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { userId: string firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { userId: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/row-dnd/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/row-dnd/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/row-pinning/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/row-pinning/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/row-pinning/index.html ================================================ Vite App
================================================ FILE: examples/react/row-pinning/package.json ================================================ { "name": "tanstack-table-example-row-pinning", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/row-pinning/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } thead { background: lightgray; margin: 0; position: sticky; top: 0; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } .container { border: 1px solid lightgray; height: 500px; max-width: 900px !important; overflow: auto; } ================================================ FILE: examples/react/row-pinning/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnFilteringFeature, createExpandedRowModel, createFilteredRowModel, createPaginatedRowModel, filterFns, rowExpandingFeature, rowPaginationFeature, rowPinningFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { Person } from './makeData' import type { Column, ColumnDef, ExpandedState, ReactTable, Row, RowPinningState, } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ rowPinningFeature, rowExpandingFeature, columnFilteringFeature, rowPaginationFeature, }) function App() { const rerender = React.useReducer(() => ({}), {})[1] // table states const [rowPinning, setRowPinning] = React.useState({ top: [], bottom: [], }) const [expanded, setExpanded] = React.useState({}) // demo states const [keepPinnedRows, setKeepPinnedRows] = React.useState(true) const [includeLeafRows, setIncludeLeafRows] = React.useState(true) const [includeParentRows, setIncludeParentRows] = React.useState(false) const [copyPinnedRows, setCopyPinnedRows] = React.useState(false) const columns = React.useMemo>>( () => [ { id: 'pin', header: () => 'Pin', cell: ({ row }) => row.getIsPinned() ? ( ) : (
), }, { accessorKey: 'firstName', header: ({ table }) => ( <> {' '} First Name ), cell: ({ row, getValue }) => (
<> {row.getCanExpand() ? ( ) : ( '🔵' )}{' '} {getValue()}
), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }, { accessorKey: 'age', header: () => 'Age', size: 50, }, { accessorKey: 'visits', header: () => Visits, size: 50, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', size: 80, }, ], [includeLeafRows, includeParentRows], ) const [data, setData] = React.useState(() => makeData(1000, 2, 2)) const refreshData = () => setData(() => makeData(1000, 2, 2)) const table = useTable( { _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), expandedRowModel: createExpandedRowModel(), paginatedRowModel: createPaginatedRowModel(), }, columns, data, initialState: { pagination: { pageSize: 20, pageIndex: 0 } }, state: { expanded, rowPinning, }, onExpandedChange: setExpanded, onRowPinningChange: setRowPinning, getSubRows: (row) => row.subRows, keepPinnedRows, debugAll: true, }, (state) => state, // subscribe to all re-renders ) // console.log(table.getBottomRows) // React.useEffect(() => { // console.log(table.getBottomRows()) // }, [table.getBottomRows()]) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getTopRows().map((row) => ( ))} {(copyPinnedRows ? table.getRowModel().rows : table.getCenterRows() ).map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })} {table.getBottomRows().map((row) => ( ))}
{header.isPlaceholder ? null : ( <> {header.column.getCanFilter() ? (
) : null} )}
Page
{table.store.state.pagination.pageIndex + 1} of{' '} {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />


setKeepPinnedRows(!keepPinnedRows)} />
setIncludeLeafRows(!includeLeafRows)} />
setIncludeParentRows(!includeParentRows)} />
setCopyPinnedRows(!copyPinnedRows)} />
{JSON.stringify(rowPinning, null, 2)}
) } function PinnedRow({ row, table, }: { row: Row table: ReactTable }) { return ( {row.getAllCells().map((cell) => { return ( ) })} ) } function Filter({ column, table, }: { column: Column table: ReactTable }) { const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) return typeof firstValue === 'number' ? (
column.setFilterValue((old: any) => [e.target.value, old?.[1]]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: any) => [old?.[0], e.target.value]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : ( column.setFilterValue(e.target.value)} placeholder={`Search...`} className="w-36 border shadow rounded" /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/row-pinning/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/row-pinning/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/row-pinning/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/row-selection/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/row-selection/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/row-selection/index.html ================================================ Vite App
================================================ FILE: examples/react/row-selection/package.json ================================================ { "name": "tanstack-table-example-row-selection", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-store": "^0.9.2", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@tanstack/react-devtools": "0.9.6", "@tanstack/react-table-devtools": "9.0.0-alpha.11", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/row-selection/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } button:disabled, button[disabled] { opacity: 0.5; cursor: not-allowed; pointer-events: none; } ================================================ FILE: examples/react/row-selection/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnFilteringFeature, createColumnHelper, createFilteredRowModel, createPaginatedRowModel, filterFns, globalFilteringFeature, rowPaginationFeature, rowSelectionFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { tableDevtoolsPlugin } from '@tanstack/react-table-devtools' import { TanStackDevtools } from '@tanstack/react-devtools' import { makeData } from './makeData' import type { HTMLProps } from 'react' import type { Person } from './makeData' import type { Column, Table } from '@tanstack/react-table' import './index.css' const _features = tableFeatures({ rowPaginationFeature, rowSelectionFeature, columnFilteringFeature, globalFilteringFeature, }) const columnHelper = createColumnHelper() function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.display({ id: 'select', header: () => { return ( state.rowSelection}> {() => ( )} ) }, cell: ({ row }) => (
), }), columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', header: () => Last Name, cell: (info) => info.getValue(), footer: (props) => props.column.id, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]), [], ) const [data, setData] = React.useState(() => makeData(1_000)) const refreshData = () => setData(() => makeData(100_000)) // stress test const table = useTable( { _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data, getRowId: (row) => row.id, enableRowSelection: true, // enable row selection for all rows // enableRowSelection: row => row.original.age > 18, // or enable row selection conditionally per row debugTable: true, }, // (state) => state, // uncomment to subscribe to the entire table state (this is how v8 used to work by default) ) return ( <> ({ // don't include row selection state to optimize re-renders columnFilters: state.columnFilters, globalFilter: state.globalFilter, pagination: state.pagination, })} > {(state) => (
table.setGlobalFilter(e.target.value)} className="p-2 font-lg shadow border border-block" placeholder="Search all columns..." />
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( state.rowSelection[row.id]} // only re-render row when row selection changes (could down move to cell render too) > {() => ( {row.getAllCells().map((cell) => { return ( ) })} )} ) })}
{header.isPlaceholder ? null : ( <> {header.column.getCanFilter() ? (
) : null} )}
state.rowSelection}> {() => ( )} Page Rows ({table.getRowModel().rows.length})
Page
{table.store.state.pagination.pageIndex + 1} of{' '} {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />

({ numSelected: Object.keys(state.rowSelection).length, })} > {({ numSelected }) => <>{numSelected} of } {table.getPreFilteredRowModel().rows.length} Total Rows Selected


state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } function Filter({ column, table, }: { column: Column table: Table }) { const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) return typeof firstValue === 'number' ? (
column.setFilterValue((old: any) => [e.target.value, old?.[1]]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: any) => [old?.[0], e.target.value]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : ( column.setFilterValue(e.target.value)} placeholder={`Search...`} className="w-36 border shadow rounded" /> ) } function IndeterminateCheckbox({ indeterminate, className = '', ...rest }: { indeterminate?: boolean } & HTMLProps) { const ref = React.useRef(null!) React.useEffect(() => { if (typeof indeterminate === 'boolean') { ref.current.indeterminate = !rest.checked && indeterminate } }, [ref, indeterminate]) return ( ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/row-selection/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: string firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { id: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/row-selection/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/row-selection/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/sorting/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/sorting/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/sorting/index.html ================================================ Vite App
================================================ FILE: examples/react/sorting/package.json ================================================ { "name": "tanstack-table-example-sorting", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/sorting/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/sorting/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { createColumnHelper, createSortedRowModel, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { SortFn } from '@tanstack/react-table' import type { Person } from './makeData' const _features = tableFeatures({ rowSortingFeature, }) const columnHelper = createColumnHelper() // custom sorting logic for one of our enum columns const sortStatusFn: SortFn = (rowA, rowB, _columnId) => { const statusA = rowA.original.status const statusB = rowB.original.status const statusOrder = ['single', 'complicated', 'relationship'] return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB) } function App() { const rerender = React.useReducer(() => ({}), {})[1] const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), // this column will sort in ascending order by default since it is a string column }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, sortUndefined: 'last', // force undefined values to the end sortDescFirst: false, // first sort order will be ascending (nullable values can mess up auto detection of sort order) }), columnHelper.accessor('age', { header: () => 'Age', // this column will sort in descending order by default since it is a number column }), columnHelper.accessor('visits', { header: () => Visits, sortUndefined: 'last', // force undefined values to the end }), columnHelper.accessor('status', { header: 'Status', sortFn: sortStatusFn, // use our custom sorting function for this enum column }), columnHelper.accessor('progress', { header: 'Profile Progress', // enableSorting: false, //disable sorting for this column }), columnHelper.accessor('rank', { header: 'Rank', invertSorting: true, // invert the sorting order (golf score-like where smaller is better) }), columnHelper.accessor('createdAt', { header: 'Created At', // sortFn: 'datetime' //make sure table knows this is a datetime column (usually can detect if no null values) }), ]), [], ) const [data, setData] = React.useState(() => makeData(1_000)) const refreshData = () => setData(() => makeData(100_000)) // stress test with 100k rows const table = useTable( { _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), // client-side sorting }, columns, data, debugTable: true, // no need to pass pageCount or rowCount with client-side pagination as it is calculated automatically // autoResetPageIndex: false, // turn off page index reset when sorting or filtering - default on/true // enableMultiSort: false, //Don't allow shift key to sort multiple columns - default on/true // enableSorting: false, // - default on/true // enableSortingRemoval: false, //Don't allow - default on/true // isMultiSortEvent: (e) => true, //Make all clicks multi-sort - default requires `shift` key // maxMultiSortColCount: 3, // only allow 3 columns to be sorted at once - default is Infinity }, // (state) => state, // uncomment to subscribe to the entire table state (this is how v8 used to work by default) ) return ( ({ sorting: state.sorting })}> {(_state) => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table .getRowModel() .rows.slice(0, 10) .map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : (
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
{table.getRowModel().rows.length.toLocaleString()} Rows
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
)} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( // , // , ) ================================================ FILE: examples/react/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string | undefined age: number visits: number | undefined progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), age: faker.number.int(40), visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], rank: faker.number.int(100), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/sorting/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/sorting/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/sub-components/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/sub-components/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/sub-components/index.html ================================================ Vite App
================================================ FILE: examples/react/sub-components/package.json ================================================ { "name": "tanstack-table-example-sub-components", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/sub-components/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/sub-components/src/main.tsx ================================================ import React, { Fragment } from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { createColumnHelper, createExpandedRowModel, rowExpandingFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { makeData } from './makeData' import type { ColumnDef, Row, RowData, TableFeatures, } from '@tanstack/react-table' import type { Person } from './makeData' const _features = tableFeatures({ rowExpandingFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.display({ id: 'expander', header: () => null, cell: ({ row }) => { return row.getCanExpand() ? ( ) : ( '🔵' ) }, }), columnHelper.accessor('firstName', { header: 'First Name', cell: ({ row, getValue }) => (
{getValue()}
), footer: (props) => props.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, }), ]) type TableProps = { data: Array columns: Array> renderSubComponent: (props: { row: Row }) => React.ReactElement getRowCanExpand: (row: Row) => boolean } function Table({ columns, data, getRowCanExpand, renderSubComponent, }: TableProps): React.JSX.Element { const table = useTable({ _features, _rowModels: { expandedRowModel: createExpandedRowModel(), }, columns, data, getRowCanExpand, }) return ( state}> {() => (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {/* first row is a normal row */} {row.getAllCells().map((cell) => { return ( ) })} {row.getIsExpanded() && ( {/* 2nd row is a custom 1 cell row */} )} ) })}
{header.isPlaceholder ? null : (
)}
{renderSubComponent({ row })}
{table.getRowModel().rows.length} Rows
)} ) } const renderSubComponent = ({ row, }: { row: Row }) => { return (
      {JSON.stringify(row.original, null, 2)}
    
) } function App() { const [data] = React.useState(() => makeData(10)) return ( true} renderSubComponent={renderSubComponent} /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/sub-components/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/sub-components/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/sub-components/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/virtualized-columns/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/virtualized-columns/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/virtualized-columns/index.html ================================================ Vite App
================================================ FILE: examples/react/virtualized-columns/package.json ================================================ { "name": "tanstack-table-example-virtualized-columns", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "@tanstack/react-virtual": "^3.13.18", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/virtualized-columns/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border-collapse: collapse; border-spacing: 0; font-family: arial, sans-serif; table-layout: fixed; } thead { background: lightgray; } tr { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } td { padding: 6px; } .container { border: 1px solid lightgray; margin: 1rem auto; } .app { margin: 1rem auto; text-align: center; } ================================================ FILE: examples/react/virtualized-columns/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnSizingFeature, createSortedRowModel, rowSortingFeature, sortFns, useTable, } from '@tanstack/react-table' import { useVirtualizer } from '@tanstack/react-virtual' import { makeColumns, makeData } from './makeData' import type { Cell, ColumnDef, Header, HeaderGroup, ReactTable, Row, } from '@tanstack/react-table' import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual' import type { Person } from './makeData' const features = { columnSizingFeature, rowSortingFeature } function App() { const columns = React.useMemo>>( () => makeColumns(1_000), [], ) const [data, setData] = React.useState(() => makeData(1_000, columns)) const refreshData = React.useCallback(() => { setData(makeData(1_000, columns)) }, [columns]) const table = useTable({ _features: features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, debugTable: true, }) // All important CSS styles are included as inline styles for this example. This is not recommended for your code. return (
{process.env.NODE_ENV === 'development' ? (

Notice: You are currently running React in development mode. Virtualized rendering performance will be slightly degraded until this application is built for production.

) : null}
({columns.length.toLocaleString()} columns)
({data.length.toLocaleString()} rows)
) } interface TableContainerProps { table: ReactTable } function TableContainer({ table }: TableContainerProps) { const visibleColumns = table.getVisibleLeafColumns() // 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 const columnVirtualizer = useVirtualizer< HTMLDivElement, HTMLTableCellElement >({ count: visibleColumns.length, 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) }) const virtualColumns = columnVirtualizer.getVirtualItems() // different virtualization strategy for columns - instead of absolute and translateY, we add empty columns to the left and right let virtualPaddingLeft: number | undefined let virtualPaddingRight: number | undefined if (virtualColumns.length) { virtualPaddingLeft = virtualColumns[0]?.start ?? 0 virtualPaddingRight = columnVirtualizer.getTotalSize() - (virtualColumns[virtualColumns.length - 1]?.end ?? 0) } return (
{/* Even though we're still using sematic table tags, we must use CSS grid and flexbox for dynamic row heights */}
) } interface TableHeadProps { columnVirtualizer: Virtualizer table: ReactTable virtualPaddingLeft: number | undefined virtualPaddingRight: number | undefined } function TableHead({ columnVirtualizer, table, virtualPaddingLeft, virtualPaddingRight, }: TableHeadProps) { return ( {table.getHeaderGroups().map((headerGroup) => ( ))} ) } interface TableHeadRowProps { columnVirtualizer: Virtualizer headerGroup: HeaderGroup virtualPaddingLeft: number | undefined virtualPaddingRight: number | undefined table: ReactTable } function TableHeadRow({ columnVirtualizer, headerGroup, virtualPaddingLeft, virtualPaddingRight, table, }: TableHeadRowProps) { const virtualColumns = columnVirtualizer.getVirtualItems() return ( {virtualPaddingLeft ? ( // fake empty column to the left for virtualization scroll padding ) : null} {virtualColumns.map((virtualColumn) => { const header = headerGroup.headers[virtualColumn.index] return })} {virtualPaddingRight ? ( // fake empty column to the right for virtualization scroll padding ) : null} ) } interface TableHeadCellProps { header: Header table: ReactTable } function TableHeadCell({ header, table }: TableHeadCellProps) { return (
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
) } interface TableBodyProps { columnVirtualizer: Virtualizer table: ReactTable tableContainerRef: React.RefObject virtualPaddingLeft: number | undefined virtualPaddingRight: number | undefined } function TableBody({ columnVirtualizer, table, tableContainerRef, virtualPaddingLeft, virtualPaddingRight, }: TableBodyProps) { const { rows } = table.getRowModel() // 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 getScrollElement: () => tableContainerRef.current, // measure dynamic row height, except in firefox because it measures table border height incorrectly measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? (element) => element.getBoundingClientRect().height : undefined, overscan: 5, }) const virtualRows = rowVirtualizer.getVirtualItems() return ( {virtualRows.map((virtualRow) => { const row = rows[virtualRow.index] return ( ) })} ) } interface TableBodyRowProps { columnVirtualizer: Virtualizer row: Row rowVirtualizer: Virtualizer virtualPaddingLeft: number | undefined virtualPaddingRight: number | undefined virtualRow: VirtualItem table: ReactTable } function TableBodyRow({ columnVirtualizer, row, rowVirtualizer, virtualPaddingLeft, virtualPaddingRight, virtualRow, table, }: TableBodyRowProps) { const visibleCells = row.getVisibleCells() const virtualColumns = columnVirtualizer.getVirtualItems() return ( rowVirtualizer.measureElement(node)} // measure dynamic row height key={row.id} style={{ display: 'flex', position: 'absolute', transform: `translateY(${virtualRow.start}px)`, // this should always be a `style` as it changes on scroll width: '100%', }} > {virtualPaddingLeft ? ( // fake empty column to the left for virtualization scroll padding ) : null} {virtualColumns.map((vc) => { const cell = visibleCells[vc.index] return })} {virtualPaddingRight ? ( // fake empty column to the right for virtualization scroll padding ) : null} ) } interface TableBodyCellProps { cell: Cell table: ReactTable } function TableBodyCell({ cell, table }: TableBodyCellProps) { return ( ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/virtualized-columns/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export const makeColumns = (num: number) => [...Array(num)].map((_, i) => { return { accessorKey: i.toString(), header: 'Column ' + i.toString(), size: Math.floor(Math.random() * 150) + 100, } }) export const makeData = (num: number, columns: Array) => [...Array(num)].map(() => ({ ...Object.fromEntries( columns.map((col: any) => [col.accessorKey, faker.person.firstName()]), ), })) export type Person = ReturnType[0] ================================================ FILE: examples/react/virtualized-columns/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/virtualized-columns/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/virtualized-columns-experimental/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/virtualized-columns-experimental/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/virtualized-columns-experimental/index.html ================================================ Vite App
================================================ FILE: examples/react/virtualized-columns-experimental/package.json ================================================ { "name": "tanstack-table-example-virtualized-columns-experimental", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "@tanstack/react-virtual": "^3.13.18", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/virtualized-columns-experimental/src/index.css ================================================ :root { --virtual-padding-left: 0px; --virtual-padding-right: 0px; } html { font-family: sans-serif; font-size: 14px; } table { border-collapse: collapse; border-spacing: 0; font-family: arial, sans-serif; table-layout: fixed; } thead { background: lightgray; } tr { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } td { padding: 6px; } .container { border: 1px solid lightgray; margin: 1rem auto; } .app { margin: 1rem auto; text-align: center; } .left-column-spacer { width: var(--virtual-padding-left); } .right-column-spacer { width: var(--virtual-padding-right); } ================================================ FILE: examples/react/virtualized-columns-experimental/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { FlexRender, columnSizingFeature, createSortedRowModel, rowSortingFeature, sortFns, useTable, } from '@tanstack/react-table' import { useVirtualizer } from '@tanstack/react-virtual' import { makeColumns, makeData } from './makeData' import type { Cell, ColumnDef, Header, HeaderGroup, ReactTable, Row, } from '@tanstack/react-table' import type { Virtualizer } from '@tanstack/react-virtual' import type { Person } from './makeData' const _features = { columnSizingFeature, rowSortingFeature, } // All important CSS styles are included as inline styles for this example. This is not recommended for your code. function App() { const columns = React.useMemo>>( () => makeColumns(1_000), [], ) const [data, setData] = React.useState(() => makeData(1_000, columns)) const refreshData = React.useCallback(() => { setData(makeData(1_000, columns)) }, [columns]) // refresh data every 5 seconds React.useEffect(() => { const interval = setInterval(() => { refreshData() }, 5000) return () => clearInterval(interval) }, [refreshData]) // The table does not live in the same scope as the virtualizers const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, debugTable: true, }) return (
{process.env.NODE_ENV === 'development' ? (

Notice: You are currently running React in development mode. Virtualized rendering performance will be slightly degraded until this application is built for production.

) : null}
({columns.length.toLocaleString()} columns)
({data.length.toLocaleString()} rows)
) } interface TableContainerProps { table: ReactTable } function TableContainer({ table }: TableContainerProps) { const visibleColumns = table.getAllLeafColumns() // 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 const columnVirtualizer = useVirtualizer< HTMLDivElement, HTMLTableCellElement >({ count: visibleColumns.length, 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) onChange: (instance) => { // requestAnimationFrame(() => { const virtualColumns = instance.getVirtualItems() // different virtualization strategy for columns - instead of absolute and translateY, we add empty columns to the left and right const virtualPaddingLeft = virtualColumns[0]?.start ?? 0 const virtualPaddingRight = instance.getTotalSize() - (virtualColumns[virtualColumns.length - 1]?.end ?? 0) tableContainerRef.current?.style.setProperty( '--virtual-padding-left', `${virtualPaddingLeft}px`, ) tableContainerRef.current?.style.setProperty( '--virtual-padding-right', `${virtualPaddingRight}px`, ) // }) }, }) return (
({ sorting: state.sorting })}> {() => ( // Even though we're still using sematic table tags, we must use CSS grid and flexbox for dynamic row heights
)}
) } interface TableHeadProps { columnVirtualizer: Virtualizer table: ReactTable } function TableHead({ table, columnVirtualizer }: TableHeadProps) { return ( {table.getHeaderGroups().map((headerGroup) => ( ))} ) } interface TableHeadRowProps { columnVirtualizer: Virtualizer headerGroup: HeaderGroup } function TableHeadRow({ columnVirtualizer, headerGroup }: TableHeadRowProps) { const virtualColumnIndexes = columnVirtualizer.getVirtualIndexes() return ( {/* fake empty column to the left for virtualization scroll padding */} {virtualColumnIndexes.map((virtualColumnIndex) => { const header = headerGroup.headers[virtualColumnIndex] return ( ) })} {/* fake empty column to the right for virtualization scroll padding */} ) } interface TableHeadCellProps { columnVirtualizer: Virtualizer header: Header } function TableHeadCell({ columnVirtualizer: _columnVirtualizer, header, }: TableHeadCellProps) { return (
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
) } const TableHeadCellMemo = React.memo( TableHeadCell, (_prev, next) => next.columnVirtualizer.isScrolling, ) as typeof TableHeadCell interface TableBodyProps { columnVirtualizer: Virtualizer table: ReactTable tableContainerRef: React.RefObject } function TableBody({ columnVirtualizer, table, tableContainerRef, }: TableBodyProps) { const tableBodyRef = React.useRef(null) const rowRefsMap = React.useRef>(new Map()) const { rows } = table.getRowModel() // 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 getScrollElement: () => tableContainerRef.current, // measure dynamic row height, except in firefox because it measures table border height incorrectly measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? (element) => element.getBoundingClientRect().height : undefined, overscan: 5, onChange: (instance) => { // requestAnimationFrame(() => { tableBodyRef.current!.style.height = `${instance.getTotalSize()}px` instance.getVirtualItems().forEach((virtualRow) => { const rowRef = rowRefsMap.current.get(virtualRow.index) if (!rowRef) return rowRef.style.transform = `translateY(${virtualRow.start}px)` }) // }) }, }) React.useLayoutEffect(() => { rowVirtualizer.measure() }, [table.store.state]) const virtualRowIndexes = rowVirtualizer.getVirtualIndexes() return ( {virtualRowIndexes.map((virtualRowIndex) => { const row = rows[virtualRowIndex] return ( ) })} ) } interface TableBodyRowProps { columnVirtualizer: Virtualizer row: Row rowVirtualizer: Virtualizer virtualRowIndex: number rowRefsMap: React.RefObject> } function TableBodyRow({ columnVirtualizer, row, rowVirtualizer, virtualRowIndex, rowRefsMap, }: TableBodyRowProps) { const visibleCells = row.getAllCells() const virtualColumnIndexes = columnVirtualizer.getVirtualIndexes() return ( { if (node && typeof virtualRowIndex !== 'undefined') { rowVirtualizer.measureElement(node) rowRefsMap.current.set(virtualRowIndex, node) } }} // measure dynamic row height key={row.id} style={{ display: 'flex', position: 'absolute', width: '100%', }} > {/* fake empty column to the left for virtualization scroll padding */} {virtualColumnIndexes.map((virtualColumnIndex) => { const cell = visibleCells[virtualColumnIndex] return ( ) })} {/* fake empty column to the right for virtualization scroll padding */} ) } // TODO: Can rows be memoized in any way without breaking column virtualization? // const TableBodyRowMemo = React.memo( // TableBodyRow, // (_prev, next) => next.rowVirtualizer.isScrolling // ) interface TableBodyCellProps { cell: Cell columnVirtualizer: Virtualizer } function TableBodyCell({ cell, columnVirtualizer: _columnVirtualizer, }: TableBodyCellProps) { return ( ) } const TableBodyCellMemo = React.memo( TableBodyCell, (_prev, next) => next.columnVirtualizer.isScrolling, ) as typeof TableBodyCell const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/virtualized-columns-experimental/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = Record export const makeColumns = (num: number) => [...Array(num)].map((_, i) => { return { accessorKey: i.toString(), header: 'Column ' + i.toString(), size: Math.floor(Math.random() * 150) + 100, } }) export const makeData = (num: number, columns: Array): Array => [...Array(num)].map(() => ({ ...Object.fromEntries( columns.map((col) => [ (col as { accessorKey?: string }).accessorKey, faker.person.firstName(), ]), ), })) ================================================ FILE: examples/react/virtualized-columns-experimental/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/virtualized-columns-experimental/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/virtualized-infinite-scrolling/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/virtualized-infinite-scrolling/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/virtualized-infinite-scrolling/index.html ================================================ Vite App
================================================ FILE: examples/react/virtualized-infinite-scrolling/package.json ================================================ { "name": "tanstack-table-example-virtualized-infinite-scrolling", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-query": "^5.90.20", "@tanstack/react-table": "^9.0.0-alpha.19", "@tanstack/react-virtual": "^3.13.18", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/virtualized-infinite-scrolling/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border-collapse: collapse; border-spacing: 0; font-family: arial, sans-serif; table-layout: fixed; } thead { background: lightgray; } tr { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } td { padding: 6px; } .container { border: 1px solid lightgray; margin: 1rem auto; } .app { margin: 1rem auto; text-align: center; } ================================================ FILE: examples/react/virtualized-infinite-scrolling/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' // 3 TanStack Libraries!!! import { columnSizingFeature, createColumnHelper, createSortedRowModel, rowSortingFeature, sortFns, tableFeatures, useTable, } from '@tanstack/react-table' import { QueryClient, QueryClientProvider, keepPreviousData, useInfiniteQuery, } from '@tanstack/react-query' import { useVirtualizer } from '@tanstack/react-virtual' import { fetchData } from './makeData' import type { Person, PersonApiResponse } from './makeData' import type { OnChangeFn, SortingState } from '@tanstack/react-table' const fetchSize = 50 const _features = tableFeatures({ columnSizingFeature, rowSortingFeature }) const columnHelper = createColumnHelper() function App() { // we need a reference to the scrolling element for logic down below const tableContainerRef = React.useRef(null) const [sorting, setSorting] = React.useState([]) const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('id', { header: 'ID', size: 60, }), columnHelper.accessor('firstName', { cell: (info) => info.getValue(), }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }), columnHelper.accessor('age', { header: () => 'Age', size: 50, }), columnHelper.accessor('visits', { header: () => Visits, size: 50, }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', size: 80, }), columnHelper.accessor('createdAt', { header: 'Created At', cell: (info) => info.getValue().toLocaleString(), size: 200, }), ]), [], ) // react-query has a useInfiniteQuery hook that is perfect for this use case const { data, fetchNextPage, isFetching, isLoading } = useInfiniteQuery({ queryKey: [ 'people', sorting, // refetch when sorting changes ], queryFn: async ({ pageParam = 0 }) => { const start = (pageParam as number) * fetchSize const fetchedData = await fetchData(start, fetchSize, sorting) // pretend api call return fetchedData }, initialPageParam: 0, getNextPageParam: (_lastGroup, groups) => groups.length, refetchOnWindowFocus: false, placeholderData: keepPreviousData, }) // flatten the array of arrays from the useInfiniteQuery hook const flatData = React.useMemo( () => data?.pages.flatMap((page) => page.data) ?? [], [data], ) const totalDBRowCount = data?.pages[0]?.meta?.totalRowCount ?? 0 const totalFetched = flatData.length // called on scroll and possibly on mount to fetch more data as the user scrolls and reaches bottom of table const fetchMoreOnBottomReached = React.useCallback( (containerRefElement?: HTMLDivElement | null) => { if (containerRefElement) { const { scrollHeight, scrollTop, clientHeight } = containerRefElement // once the user has scrolled within 500px of the bottom of the table, fetch more data if we can if ( scrollHeight - scrollTop - clientHeight < 500 && !isFetching && totalFetched < totalDBRowCount ) { fetchNextPage() } } }, [fetchNextPage, isFetching, totalFetched, totalDBRowCount], ) // a check on mount and after a fetch to see if the table is already scrolled to the bottom and immediately needs to fetch more data React.useEffect(() => { fetchMoreOnBottomReached(tableContainerRef.current) }, [fetchMoreOnBottomReached]) const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, data: flatData, columns, state: { sorting, }, manualSorting: true, debugTable: true, }) // scroll to top of table when sorting changes const handleSortingChange: OnChangeFn = (updater) => { setSorting(updater) if (table.getRowModel().rows.length) { rowVirtualizer.scrollToIndex(0) } } // since this table option is derived from table row model state, we're using the table.setOptions utility table.setOptions((prev) => ({ ...prev, onSortingChange: handleSortingChange, })) const { rows } = table.getRowModel() const rowVirtualizer = useVirtualizer({ count: rows.length, 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 measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? (element) => element.getBoundingClientRect().height : undefined, overscan: 5, }) if (isLoading) { return <>Loading... } return (
{process.env.NODE_ENV === 'development' ? (

Notice: You are currently running React in development mode. Virtualized rendering performance will be slightly degraded until this application is built for production.

) : null} ({flatData.length} of {totalDBRowCount} rows fetched)
fetchMoreOnBottomReached(e.currentTarget)} ref={tableContainerRef} style={{ overflow: 'auto', // our scrollable table container position: 'relative', // needed for sticky header height: '600px', // should be a fixed height }} > {/* Even though we're still using sematic table tags, we must use CSS grid and flexbox for dynamic row heights */} {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {rowVirtualizer.getVirtualItems().map((virtualRow) => { const row = rows[virtualRow.index] return ( rowVirtualizer.measureElement(node)} // measure dynamic row height key={row.id} style={{ display: 'flex', position: 'absolute', transform: `translateY(${virtualRow.start}px)`, // this should always be a `style` as it changes on scroll width: '100%', }} > {row.getAllCells().map((cell) => { return ( ) })} ) })}
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
{isFetching &&
Fetching More...
}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') const queryClient = new QueryClient() ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/virtualized-infinite-scrolling/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' import type { SortingState } from '@tanstack/react-table' export type Person = { id: number firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' createdAt: Date } export type PersonApiResponse = { data: Array meta: { totalRowCount: number } } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (index: number): Person => { return { id: index + 1, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(d), } }) } return makeDataLevel() } const data = makeData(1000) // simulates a backend api export const fetchData = async ( start: number, size: number, sorting: SortingState, ) => { const dbData = [...data] if (sorting.length) { const sort = sorting[0] const { id, desc } = sort as { id: keyof Person; desc: boolean } dbData.sort((a, b) => { if (desc) { return a[id] < b[id] ? 1 : -1 } return a[id] > b[id] ? 1 : -1 }) } // simulate a backend api await new Promise((resolve) => setTimeout(resolve, 200)) return { data: dbData.slice(start, start + size), meta: { totalRowCount: dbData.length, }, } } ================================================ FILE: examples/react/virtualized-infinite-scrolling/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/virtualized-infinite-scrolling/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/virtualized-rows/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/virtualized-rows/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/virtualized-rows/index.html ================================================ Vite App
================================================ FILE: examples/react/virtualized-rows/package.json ================================================ { "name": "tanstack-table-example-virtualized-rows", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "@tanstack/react-virtual": "^3.13.18", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/virtualized-rows/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border-collapse: collapse; border-spacing: 0; font-family: arial, sans-serif; table-layout: fixed; } thead { background: lightgray; } tr { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } td { padding: 6px; } .container { border: 1px solid lightgray; margin: 1rem auto; } .app { margin: 1rem auto; text-align: center; } ================================================ FILE: examples/react/virtualized-rows/src/main.tsx ================================================ import React, { useEffect } from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { columnSizingFeature, createSortedRowModel, rowSortingFeature, sortFns, useTable, } from '@tanstack/react-table' import { useVirtualizer } from '@tanstack/react-virtual' import { makeData } from './makeData' import type { ColumnDef, ReactTable, Row } from '@tanstack/react-table' import type { VirtualItem, Virtualizer } from '@tanstack/react-virtual' import type { Person } from './makeData' const features = { columnSizingFeature, rowSortingFeature, } // This is a dynamic row height example, which is more complicated, but allows for a more realistic table. // See https://tanstack.com/virtual/v3/docs/examples/react/table for a simpler fixed row height example. function App() { const columns = React.useMemo>>( () => [ { accessorKey: 'id', header: 'ID', size: 60, }, { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }, { accessorKey: 'age', header: () => 'Age', size: 50, }, { accessorKey: 'visits', header: () => Visits, size: 50, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', size: 80, }, { accessorKey: 'createdAt', header: 'Created At', cell: (info) => info.getValue().toLocaleString(), size: 250, }, ], [], ) // The virtualizer will need a reference to the scrollable container element const tableContainerRef = React.useRef(null) const [data, setData] = React.useState(() => makeData(100_000)) const refreshData = React.useCallback(() => { setData(makeData(100_000)) }, []) const table = useTable({ _features: features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, debugTable: true, }) // All important CSS styles are included as inline styles for this example. This is not recommended for your code. return ( <>
{process.env.NODE_ENV === 'development' ? (

Notice: You are currently running React in development mode. Virtualized rendering performance will be slightly degraded until this application is built for production.

) : null} ({data.length.toLocaleString()} rows)
state}> {() => ( // Even though we're still using sematic table tags, we must use CSS grid and flexbox for dynamic row heights {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))}
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
state}> {(state) =>
{JSON.stringify(state, null, 2)}
}
) } interface TableBodyProps { table: ReactTable tableContainerRef: React.RefObject } function TableBody({ table, tableContainerRef }: TableBodyProps) { const { rows } = table.getRowModel() // Important: Keep the row virtualizer in the lowest component possible to avoid unnecessary re-renders. const rowVirtualizer = useVirtualizer({ count: rows.length, 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 measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? (element) => element.getBoundingClientRect().height : undefined, overscan: 5, }) useEffect(() => { rowVirtualizer.measure() }, []) return ( {rowVirtualizer.getVirtualItems().map((virtualRow) => { const row = rows[virtualRow.index] return ( ) })} ) } interface TableBodyRowProps { row: Row virtualRow: VirtualItem rowVirtualizer: Virtualizer table: ReactTable } function TableBodyRow({ row, virtualRow, rowVirtualizer, table, }: TableBodyRowProps) { return ( rowVirtualizer.measureElement(node)} // measure dynamic row height key={row.id} style={{ display: 'flex', position: 'absolute', transform: `translateY(${virtualRow.start}px)`, // this should always be a `style` as it changes on scroll width: '100%', }} > {row.getAllCells().map((cell) => { return ( ) })} ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/virtualized-rows/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: number firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' createdAt: Date } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (index: number): Person => { return { id: index + 1, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(d), } }) } return makeDataLevel() } ================================================ FILE: examples/react/virtualized-rows/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/virtualized-rows/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/virtualized-rows-experimental/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/virtualized-rows-experimental/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/virtualized-rows-experimental/index.html ================================================ Vite App
================================================ FILE: examples/react/virtualized-rows-experimental/package.json ================================================ { "name": "tanstack-table-example-virtualized-rows-experimental", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-table": "^9.0.0-alpha.19", "@tanstack/react-virtual": "^3.13.18", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/virtualized-rows-experimental/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border-collapse: collapse; border-spacing: 0; font-family: arial, sans-serif; table-layout: fixed; } thead { background: lightgray; } tr { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } td { padding: 6px; } .container { border: 1px solid lightgray; margin: 1rem auto; } .app { margin: 1rem auto; text-align: center; } ================================================ FILE: examples/react/virtualized-rows-experimental/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { FlexRender, columnSizingFeature, createSortedRowModel, rowSortingFeature, sortFns, useTable, } from '@tanstack/react-table' import { useVirtualizer } from '@tanstack/react-virtual' import { makeData } from './makeData' import type { ColumnDef, Row, Table } from '@tanstack/react-table' import type { Virtualizer } from '@tanstack/react-virtual' import type { Person } from './makeData' import './index.css' const _features = { columnSizingFeature, rowSortingFeature, } // This is a dynamic row height example, which is more complicated, but allows for a more realistic table. // See https://tanstack.com/virtual/v3/docs/examples/react/table for a simpler fixed row height example. function App() { const columns = React.useMemo>>( () => [ { accessorKey: 'id', header: 'ID', size: 60, }, { accessorKey: 'firstName', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, }, { accessorKey: 'age', header: () => 'Age', size: 50, }, { accessorKey: 'visits', header: () => Visits, size: 50, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', size: 80, }, { accessorKey: 'createdAt', header: 'Created At', cell: (info) => info.getValue().toLocaleString(), size: 250, }, ], [], ) const [data, _setData] = React.useState(() => makeData(50_000)) const refreshData = React.useCallback(() => { _setData(makeData(50_000)) }, []) // refresh data every 5 seconds React.useEffect(() => { const interval = setInterval(() => { refreshData() }, 5000) return () => clearInterval(interval) }, [refreshData]) console.log('data', data[0].firstName) const table = useTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns) }, columns, data, debugTable: true, }) // The virtualizer needs to know the scrollable container element const tableContainerRef = React.useRef(null) // All important CSS styles are included as inline styles for this example. This is not recommended for your code. return (
{process.env.NODE_ENV === 'development' ? (

Notice: You are currently running React in development mode. Virtualized rendering performance will be slightly degraded until this application is built for production.

) : null} ({data.length} rows)
({ sorting: state.sorting })}> {() => ( // Even though we're still using sematic table tags, we must use CSS grid and flexbox for dynamic row heights {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))}
{{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
) } interface TableBodyWrapperProps { table: Table tableContainerRef: React.RefObject } function TableBodyWrapper({ table, tableContainerRef }: TableBodyWrapperProps) { const rowRefsMap = React.useRef>(new Map()) const { rows } = table.getRowModel() const rowVirtualizer = useVirtualizer({ count: rows.length, 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 measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? (element) => element.getBoundingClientRect().height : undefined, overscan: 5, onChange: (instance) => { // requestAnimationFrame(() => { instance.getVirtualItems().forEach((virtualRow) => { const rowRef = rowRefsMap.current.get(virtualRow.index) if (!rowRef) return rowRef.style.transform = `translateY(${virtualRow.start}px)` }) // }) }, }) React.useLayoutEffect(() => { rowVirtualizer.measure() }, [table.store.state]) return ( ) } interface TableBodyProps { table: Table rowVirtualizer: Virtualizer rowRefsMap: React.MutableRefObject> } function TableBody({ rowVirtualizer, table, rowRefsMap }: TableBodyProps) { const { rows } = table.getRowModel() const virtualRowIndexes = rowVirtualizer.getVirtualIndexes() return ( {virtualRowIndexes.map((virtualRowIndex) => { const row = rows[virtualRowIndex] return ( ) })} ) } interface TableBodyRowProps { row: Row rowRefsMap: React.MutableRefObject> rowVirtualizer: Virtualizer virtualRowIndex: number } function TableBodyRow({ row, rowRefsMap, rowVirtualizer, virtualRowIndex, }: TableBodyRowProps) { return ( { if (node && typeof virtualRowIndex !== 'undefined') { rowVirtualizer.measureElement(node) // measure dynamic row height rowRefsMap.current.set(virtualRowIndex, node) // store ref for virtualizer to apply scrolling transforms } }} key={row.id} style={{ display: 'flex', position: 'absolute', width: '100%', }} > {row.getAllCells().map((cell) => { return ( ) })} ) } // test out when rows don't re-render at all (future TanStack Virtual release can make this unnecessary) const TableBodyRowMemo = React.memo( TableBodyRow, (_prev, next) => next.rowVirtualizer.isScrolling, ) as typeof TableBodyRow const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( // , // , ) ================================================ FILE: examples/react/virtualized-rows-experimental/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: number firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' createdAt: Date } const range = (len: number) => { const arr: number[] = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (index: number): Person => { return { id: index + 1, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0]!, } } export function makeData(...lens: number[]) { const makeDataLevel = (depth = 0): Person[] => { const len = lens[depth]! return range(len).map((d): Person => { return { ...newPerson(d), } }) } return makeDataLevel() } ================================================ FILE: examples/react/virtualized-rows-experimental/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/virtualized-rows-experimental/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/with-tanstack-form/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/with-tanstack-form/README.md ================================================ # Editable Data with TanStack Form This example demonstrates integrating TanStack Form with TanStack Table for editable data management. ## Features - **Form-based editing**: Each table cell is a form field managed by TanStack Form - **Array field management**: Table data is stored as a form array with indexed field access - **Validation**: Per-field Zod validation with error display - **Form state tracking**: Dirty/pristine and valid/invalid indicators - **Pagination & Filtering**: Full table features work with form-managed data ## Key Patterns - `useAppForm` with `defaultValues: { data: [...] }` for array data - `form.AppField name="data[${row.index}].fieldName"` for cell editing - `table.Subscribe` for reactive table state - `table.FlexRender` for cell rendering ## Running the Example ```bash pnpm install pnpm dev ``` ================================================ FILE: examples/react/with-tanstack-form/index.html ================================================ Vite App
================================================ FILE: examples/react/with-tanstack-form/package.json ================================================ { "name": "tanstack-table-example-with-tanstack-form", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-form": "^1.28.0", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4", "zod": "^4.3.6" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/with-tanstack-form/src/form.tsx ================================================ import { createFormHook, createFormHookContexts, useStore, } from '@tanstack/react-form' // Create form and field contexts export const { fieldContext, useFieldContext, formContext, useFormContext } = createFormHookContexts() // TextField component for string inputs function TextField() { const field = useFieldContext() const errors = useStore(field.store, (state) => state.meta.errors) return (
field.handleChange(e.target.value)} onBlur={field.handleBlur} /> {errors.length > 0 && (
{errors.join(', ')}
)}
) } // NumberField component for numeric inputs function NumberField() { const field = useFieldContext() const errors = useStore(field.store, (state) => state.meta.errors) return (
field.handleChange(Number(e.target.value))} onBlur={field.handleBlur} /> {errors.length > 0 && (
{errors.join(', ')}
)}
) } // SelectField component for status dropdown const statusOptions = ['relationship', 'complicated', 'single'] as const function SelectField() { const field = useFieldContext() const errors = useStore(field.store, (state) => state.meta.errors) return (
{errors.length > 0 && (
{errors.join(', ')}
)}
) } // SubmitButton component that shows form state function SubmitButton({ label }: { label: string }) { const form = useFormContext() return ( [state.isSubmitting, state.canSubmit]}> {([isSubmitting, canSubmit]) => ( )} ) } // FormStateIndicator component to show dirty/valid state function FormStateIndicator() { const form = useFormContext() return ( ({ isDirty: state.isDirty, isValid: state.isValid, errorMap: state.errorMap, })} > {({ isDirty, isValid, errorMap }) => (
{isDirty ? '● Modified' : '○ Pristine'} {isValid ? '✓ Valid' : '✗ Invalid'} {Object.keys(errorMap).length > 0 && ( Errors: {JSON.stringify(errorMap)} )}
)}
) } // Create the form hook with all components export const { useAppForm, withForm } = createFormHook({ fieldComponents: { TextField, NumberField, SelectField, }, formComponents: { SubmitButton, FormStateIndicator, }, fieldContext, formContext, }) ================================================ FILE: examples/react/with-tanstack-form/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/with-tanstack-form/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { columnFilteringFeature, createColumnHelper, createFilteredRowModel, createPaginatedRowModel, filterFns, rowPaginationFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { useStore } from '@tanstack/react-form' import { z } from 'zod' import { makeData } from './makeData' import { useAppForm } from './form' import type { Column, Table } from '@tanstack/react-table' import type { Person } from './makeData' import './index.css' // Define table features const _features = tableFeatures({ rowPaginationFeature, columnFilteringFeature, }) // Create column helper with features and Person type const columnHelper = createColumnHelper() // Zod validation schema for a person const personSchema = z.object({ firstName: z.string().min(1, 'First name is required'), lastName: z.string().min(1, 'Last name is required'), age: z .number() .min(0, 'Age must be positive') .max(150, 'Age must be realistic'), visits: z.number().min(0, 'Visits must be positive'), progress: z .number() .min(0, 'Progress must be 0-100') .max(100, 'Progress must be 0-100'), status: z.enum(['relationship', 'complicated', 'single']), }) // Form data schema const formSchema = z.object({ data: z.array(personSchema), }) type FormData = z.infer function App() { // Initialize form with makeData const form = useAppForm({ defaultValues: { data: makeData(100), } as FormData, onSubmit: ({ value }) => { alert( `Submitted ${value.data.length} records!\n\nFirst record: ${JSON.stringify(value.data[0], null, 2)}`, ) }, validators: { onChange: formSchema, }, }) // Create columns with form fields for editing const columns = React.useMemo( () => columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', footer: (props) => props.column.id, cell: ({ row }) => ( {(field) => } ), }), columnHelper.accessor('lastName', { header: () => Last Name, footer: (props) => props.column.id, cell: ({ row }) => ( {(field) => } ), }), columnHelper.accessor('age', { header: () => 'Age', footer: (props) => props.column.id, cell: ({ row }) => ( {(field) => } ), }), columnHelper.accessor('visits', { header: () => Visits, footer: (props) => props.column.id, cell: ({ row }) => ( {(field) => } ), }), columnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, cell: ({ row }) => ( {(field) => } ), }), columnHelper.accessor('progress', { header: 'Profile Progress', footer: (props) => props.column.id, cell: ({ row }) => ( {(field) => } ), }), ]), [form], ) // Subscribe only to array length to trigger re-renders when rows are added/removed // This avoids infinite loops from subscribing to the entire data array const dataLength = useStore(form.store, (state) => state.values.data.length) void dataLength // Used to trigger re-renders, value not needed // Create table using form state as data source // The table gets fresh data on each render, cells handle their own field state const table = useTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, columns, data: form.state.values.data, debugTable: true, }) const refreshData = () => { form.reset({ data: makeData(100) }) } const addRow = () => { form.pushFieldValue('data', { firstName: '', lastName: '', age: 0, visits: 0, progress: 0, status: 'single', }) } return (
{ e.preventDefault() e.stopPropagation() form.handleSubmit() }} > {/* Form state indicators */}
{/* Table */} ({ pagination: state.pagination, columnFilters: state.columnFilters, })} > {(tableState) => ( <>
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : (
{header.column.getCanFilter() ? (
) : null}
)}
{/* Pagination controls */}
Page
{tableState.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
)}
) } function Filter({ column, table, }: { column: Column table: Table }) { const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id) const columnFilterValue = column.getFilterValue() return typeof firstValue === 'number' ? (
column.setFilterValue((old: [number, number]) => [ e.target.value, old[1], ]) } placeholder={`Min`} className="w-24 border shadow rounded" /> column.setFilterValue((old: [number, number]) => [ old[0], e.target.value, ]) } placeholder={`Max`} className="w-24 border shadow rounded" />
) : ( column.setFilterValue(e.target.value)} placeholder={`Search...`} className="w-36 border shadow rounded" /> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/with-tanstack-form/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/react/with-tanstack-form/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/with-tanstack-form/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/with-tanstack-query/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/with-tanstack-query/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/with-tanstack-query/index.html ================================================ Vite App
================================================ FILE: examples/react/with-tanstack-query/package.json ================================================ { "name": "tanstack-table-example-with-tanstack-query", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/react-query": "^5.90.20", "@tanstack/react-store": "^0.9.2", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/with-tanstack-query/src/fetchData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } const data = makeData(10000) export async function fetchData(options: { pageIndex: number pageSize: number }) { // Simulate some network latency await new Promise((r) => setTimeout(r, 500)) return { rows: data.slice( options.pageIndex * options.pageSize, (options.pageIndex + 1) * options.pageSize, ), pageCount: Math.ceil(data.length / options.pageSize), rowCount: data.length, } } ================================================ FILE: examples/react/with-tanstack-query/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } button:disabled { opacity: 0.5; } ================================================ FILE: examples/react/with-tanstack-query/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import { QueryClient, QueryClientProvider, keepPreviousData, useQuery, } from '@tanstack/react-query' import { createStore, useStore } from '@tanstack/react-store' import './index.css' import { createColumnHelper, getInitialTableState, rowPaginationFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { fetchData } from './fetchData' import type { Person } from './fetchData' const queryClient = new QueryClient() const _features = tableFeatures({ rowPaginationFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { header: 'Last Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: 'Age', }), columnHelper.accessor('visits', { header: 'Visits', }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', }), ]) const myTableStore = createStore( getInitialTableState(_features, { pagination: { pageIndex: 0, pageSize: 10 }, }), ) function App() { const rerender = React.useReducer(() => ({}), {})[1] // Subscribe to store state for reactive updates const state = useStore(myTableStore, (state) => state) const dataQuery = useQuery({ queryKey: ['data', state.pagination], queryFn: () => fetchData(state.pagination), placeholderData: keepPreviousData, // don't have 0 rows flash while changing pages/loading next page }) const defaultData = React.useMemo(() => [], []) const table = useTable({ _features, _rowModels: {}, columns, data: dataQuery.data?.rows ?? defaultData, rowCount: dataQuery.data?.rowCount, store: myTableStore, manualPagination: true, // we're doing manual "server-side" pagination debugTable: true, }) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( ))} ))} {table.getRowModel().rows.map((row) => ( {row.getAllCells().map((cell) => ( ))} ))}
{header.isPlaceholder ? null : ( )}
Page
{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" /> {dataQuery.isFetching ? 'Loading...' : null}
Showing {table.getRowModel().rows.length.toLocaleString()} of{' '} {dataQuery.data?.rowCount.toLocaleString()} Rows
{JSON.stringify(state, null, 2)}
) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/with-tanstack-query/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/with-tanstack-query/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), ], }) ================================================ FILE: examples/react/with-tanstack-router/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/react/with-tanstack-router/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/react/with-tanstack-router/index.html ================================================ Vite App
================================================ FILE: examples/react/with-tanstack-router/package.json ================================================ { "name": "tanstack-table-example-with-tanstack-router", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite", "lint": "eslint ./src", "test:types": "tsc" }, "dependencies": { "@tanstack/react-query": "^5.90.20", "@tanstack/react-router": "^1.157.16", "@tanstack/react-table": "^9.0.0-alpha.19", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@tanstack/router-vite-plugin": "^1.157.16", "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/react/with-tanstack-router/src/App.tsx ================================================ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { RouterProvider, createRouter } from '@tanstack/react-router' import { routeTree } from './routeTree.gen' const router = createRouter({ routeTree }) declare module '@tanstack/react-router' { interface Register { router: typeof router } } const queryClient = new QueryClient() export default function App() { return ( ) } ================================================ FILE: examples/react/with-tanstack-router/src/api/data.json ================================================ [ { "id": 1, "firstName": "Luz", "lastName": "Flatley", "age": 13 }, { "id": 2, "firstName": "Buford", "lastName": "Zemlak", "age": 10 }, { "id": 3, "firstName": "Ivah", "lastName": "Schoen", "age": 7 }, { "id": 4, "firstName": "Rowena", "lastName": "Green", "age": 5 }, { "id": 5, "firstName": "Laurel", "lastName": "Boehm", "age": 30 }, { "id": 6, "firstName": "Markus", "lastName": "Moore", "age": 29 }, { "id": 7, "firstName": "Anne", "lastName": "Hegmann", "age": 33 }, { "id": 8, "firstName": "Jefferey", "lastName": "Rodriguez", "age": 25 }, { "id": 9, "firstName": "Albertha", "lastName": "Reilly", "age": 7 }, { "id": 10, "firstName": "Adalberto", "lastName": "Von-Keeling", "age": 20 }, { "id": 11, "firstName": "Junius", "lastName": "Robel", "age": 31 }, { "id": 12, "firstName": "Haskell", "lastName": "Armstrong-Smith", "age": 22 }, { "id": 13, "firstName": "Kariane", "lastName": "Wolff", "age": 13 }, { "id": 14, "firstName": "Devon", "lastName": "Schoen", "age": 3 }, { "id": 15, "firstName": "Rocio", "lastName": "Macejkovic", "age": 34 }, { "id": 16, "firstName": "Brennan", "lastName": "King", "age": 15 }, { "id": 17, "firstName": "Zella", "lastName": "Blick", "age": 19 }, { "id": 18, "firstName": "Columbus", "lastName": "Hessel", "age": 34 }, { "id": 19, "firstName": "Maiya", "lastName": "Boyle-Daugherty", "age": 32 }, { "id": 20, "firstName": "Kennedy", "lastName": "Effertz", "age": 14 }, { "id": 21, "firstName": "Walker", "lastName": "Satterfield-Lemke", "age": 6 }, { "id": 22, "firstName": "Barney", "lastName": "Homenick", "age": 27 }, { "id": 23, "firstName": "Eliezer", "lastName": "Bahringer", "age": 28 }, { "id": 24, "firstName": "Flossie", "lastName": "Adams", "age": 35 }, { "id": 25, "firstName": "Miguel", "lastName": "Kautzer", "age": 38 }, { "id": 26, "firstName": "Gunner", "lastName": "Ritchie", "age": 22 }, { "id": 27, "firstName": "Domenica", "lastName": "Boyer", "age": 24 }, { "id": 28, "firstName": "Valentine", "lastName": "Zemlak", "age": 21 }, { "id": 29, "firstName": "Ike", "lastName": "Grady", "age": 0 }, { "id": 30, "firstName": "Jalon", "lastName": "Kunze", "age": 37 }, { "id": 31, "firstName": "Laisha", "lastName": "Casper", "age": 26 }, { "id": 32, "firstName": "Jaren", "lastName": "Gutkowski", "age": 38 }, { "id": 33, "firstName": "Jeffery", "lastName": "King", "age": 14 }, { "id": 34, "firstName": "Gunner", "lastName": "Batz", "age": 1 }, { "id": 35, "firstName": "Reyes", "lastName": "Kiehn", "age": 19 }, { "id": 36, "firstName": "Miracle", "lastName": "Bergstrom", "age": 19 }, { "id": 37, "firstName": "Lempi", "lastName": "Towne", "age": 26 }, { "id": 38, "firstName": "Ignacio", "lastName": "Kutch", "age": 20 }, { "id": 39, "firstName": "Arthur", "lastName": "Doyle", "age": 18 }, { "id": 40, "firstName": "Julianne", "lastName": "Trantow", "age": 25 }, { "id": 41, "firstName": "Meredith", "lastName": "Waters", "age": 28 }, { "id": 42, "firstName": "Hilma", "lastName": "Stark-Kiehn", "age": 15 }, { "id": 43, "firstName": "Helena", "lastName": "Funk", "age": 20 }, { "id": 44, "firstName": "Buddy", "lastName": "Runte", "age": 20 }, { "id": 45, "firstName": "Wilton", "lastName": "Boyer", "age": 33 }, { "id": 46, "firstName": "Bailee", "lastName": "Deckow", "age": 34 }, { "id": 47, "firstName": "Rhett", "lastName": "Schuppe", "age": 36 }, { "id": 48, "firstName": "Florida", "lastName": "Hodkiewicz", "age": 3 }, { "id": 49, "firstName": "Edmond", "lastName": "Jones-Powlowski", "age": 33 }, { "id": 50, "firstName": "Winfield", "lastName": "Hoeger", "age": 20 }, { "id": 51, "firstName": "Jade", "lastName": "Dicki", "age": 19 }, { "id": 52, "firstName": "Lula", "lastName": "Huel", "age": 8 }, { "id": 53, "firstName": "Lane", "lastName": "Baumbach", "age": 28 }, { "id": 54, "firstName": "Garrett", "lastName": "Ratke", "age": 23 }, { "id": 55, "firstName": "Tierra", "lastName": "Grimes", "age": 14 }, { "id": 56, "firstName": "Jena", "lastName": "Ferry", "age": 40 }, { "id": 57, "firstName": "Elliot", "lastName": "Beahan", "age": 38 }, { "id": 58, "firstName": "Tanner", "lastName": "Moen", "age": 21 }, { "id": 59, "firstName": "Jarret", "lastName": "Von", "age": 15 }, { "id": 60, "firstName": "Ransom", "lastName": "Schowalter", "age": 22 }, { "id": 61, "firstName": "Patience", "lastName": "Lind", "age": 34 }, { "id": 62, "firstName": "Jessyca", "lastName": "Gorczany", "age": 35 }, { "id": 63, "firstName": "Anna", "lastName": "Ebert", "age": 32 }, { "id": 64, "firstName": "Fern", "lastName": "Jaskolski", "age": 13 }, { "id": 65, "firstName": "Ray", "lastName": "Reynolds", "age": 26 }, { "id": 66, "firstName": "Merle", "lastName": "Bashirian", "age": 6 }, { "id": 67, "firstName": "Eldora", "lastName": "Schuppe", "age": 16 }, { "id": 68, "firstName": "Josue", "lastName": "Weissnat", "age": 24 }, { "id": 69, "firstName": "Antoinette", "lastName": "Wintheiser", "age": 6 }, { "id": 70, "firstName": "Edgar", "lastName": "Swaniawski", "age": 18 }, { "id": 71, "firstName": "Eulalia", "lastName": "Cole", "age": 19 }, { "id": 72, "firstName": "Maximilian", "lastName": "Klocko", "age": 39 }, { "id": 73, "firstName": "Isabell", "lastName": "Grant", "age": 4 }, { "id": 74, "firstName": "Adella", "lastName": "Stokes", "age": 34 }, { "id": 75, "firstName": "Jerad", "lastName": "Lakin-Lang", "age": 28 }, { "id": 76, "firstName": "Blaze", "lastName": "McClure", "age": 29 }, { "id": 77, "firstName": "Darron", "lastName": "Littel", "age": 8 }, { "id": 78, "firstName": "Tre", "lastName": "Boehm", "age": 6 }, { "id": 79, "firstName": "Mikayla", "lastName": "Wilderman", "age": 33 }, { "id": 80, "firstName": "Lee", "lastName": "Parker", "age": 28 }, { "id": 81, "firstName": "Mckenzie", "lastName": "Tremblay-McClure", "age": 30 }, { "id": 82, "firstName": "Frankie", "lastName": "Marquardt", "age": 36 }, { "id": 83, "firstName": "Melany", "lastName": "Schamberger", "age": 9 }, { "id": 84, "firstName": "Gerald", "lastName": "Lynch", "age": 28 }, { "id": 85, "firstName": "Jaunita", "lastName": "Armstrong", "age": 0 }, { "id": 86, "firstName": "Ruthie", "lastName": "Bradtke", "age": 11 }, { "id": 87, "firstName": "Jennie", "lastName": "Douglas", "age": 26 }, { "id": 88, "firstName": "Ellen", "lastName": "Pacocha", "age": 20 }, { "id": 89, "firstName": "Gaston", "lastName": "Carroll", "age": 12 }, { "id": 90, "firstName": "Rowan", "lastName": "Heller", "age": 20 }, { "id": 91, "firstName": "Kamren", "lastName": "Mitchell", "age": 4 }, { "id": 92, "firstName": "Kody", "lastName": "Kiehn", "age": 2 }, { "id": 93, "firstName": "Alexie", "lastName": "Kshlerin", "age": 24 }, { "id": 94, "firstName": "Ariel", "lastName": "Stanton", "age": 8 }, { "id": 95, "firstName": "Assunta", "lastName": "Kilback", "age": 39 }, { "id": 96, "firstName": "Raymundo", "lastName": "Russel", "age": 5 }, { "id": 97, "firstName": "Jaquelin", "lastName": "Grimes", "age": 2 }, { "id": 98, "firstName": "Nola", "lastName": "Wolff", "age": 0 }, { "id": 99, "firstName": "Macy", "lastName": "Heidenreich", "age": 13 }, { "id": 100, "firstName": "Sam", "lastName": "Hintz", "age": 26 }, { "id": 101, "firstName": "Nya", "lastName": "Dietrich", "age": 22 }, { "id": 102, "firstName": "Julio", "lastName": "Ruecker", "age": 18 }, { "id": 103, "firstName": "Carter", "lastName": "Dooley", "age": 2 }, { "id": 104, "firstName": "Don", "lastName": "Herman", "age": 9 }, { "id": 105, "firstName": "Wyman", "lastName": "Bednar", "age": 32 }, { "id": 106, "firstName": "Elise", "lastName": "Metz", "age": 1 }, { "id": 107, "firstName": "Rashawn", "lastName": "Bednar", "age": 0 }, { "id": 108, "firstName": "Terrance", "lastName": "Hickle", "age": 20 }, { "id": 109, "firstName": "Savanna", "lastName": "Bogan", "age": 5 }, { "id": 110, "firstName": "Giovanna", "lastName": "Dare", "age": 2 }, { "id": 111, "firstName": "Yvonne", "lastName": "Schuster", "age": 29 }, { "id": 112, "firstName": "Alize", "lastName": "Cassin", "age": 19 }, { "id": 113, "firstName": "Rhiannon", "lastName": "Thompson", "age": 34 }, { "id": 114, "firstName": "Olin", "lastName": "Schulist", "age": 10 }, { "id": 115, "firstName": "Savannah", "lastName": "Simonis", "age": 1 }, { "id": 116, "firstName": "Calista", "lastName": "Pacocha", "age": 12 }, { "id": 117, "firstName": "Felicia", "lastName": "Wolf", "age": 8 }, { "id": 118, "firstName": "Werner", "lastName": "Swift", "age": 22 }, { "id": 119, "firstName": "John", "lastName": "Lynch", "age": 6 }, { "id": 120, "firstName": "Joaquin", "lastName": "Hegmann", "age": 30 }, { "id": 121, "firstName": "Citlalli", "lastName": "Bernier", "age": 23 }, { "id": 122, "firstName": "Carrie", "lastName": "Waters", "age": 14 }, { "id": 123, "firstName": "Alexanne", "lastName": "Rutherford", "age": 8 }, { "id": 124, "firstName": "Evelyn", "lastName": "Halvorson", "age": 3 }, { "id": 125, "firstName": "Janelle", "lastName": "Blanda", "age": 36 }, { "id": 126, "firstName": "Amiya", "lastName": "Kihn", "age": 22 }, { "id": 127, "firstName": "Hilbert", "lastName": "Upton", "age": 39 }, { "id": 128, "firstName": "Janick", "lastName": "Pollich", "age": 37 }, { "id": 129, "firstName": "Eleazar", "lastName": "Toy", "age": 13 }, { "id": 130, "firstName": "Josiah", "lastName": "Doyle", "age": 22 }, { "id": 131, "firstName": "Kelley", "lastName": "Armstrong", "age": 2 }, { "id": 132, "firstName": "Shawn", "lastName": "Wehner-Kassulke", "age": 18 }, { "id": 133, "firstName": "Rosemarie", "lastName": "Homenick", "age": 29 }, { "id": 134, "firstName": "Tressie", "lastName": "Glover", "age": 8 }, { "id": 135, "firstName": "Enos", "lastName": "Hoeger", "age": 5 }, { "id": 136, "firstName": "Nels", "lastName": "Shanahan", "age": 24 }, { "id": 137, "firstName": "Margie", "lastName": "Rogahn", "age": 13 }, { "id": 138, "firstName": "Kayden", "lastName": "Daniel", "age": 21 }, { "id": 139, "firstName": "Darian", "lastName": "O'Hara", "age": 6 }, { "id": 140, "firstName": "Duncan", "lastName": "Kovacek", "age": 18 }, { "id": 141, "firstName": "Arnulfo", "lastName": "Shields", "age": 23 }, { "id": 142, "firstName": "Bryon", "lastName": "Reynolds", "age": 22 }, { "id": 143, "firstName": "Kayleigh", "lastName": "Barton", "age": 14 }, { "id": 144, "firstName": "Jolie", "lastName": "Heidenreich", "age": 30 }, { "id": 145, "firstName": "Angelina", "lastName": "Lehner", "age": 1 }, { "id": 146, "firstName": "Luz", "lastName": "Walker-Dach", "age": 24 }, { "id": 147, "firstName": "Annamae", "lastName": "Yundt", "age": 21 }, { "id": 148, "firstName": "Lois", "lastName": "Schiller-Gibson", "age": 3 }, { "id": 149, "firstName": "Macey", "lastName": "Green", "age": 37 }, { "id": 150, "firstName": "Luciano", "lastName": "Walter", "age": 0 }, { "id": 151, "firstName": "Eva", "lastName": "Fadel", "age": 16 }, { "id": 152, "firstName": "Dawn", "lastName": "Morissette", "age": 35 }, { "id": 153, "firstName": "Thelma", "lastName": "Denesik", "age": 17 }, { "id": 154, "firstName": "Clark", "lastName": "Roberts", "age": 3 }, { "id": 155, "firstName": "Otto", "lastName": "Keeling", "age": 28 }, { "id": 156, "firstName": "Michale", "lastName": "Mohr", "age": 26 }, { "id": 157, "firstName": "Eldridge", "lastName": "Bartoletti", "age": 2 }, { "id": 158, "firstName": "Luciano", "lastName": "Casper", "age": 1 }, { "id": 159, "firstName": "Arden", "lastName": "Hills", "age": 1 }, { "id": 160, "firstName": "Julia", "lastName": "Ullrich", "age": 36 }, { "id": 161, "firstName": "Geraldine", "lastName": "Schamberger", "age": 27 }, { "id": 162, "firstName": "Emily", "lastName": "Pacocha", "age": 9 }, { "id": 163, "firstName": "Wilburn", "lastName": "Bogisich", "age": 29 }, { "id": 164, "firstName": "Krystina", "lastName": "Dicki", "age": 12 }, { "id": 165, "firstName": "Pasquale", "lastName": "Douglas", "age": 21 }, { "id": 166, "firstName": "Horace", "lastName": "Jacobson", "age": 21 }, { "id": 167, "firstName": "Adelle", "lastName": "Schulist", "age": 16 }, { "id": 168, "firstName": "Monserrate", "lastName": "Skiles", "age": 3 }, { "id": 169, "firstName": "Salvador", "lastName": "Weimann", "age": 17 }, { "id": 170, "firstName": "Marcelle", "lastName": "Runte", "age": 5 }, { "id": 171, "firstName": "Sylvia", "lastName": "Cole", "age": 8 }, { "id": 172, "firstName": "Ressie", "lastName": "Hessel", "age": 31 }, { "id": 173, "firstName": "Kim", "lastName": "Kutch", "age": 19 }, { "id": 174, "firstName": "Loyal", "lastName": "Schumm", "age": 3 }, { "id": 175, "firstName": "Curt", "lastName": "Langosh", "age": 22 }, { "id": 176, "firstName": "Lupe", "lastName": "Beier", "age": 24 }, { "id": 177, "firstName": "Estell", "lastName": "Emmerich", "age": 26 }, { "id": 178, "firstName": "Katarina", "lastName": "Jast", "age": 11 }, { "id": 179, "firstName": "Mollie", "lastName": "Emard", "age": 32 }, { "id": 180, "firstName": "Santa", "lastName": "Pollich", "age": 6 }, { "id": 181, "firstName": "Art", "lastName": "O'Conner", "age": 20 }, { "id": 182, "firstName": "Reanna", "lastName": "Mayert", "age": 18 }, { "id": 183, "firstName": "Ellie", "lastName": "Mayert", "age": 8 }, { "id": 184, "firstName": "Keyon", "lastName": "Connelly", "age": 9 }, { "id": 185, "firstName": "Alvina", "lastName": "Padberg", "age": 3 }, { "id": 186, "firstName": "Kane", "lastName": "Stehr", "age": 6 }, { "id": 187, "firstName": "Jeffrey", "lastName": "Baumbach", "age": 13 }, { "id": 188, "firstName": "Angelo", "lastName": "Koelpin", "age": 17 }, { "id": 189, "firstName": "Nicola", "lastName": "Nader", "age": 17 }, { "id": 190, "firstName": "Edwina", "lastName": "Bernhard", "age": 35 }, { "id": 191, "firstName": "Francisco", "lastName": "Cartwright", "age": 25 }, { "id": 192, "firstName": "Sigrid", "lastName": "Johns", "age": 28 }, { "id": 193, "firstName": "Columbus", "lastName": "Ortiz", "age": 16 }, { "id": 194, "firstName": "Bell", "lastName": "Beatty", "age": 31 }, { "id": 195, "firstName": "Austyn", "lastName": "Feeney", "age": 21 }, { "id": 196, "firstName": "Jessika", "lastName": "Brakus", "age": 30 }, { "id": 197, "firstName": "Bernita", "lastName": "McKenzie", "age": 11 }, { "id": 198, "firstName": "Jerry", "lastName": "Marks", "age": 12 }, { "id": 199, "firstName": "Annamae", "lastName": "Pfeffer", "age": 36 }, { "id": 200, "firstName": "Leopold", "lastName": "Harris", "age": 3 }, { "id": 201, "firstName": "Maximillia", "lastName": "Schiller", "age": 9 }, { "id": 202, "firstName": "Joaquin", "lastName": "Torphy", "age": 28 }, { "id": 203, "firstName": "Minnie", "lastName": "Doyle-Stracke", "age": 25 }, { "id": 204, "firstName": "Johan", "lastName": "Corkery", "age": 35 }, { "id": 205, "firstName": "Gabe", "lastName": "Stark", "age": 29 }, { "id": 206, "firstName": "Lily", "lastName": "McLaughlin", "age": 17 }, { "id": 207, "firstName": "Aubree", "lastName": "Quigley", "age": 25 }, { "id": 208, "firstName": "Marshall", "lastName": "Howe", "age": 16 }, { "id": 209, "firstName": "Fanny", "lastName": "Flatley", "age": 20 }, { "id": 210, "firstName": "Kelton", "lastName": "Simonis", "age": 38 }, { "id": 211, "firstName": "Dolores", "lastName": "Reilly", "age": 8 }, { "id": 212, "firstName": "Filomena", "lastName": "Raynor", "age": 6 }, { "id": 213, "firstName": "Jaden", "lastName": "Jones", "age": 37 }, { "id": 214, "firstName": "Alexanne", "lastName": "Macejkovic", "age": 31 }, { "id": 215, "firstName": "Vilma", "lastName": "Herman", "age": 21 }, { "id": 216, "firstName": "Oswaldo", "lastName": "Grant", "age": 10 }, { "id": 217, "firstName": "Lexus", "lastName": "Gusikowski", "age": 28 }, { "id": 218, "firstName": "Isaias", "lastName": "Doyle", "age": 15 }, { "id": 219, "firstName": "Hosea", "lastName": "Hayes", "age": 33 }, { "id": 220, "firstName": "Santino", "lastName": "Schoen", "age": 23 }, { "id": 221, "firstName": "Furman", "lastName": "Farrell", "age": 31 }, { "id": 222, "firstName": "Rebeca", "lastName": "Hammes", "age": 37 }, { "id": 223, "firstName": "Alycia", "lastName": "Emmerich", "age": 2 }, { "id": 224, "firstName": "Camila", "lastName": "Feeney", "age": 29 }, { "id": 225, "firstName": "Haylee", "lastName": "Smith", "age": 33 }, { "id": 226, "firstName": "Margaretta", "lastName": "Hamill", "age": 22 }, { "id": 227, "firstName": "Frederic", "lastName": "Heaney", "age": 20 }, { "id": 228, "firstName": "Fanny", "lastName": "Goodwin", "age": 23 }, { "id": 229, "firstName": "Akeem", "lastName": "Sipes", "age": 32 }, { "id": 230, "firstName": "Isac", "lastName": "Mosciski-Ruecker", "age": 15 }, { "id": 231, "firstName": "Annie", "lastName": "Corwin", "age": 36 }, { "id": 232, "firstName": "Zion", "lastName": "Bernhard", "age": 22 }, { "id": 233, "firstName": "Joe", "lastName": "Rippin", "age": 35 }, { "id": 234, "firstName": "Libbie", "lastName": "Considine", "age": 37 }, { "id": 235, "firstName": "Eldridge", "lastName": "Ortiz", "age": 21 }, { "id": 236, "firstName": "Julius", "lastName": "Murazik", "age": 19 }, { "id": 237, "firstName": "Freida", "lastName": "Block", "age": 11 }, { "id": 238, "firstName": "Winfield", "lastName": "Pfeffer", "age": 21 }, { "id": 239, "firstName": "Armando", "lastName": "Krajcik", "age": 30 }, { "id": 240, "firstName": "Aubree", "lastName": "Waters", "age": 19 }, { "id": 241, "firstName": "Sebastian", "lastName": "Reilly", "age": 29 }, { "id": 242, "firstName": "Dillon", "lastName": "Littel", "age": 5 }, { "id": 243, "firstName": "Danny", "lastName": "Hegmann", "age": 35 }, { "id": 244, "firstName": "Alexandra", "lastName": "Halvorson", "age": 9 }, { "id": 245, "firstName": "Esteban", "lastName": "Champlin", "age": 2 }, { "id": 246, "firstName": "Theo", "lastName": "Mann", "age": 40 }, { "id": 247, "firstName": "Justen", "lastName": "Bernhard", "age": 10 }, { "id": 248, "firstName": "Pinkie", "lastName": "Hessel", "age": 30 }, { "id": 249, "firstName": "Nicholaus", "lastName": "Ortiz", "age": 27 }, { "id": 250, "firstName": "Zechariah", "lastName": "Grady", "age": 29 }, { "id": 251, "firstName": "Newton", "lastName": "Quitzon", "age": 8 }, { "id": 252, "firstName": "Mary", "lastName": "Collins", "age": 27 }, { "id": 253, "firstName": "Jonathon", "lastName": "Boyer-Kozey", "age": 36 }, { "id": 254, "firstName": "Burley", "lastName": "Collier", "age": 5 }, { "id": 255, "firstName": "Brooklyn", "lastName": "Nikolaus", "age": 13 }, { "id": 256, "firstName": "Charlotte", "lastName": "Olson", "age": 0 }, { "id": 257, "firstName": "Pasquale", "lastName": "Jenkins", "age": 5 }, { "id": 258, "firstName": "Reagan", "lastName": "Gleichner", "age": 22 }, { "id": 259, "firstName": "Anais", "lastName": "Denesik", "age": 33 }, { "id": 260, "firstName": "Anastacio", "lastName": "Nikolaus", "age": 28 }, { "id": 261, "firstName": "Zachery", "lastName": "Bashirian", "age": 40 }, { "id": 262, "firstName": "Mario", "lastName": "Ernser", "age": 15 }, { "id": 263, "firstName": "Desiree", "lastName": "Smitham", "age": 17 }, { "id": 264, "firstName": "Meredith", "lastName": "Bartell-Romaguera", "age": 4 }, { "id": 265, "firstName": "Quentin", "lastName": "Stokes", "age": 37 }, { "id": 266, "firstName": "Kathleen", "lastName": "Huels", "age": 1 }, { "id": 267, "firstName": "Yoshiko", "lastName": "O'Conner", "age": 1 }, { "id": 268, "firstName": "Marley", "lastName": "Emard", "age": 5 }, { "id": 269, "firstName": "Mitchel", "lastName": "Leffler", "age": 11 }, { "id": 270, "firstName": "Myles", "lastName": "Borer", "age": 25 }, { "id": 271, "firstName": "Treva", "lastName": "Schultz", "age": 1 }, { "id": 272, "firstName": "Reginald", "lastName": "Kshlerin", "age": 18 }, { "id": 273, "firstName": "Ila", "lastName": "Koepp", "age": 26 }, { "id": 274, "firstName": "Lily", "lastName": "Quigley", "age": 24 }, { "id": 275, "firstName": "Arnulfo", "lastName": "Beatty", "age": 11 }, { "id": 276, "firstName": "Cierra", "lastName": "Jerde", "age": 18 }, { "id": 277, "firstName": "Rodolfo", "lastName": "Rath-Kuhn", "age": 39 }, { "id": 278, "firstName": "Gwen", "lastName": "Rowe", "age": 6 }, { "id": 279, "firstName": "Tre", "lastName": "Balistreri", "age": 5 }, { "id": 280, "firstName": "Kaci", "lastName": "Hettinger", "age": 7 }, { "id": 281, "firstName": "Marilyne", "lastName": "Stroman", "age": 5 }, { "id": 282, "firstName": "Orlando", "lastName": "Rodriguez-Beatty", "age": 4 }, { "id": 283, "firstName": "Trey", "lastName": "Schuster", "age": 16 }, { "id": 284, "firstName": "Jenifer", "lastName": "Romaguera", "age": 38 }, { "id": 285, "firstName": "Dexter", "lastName": "Williamson", "age": 33 }, { "id": 286, "firstName": "Dawn", "lastName": "Armstrong", "age": 20 }, { "id": 287, "firstName": "Elenora", "lastName": "Prosacco", "age": 24 }, { "id": 288, "firstName": "Margarete", "lastName": "Stokes", "age": 26 }, { "id": 289, "firstName": "Hank", "lastName": "Spencer", "age": 13 }, { "id": 290, "firstName": "Litzy", "lastName": "Miller", "age": 25 }, { "id": 291, "firstName": "Noelia", "lastName": "Becker", "age": 37 }, { "id": 292, "firstName": "Mac", "lastName": "Bartell", "age": 5 }, { "id": 293, "firstName": "Jadyn", "lastName": "Moen", "age": 38 }, { "id": 294, "firstName": "Garland", "lastName": "Hayes", "age": 31 }, { "id": 295, "firstName": "Myriam", "lastName": "Rutherford", "age": 29 }, { "id": 296, "firstName": "Alicia", "lastName": "Rosenbaum-Hudson", "age": 36 }, { "id": 297, "firstName": "Madge", "lastName": "Schmidt", "age": 22 }, { "id": 298, "firstName": "Destini", "lastName": "Littel", "age": 35 }, { "id": 299, "firstName": "Ellis", "lastName": "Brakus", "age": 30 }, { "id": 300, "firstName": "Yasmin", "lastName": "Renner-Baumbach", "age": 23 }, { "id": 301, "firstName": "Mittie", "lastName": "O'Hara", "age": 13 }, { "id": 302, "firstName": "Alejandra", "lastName": "Stehr", "age": 10 }, { "id": 303, "firstName": "Pat", "lastName": "Berge", "age": 24 }, { "id": 304, "firstName": "Dorris", "lastName": "Daugherty", "age": 17 }, { "id": 305, "firstName": "Ashtyn", "lastName": "Windler", "age": 28 }, { "id": 306, "firstName": "Guadalupe", "lastName": "Treutel", "age": 3 }, { "id": 307, "firstName": "Melody", "lastName": "Lemke", "age": 34 }, { "id": 308, "firstName": "Elmer", "lastName": "Moen", "age": 38 }, { "id": 309, "firstName": "Kobe", "lastName": "Bode", "age": 16 }, { "id": 310, "firstName": "Nicolette", "lastName": "Abshire", "age": 26 }, { "id": 311, "firstName": "Evans", "lastName": "Daniel", "age": 7 }, { "id": 312, "firstName": "Fabian", "lastName": "Farrell", "age": 4 }, { "id": 313, "firstName": "Kiel", "lastName": "Cormier", "age": 24 }, { "id": 314, "firstName": "Brandon", "lastName": "Pollich", "age": 5 }, { "id": 315, "firstName": "Gerry", "lastName": "Champlin", "age": 28 }, { "id": 316, "firstName": "Lavina", "lastName": "Lehner", "age": 21 }, { "id": 317, "firstName": "Keyshawn", "lastName": "Wolff", "age": 38 }, { "id": 318, "firstName": "Eileen", "lastName": "Kreiger", "age": 16 }, { "id": 319, "firstName": "Justine", "lastName": "King", "age": 26 }, { "id": 320, "firstName": "Earl", "lastName": "Wisozk", "age": 31 }, { "id": 321, "firstName": "Adrianna", "lastName": "Brown", "age": 9 }, { "id": 322, "firstName": "Susana", "lastName": "Gutkowski", "age": 6 }, { "id": 323, "firstName": "Ashtyn", "lastName": "Reynolds", "age": 5 }, { "id": 324, "firstName": "Brad", "lastName": "Murazik", "age": 14 }, { "id": 325, "firstName": "Zaria", "lastName": "Kreiger", "age": 7 }, { "id": 326, "firstName": "Ariane", "lastName": "Satterfield", "age": 31 }, { "id": 327, "firstName": "Terrell", "lastName": "Beer", "age": 32 }, { "id": 328, "firstName": "Keven", "lastName": "Moen", "age": 34 }, { "id": 329, "firstName": "Adella", "lastName": "Williamson", "age": 32 }, { "id": 330, "firstName": "Conrad", "lastName": "Heaney", "age": 19 }, { "id": 331, "firstName": "Alexis", "lastName": "Ratke", "age": 29 }, { "id": 332, "firstName": "Clotilde", "lastName": "Rohan", "age": 38 }, { "id": 333, "firstName": "Harry", "lastName": "Block", "age": 0 }, { "id": 334, "firstName": "Caroline", "lastName": "Wilkinson", "age": 34 }, { "id": 335, "firstName": "Theresia", "lastName": "Sawayn", "age": 9 }, { "id": 336, "firstName": "Cody", "lastName": "Erdman", "age": 32 }, { "id": 337, "firstName": "Newell", "lastName": "Cummerata", "age": 3 }, { "id": 338, "firstName": "Chauncey", "lastName": "Keebler", "age": 9 }, { "id": 339, "firstName": "Armando", "lastName": "Grant", "age": 3 }, { "id": 340, "firstName": "Yasmeen", "lastName": "Olson", "age": 24 }, { "id": 341, "firstName": "Vena", "lastName": "Dickinson", "age": 22 }, { "id": 342, "firstName": "Deron", "lastName": "Dicki", "age": 31 }, { "id": 343, "firstName": "Adriel", "lastName": "Zboncak", "age": 7 }, { "id": 344, "firstName": "Ona", "lastName": "Lindgren", "age": 35 }, { "id": 345, "firstName": "Dorothea", "lastName": "Bosco", "age": 40 }, { "id": 346, "firstName": "Graham", "lastName": "Spencer", "age": 34 }, { "id": 347, "firstName": "Amelie", "lastName": "Bogan", "age": 26 }, { "id": 348, "firstName": "Ayla", "lastName": "Willms", "age": 33 }, { "id": 349, "firstName": "Alfred", "lastName": "Pfannerstill", "age": 20 }, { "id": 350, "firstName": "Jodie", "lastName": "Armstrong", "age": 21 }, { "id": 351, "firstName": "Juliet", "lastName": "Lubowitz", "age": 2 }, { "id": 352, "firstName": "Bennett", "lastName": "Wiegand", "age": 0 }, { "id": 353, "firstName": "Shaylee", "lastName": "Ullrich", "age": 0 }, { "id": 354, "firstName": "Madeline", "lastName": "Reinger-Wilderman", "age": 0 }, { "id": 355, "firstName": "Violette", "lastName": "Mann", "age": 13 }, { "id": 356, "firstName": "Vincent", "lastName": "Armstrong", "age": 12 }, { "id": 357, "firstName": "Brycen", "lastName": "Runolfsson", "age": 4 }, { "id": 358, "firstName": "Aurelia", "lastName": "Trantow", "age": 10 }, { "id": 359, "firstName": "Velma", "lastName": "Crooks", "age": 38 }, { "id": 360, "firstName": "Germaine", "lastName": "Lemke", "age": 20 }, { "id": 361, "firstName": "Heaven", "lastName": "Kreiger", "age": 2 }, { "id": 362, "firstName": "Rosario", "lastName": "Beier", "age": 14 }, { "id": 363, "firstName": "Bell", "lastName": "Beahan", "age": 39 }, { "id": 364, "firstName": "Ashlee", "lastName": "Bailey", "age": 28 }, { "id": 365, "firstName": "Jan", "lastName": "Wyman", "age": 2 }, { "id": 366, "firstName": "River", "lastName": "King", "age": 34 }, { "id": 367, "firstName": "Jalen", "lastName": "Labadie", "age": 28 }, { "id": 368, "firstName": "Hertha", "lastName": "Klocko", "age": 29 }, { "id": 369, "firstName": "Jaiden", "lastName": "Braun", "age": 11 }, { "id": 370, "firstName": "Bailee", "lastName": "Ortiz", "age": 30 }, { "id": 371, "firstName": "Garth", "lastName": "Murray", "age": 30 }, { "id": 372, "firstName": "Alexandra", "lastName": "Satterfield", "age": 22 }, { "id": 373, "firstName": "Misty", "lastName": "Leffler", "age": 4 }, { "id": 374, "firstName": "Samara", "lastName": "Heller", "age": 13 }, { "id": 375, "firstName": "Claud", "lastName": "Keeling", "age": 15 }, { "id": 376, "firstName": "Kaley", "lastName": "Terry", "age": 38 }, { "id": 377, "firstName": "Juliana", "lastName": "Hagenes", "age": 0 }, { "id": 378, "firstName": "Madie", "lastName": "Stehr", "age": 40 }, { "id": 379, "firstName": "Enrico", "lastName": "Schulist", "age": 40 }, { "id": 380, "firstName": "Theodore", "lastName": "Dibbert", "age": 25 }, { "id": 381, "firstName": "Marty", "lastName": "Wunsch", "age": 29 }, { "id": 382, "firstName": "Ramona", "lastName": "Zulauf", "age": 6 }, { "id": 383, "firstName": "Willard", "lastName": "Stark", "age": 0 }, { "id": 384, "firstName": "Karine", "lastName": "Windler", "age": 29 }, { "id": 385, "firstName": "Geovanni", "lastName": "McDermott", "age": 35 }, { "id": 386, "firstName": "Jannie", "lastName": "Berge", "age": 4 }, { "id": 387, "firstName": "Alberto", "lastName": "Kulas", "age": 29 }, { "id": 388, "firstName": "Zora", "lastName": "Hackett", "age": 21 }, { "id": 389, "firstName": "Brandi", "lastName": "Reinger", "age": 0 }, { "id": 390, "firstName": "Ophelia", "lastName": "Maggio", "age": 36 }, { "id": 391, "firstName": "Ardith", "lastName": "Hegmann", "age": 14 }, { "id": 392, "firstName": "Maverick", "lastName": "Bergstrom", "age": 35 }, { "id": 393, "firstName": "Rosalia", "lastName": "Lesch", "age": 11 }, { "id": 394, "firstName": "Neil", "lastName": "Wiza", "age": 15 }, { "id": 395, "firstName": "Kenton", "lastName": "Bailey", "age": 29 }, { "id": 396, "firstName": "Elyse", "lastName": "McDermott", "age": 22 }, { "id": 397, "firstName": "Hilbert", "lastName": "Walsh", "age": 12 }, { "id": 398, "firstName": "Lennie", "lastName": "Simonis-Pollich", "age": 7 }, { "id": 399, "firstName": "Orville", "lastName": "Bashirian", "age": 35 }, { "id": 400, "firstName": "Einar", "lastName": "Rempel", "age": 4 }, { "id": 401, "firstName": "Destany", "lastName": "Boehm", "age": 13 }, { "id": 402, "firstName": "Baby", "lastName": "Witting", "age": 29 }, { "id": 403, "firstName": "Columbus", "lastName": "Berge", "age": 10 }, { "id": 404, "firstName": "Delphia", "lastName": "Ledner", "age": 18 }, { "id": 405, "firstName": "Margarett", "lastName": "Dach", "age": 0 }, { "id": 406, "firstName": "Henriette", "lastName": "Rath", "age": 16 }, { "id": 407, "firstName": "Coleman", "lastName": "VonRueden", "age": 13 }, { "id": 408, "firstName": "Kayley", "lastName": "Wuckert", "age": 6 }, { "id": 409, "firstName": "Rusty", "lastName": "Yundt", "age": 35 }, { "id": 410, "firstName": "Gabrielle", "lastName": "McClure", "age": 10 }, { "id": 411, "firstName": "Madie", "lastName": "Roberts", "age": 7 }, { "id": 412, "firstName": "Jarrell", "lastName": "Bayer", "age": 13 }, { "id": 413, "firstName": "Elva", "lastName": "Dickinson", "age": 24 }, { "id": 414, "firstName": "Icie", "lastName": "Ryan", "age": 7 }, { "id": 415, "firstName": "Katherine", "lastName": "Satterfield", "age": 8 }, { "id": 416, "firstName": "Merlin", "lastName": "Bergstrom", "age": 17 }, { "id": 417, "firstName": "Columbus", "lastName": "Auer", "age": 5 }, { "id": 418, "firstName": "Gregoria", "lastName": "Olson", "age": 6 }, { "id": 419, "firstName": "Laurine", "lastName": "Luettgen-O'Hara", "age": 38 }, { "id": 420, "firstName": "Monty", "lastName": "Emard", "age": 15 }, { "id": 421, "firstName": "Eli", "lastName": "Dibbert", "age": 1 }, { "id": 422, "firstName": "Kiana", "lastName": "Johnston", "age": 32 }, { "id": 423, "firstName": "Genevieve", "lastName": "Rau-Frami", "age": 15 }, { "id": 424, "firstName": "Agustin", "lastName": "Ferry", "age": 10 }, { "id": 425, "firstName": "Abel", "lastName": "Rosenbaum", "age": 14 }, { "id": 426, "firstName": "Ryan", "lastName": "Bradtke", "age": 2 }, { "id": 427, "firstName": "Max", "lastName": "Johnston", "age": 29 }, { "id": 428, "firstName": "Ethan", "lastName": "Breitenberg", "age": 16 }, { "id": 429, "firstName": "Caitlyn", "lastName": "Kovacek", "age": 24 }, { "id": 430, "firstName": "Keyon", "lastName": "Spencer", "age": 2 }, { "id": 431, "firstName": "Jaden", "lastName": "Hoppe", "age": 31 }, { "id": 432, "firstName": "Olaf", "lastName": "VonRueden", "age": 4 }, { "id": 433, "firstName": "Kariane", "lastName": "Ankunding", "age": 3 }, { "id": 434, "firstName": "Baron", "lastName": "Abernathy", "age": 37 }, { "id": 435, "firstName": "Abigail", "lastName": "Bins", "age": 29 }, { "id": 436, "firstName": "Parker", "lastName": "Hammes", "age": 20 }, { "id": 437, "firstName": "Summer", "lastName": "Kub", "age": 2 }, { "id": 438, "firstName": "Lucio", "lastName": "Powlowski", "age": 8 }, { "id": 439, "firstName": "Nicholaus", "lastName": "Harris", "age": 0 }, { "id": 440, "firstName": "Terry", "lastName": "Schamberger", "age": 2 }, { "id": 441, "firstName": "Joseph", "lastName": "McClure", "age": 1 }, { "id": 442, "firstName": "Rogelio", "lastName": "Goyette", "age": 33 }, { "id": 443, "firstName": "Vidal", "lastName": "Hauck", "age": 38 }, { "id": 444, "firstName": "Julie", "lastName": "Ebert", "age": 34 }, { "id": 445, "firstName": "Ashtyn", "lastName": "Hahn", "age": 11 }, { "id": 446, "firstName": "Orlando", "lastName": "Nicolas", "age": 21 }, { "id": 447, "firstName": "Mabelle", "lastName": "Krajcik", "age": 12 }, { "id": 448, "firstName": "Jerrod", "lastName": "Dicki", "age": 14 }, { "id": 449, "firstName": "Jeff", "lastName": "Stanton", "age": 9 }, { "id": 450, "firstName": "Alanis", "lastName": "Stoltenberg", "age": 17 }, { "id": 451, "firstName": "Nathaniel", "lastName": "Pagac", "age": 26 }, { "id": 452, "firstName": "Dillan", "lastName": "Nitzsche", "age": 12 }, { "id": 453, "firstName": "Alanis", "lastName": "Stoltenberg", "age": 28 }, { "id": 454, "firstName": "Casimer", "lastName": "Swaniawski", "age": 7 }, { "id": 455, "firstName": "Devin", "lastName": "Marvin", "age": 39 }, { "id": 456, "firstName": "Nikolas", "lastName": "McGlynn-Hyatt", "age": 34 }, { "id": 457, "firstName": "Montana", "lastName": "Christiansen", "age": 20 }, { "id": 458, "firstName": "Jevon", "lastName": "Hilpert", "age": 25 }, { "id": 459, "firstName": "Delia", "lastName": "White", "age": 26 }, { "id": 460, "firstName": "Alena", "lastName": "Koelpin", "age": 10 }, { "id": 461, "firstName": "Gracie", "lastName": "Lesch", "age": 12 }, { "id": 462, "firstName": "Forest", "lastName": "Schmidt", "age": 18 }, { "id": 463, "firstName": "Karley", "lastName": "Carroll", "age": 32 }, { "id": 464, "firstName": "Sydnee", "lastName": "Huels", "age": 40 }, { "id": 465, "firstName": "Anissa", "lastName": "Hettinger", "age": 26 }, { "id": 466, "firstName": "Sylvia", "lastName": "Kassulke", "age": 10 }, { "id": 467, "firstName": "Cleve", "lastName": "Hackett", "age": 30 }, { "id": 468, "firstName": "Yoshiko", "lastName": "Lynch", "age": 18 }, { "id": 469, "firstName": "Vesta", "lastName": "Feil", "age": 36 }, { "id": 470, "firstName": "Dejuan", "lastName": "Block-Wisozk", "age": 16 }, { "id": 471, "firstName": "Camden", "lastName": "Ankunding", "age": 29 }, { "id": 472, "firstName": "Tyrese", "lastName": "Hermann-Stehr", "age": 27 }, { "id": 473, "firstName": "Marlee", "lastName": "Champlin", "age": 22 }, { "id": 474, "firstName": "Everardo", "lastName": "Nienow", "age": 29 }, { "id": 475, "firstName": "Wayne", "lastName": "Schuppe", "age": 25 }, { "id": 476, "firstName": "Don", "lastName": "Medhurst", "age": 26 }, { "id": 477, "firstName": "Ilene", "lastName": "Ankunding", "age": 2 }, { "id": 478, "firstName": "Arjun", "lastName": "Hauck", "age": 33 }, { "id": 479, "firstName": "Herbert", "lastName": "Macejkovic", "age": 26 }, { "id": 480, "firstName": "Giovanna", "lastName": "Glover", "age": 24 }, { "id": 481, "firstName": "Karelle", "lastName": "Ziemann-Lowe", "age": 13 }, { "id": 482, "firstName": "Rico", "lastName": "Kshlerin", "age": 10 }, { "id": 483, "firstName": "Dean", "lastName": "Lueilwitz", "age": 29 }, { "id": 484, "firstName": "Curt", "lastName": "Rohan", "age": 19 }, { "id": 485, "firstName": "Ed", "lastName": "Collier", "age": 12 }, { "id": 486, "firstName": "Mariam", "lastName": "Krajcik", "age": 37 }, { "id": 487, "firstName": "Keyon", "lastName": "Sporer", "age": 27 }, { "id": 488, "firstName": "Ike", "lastName": "Gerhold", "age": 17 }, { "id": 489, "firstName": "Tierra", "lastName": "Bahringer", "age": 13 }, { "id": 490, "firstName": "Carolanne", "lastName": "Botsford", "age": 36 }, { "id": 491, "firstName": "Obie", "lastName": "Bogan", "age": 0 }, { "id": 492, "firstName": "Elmore", "lastName": "Franecki", "age": 30 }, { "id": 493, "firstName": "Jonathon", "lastName": "Farrell", "age": 10 }, { "id": 494, "firstName": "Ashlynn", "lastName": "Hilpert", "age": 19 }, { "id": 495, "firstName": "Lamont", "lastName": "Blick", "age": 21 }, { "id": 496, "firstName": "Retta", "lastName": "Hansen", "age": 35 }, { "id": 497, "firstName": "Oda", "lastName": "Ratke", "age": 32 }, { "id": 498, "firstName": "Colton", "lastName": "Schinner", "age": 34 }, { "id": 499, "firstName": "Domenic", "lastName": "Denesik", "age": 9 }, { "id": 500, "firstName": "Chaim", "lastName": "Cronin", "age": 32 }, { "id": 501, "firstName": "Carroll", "lastName": "Zulauf", "age": 34 }, { "id": 502, "firstName": "Cheyanne", "lastName": "Rippin", "age": 0 }, { "id": 503, "firstName": "Olaf", "lastName": "Zulauf", "age": 6 }, { "id": 504, "firstName": "Chanelle", "lastName": "Jakubowski", "age": 16 }, { "id": 505, "firstName": "Lavina", "lastName": "Fay", "age": 20 }, { "id": 506, "firstName": "Maud", "lastName": "Wunsch", "age": 25 }, { "id": 507, "firstName": "Nels", "lastName": "Windler", "age": 14 }, { "id": 508, "firstName": "Brionna", "lastName": "Mohr", "age": 2 }, { "id": 509, "firstName": "Esperanza", "lastName": "Daugherty", "age": 23 }, { "id": 510, "firstName": "Candace", "lastName": "Langworth", "age": 18 }, { "id": 511, "firstName": "Verna", "lastName": "Osinski", "age": 16 }, { "id": 512, "firstName": "Dakota", "lastName": "Rippin", "age": 29 }, { "id": 513, "firstName": "Karen", "lastName": "Kohler", "age": 25 }, { "id": 514, "firstName": "Coralie", "lastName": "Farrell", "age": 38 }, { "id": 515, "firstName": "Myah", "lastName": "Hermiston", "age": 24 }, { "id": 516, "firstName": "Green", "lastName": "Kulas", "age": 37 }, { "id": 517, "firstName": "Myah", "lastName": "Olson", "age": 29 }, { "id": 518, "firstName": "Cynthia", "lastName": "Bartoletti", "age": 10 }, { "id": 519, "firstName": "Lea", "lastName": "Treutel", "age": 29 }, { "id": 520, "firstName": "Pierre", "lastName": "Marvin", "age": 17 }, { "id": 521, "firstName": "Abbie", "lastName": "Prosacco", "age": 36 }, { "id": 522, "firstName": "Rosa", "lastName": "Lueilwitz", "age": 32 }, { "id": 523, "firstName": "Edna", "lastName": "Kertzmann", "age": 12 }, { "id": 524, "firstName": "Ignatius", "lastName": "Von", "age": 7 }, { "id": 525, "firstName": "Freeman", "lastName": "Russel", "age": 34 }, { "id": 526, "firstName": "Cullen", "lastName": "Wilkinson", "age": 8 }, { "id": 527, "firstName": "Liliana", "lastName": "Anderson", "age": 30 }, { "id": 528, "firstName": "Edgardo", "lastName": "Wiegand", "age": 39 }, { "id": 529, "firstName": "Molly", "lastName": "Lemke", "age": 13 }, { "id": 530, "firstName": "Tara", "lastName": "Pacocha", "age": 25 }, { "id": 531, "firstName": "Hannah", "lastName": "Crist", "age": 35 }, { "id": 532, "firstName": "Myriam", "lastName": "Kassulke", "age": 20 }, { "id": 533, "firstName": "Gregoria", "lastName": "Rice", "age": 3 }, { "id": 534, "firstName": "Yazmin", "lastName": "Spencer", "age": 35 }, { "id": 535, "firstName": "Harrison", "lastName": "McGlynn", "age": 12 }, { "id": 536, "firstName": "Nelson", "lastName": "Effertz-McKenzie", "age": 22 }, { "id": 537, "firstName": "Myrtis", "lastName": "Gutkowski", "age": 17 }, { "id": 538, "firstName": "Zita", "lastName": "Larson", "age": 32 }, { "id": 539, "firstName": "Myriam", "lastName": "Barton", "age": 30 }, { "id": 540, "firstName": "Lew", "lastName": "Volkman", "age": 11 }, { "id": 541, "firstName": "Concepcion", "lastName": "Lynch", "age": 18 }, { "id": 542, "firstName": "Josefina", "lastName": "Stanton", "age": 25 }, { "id": 543, "firstName": "Abagail", "lastName": "Robel", "age": 0 }, { "id": 544, "firstName": "Amara", "lastName": "Wilkinson", "age": 29 }, { "id": 545, "firstName": "Bria", "lastName": "Simonis", "age": 10 }, { "id": 546, "firstName": "Jaycee", "lastName": "Thiel", "age": 20 }, { "id": 547, "firstName": "Furman", "lastName": "Bins", "age": 39 }, { "id": 548, "firstName": "Granville", "lastName": "Schultz", "age": 27 }, { "id": 549, "firstName": "Layla", "lastName": "Kovacek", "age": 2 }, { "id": 550, "firstName": "Naomi", "lastName": "Jaskolski", "age": 31 }, { "id": 551, "firstName": "Nikolas", "lastName": "Jerde", "age": 20 }, { "id": 552, "firstName": "Herta", "lastName": "Klein", "age": 13 }, { "id": 553, "firstName": "Orpha", "lastName": "Upton", "age": 37 }, { "id": 554, "firstName": "Lucile", "lastName": "Osinski", "age": 4 }, { "id": 555, "firstName": "Sim", "lastName": "Morissette", "age": 26 }, { "id": 556, "firstName": "Hailey", "lastName": "Mraz", "age": 13 }, { "id": 557, "firstName": "Rex", "lastName": "Kutch", "age": 14 }, { "id": 558, "firstName": "Lorena", "lastName": "Gerhold", "age": 21 }, { "id": 559, "firstName": "Cletus", "lastName": "Haag", "age": 36 }, { "id": 560, "firstName": "Maynard", "lastName": "Parker", "age": 40 }, { "id": 561, "firstName": "Weldon", "lastName": "Rodriguez", "age": 15 }, { "id": 562, "firstName": "Willy", "lastName": "Cassin", "age": 9 }, { "id": 563, "firstName": "Lavina", "lastName": "Murphy", "age": 33 }, { "id": 564, "firstName": "Pearlie", "lastName": "Fahey", "age": 28 }, { "id": 565, "firstName": "Heidi", "lastName": "Haag-Conroy", "age": 6 }, { "id": 566, "firstName": "Jacklyn", "lastName": "Waters", "age": 20 }, { "id": 567, "firstName": "Arno", "lastName": "Hartmann", "age": 8 }, { "id": 568, "firstName": "Theo", "lastName": "Watsica", "age": 13 }, { "id": 569, "firstName": "John", "lastName": "Von", "age": 10 }, { "id": 570, "firstName": "Christina", "lastName": "Ebert", "age": 13 }, { "id": 571, "firstName": "Milford", "lastName": "Keebler", "age": 27 }, { "id": 572, "firstName": "Cristobal", "lastName": "Watsica", "age": 32 }, { "id": 573, "firstName": "Patricia", "lastName": "Bauch", "age": 0 }, { "id": 574, "firstName": "Dorian", "lastName": "Lubowitz", "age": 24 }, { "id": 575, "firstName": "Antwan", "lastName": "Kuvalis", "age": 21 }, { "id": 576, "firstName": "Krystal", "lastName": "Kirlin", "age": 22 }, { "id": 577, "firstName": "Eleazar", "lastName": "Bergstrom", "age": 14 }, { "id": 578, "firstName": "Abel", "lastName": "Abernathy", "age": 14 }, { "id": 579, "firstName": "Cindy", "lastName": "Gerlach", "age": 27 }, { "id": 580, "firstName": "Angus", "lastName": "Brakus", "age": 5 }, { "id": 581, "firstName": "Nelle", "lastName": "Gleason", "age": 27 }, { "id": 582, "firstName": "Sylvan", "lastName": "Schmeler", "age": 14 }, { "id": 583, "firstName": "Etha", "lastName": "Kris", "age": 19 }, { "id": 584, "firstName": "Eloise", "lastName": "Swift", "age": 18 }, { "id": 585, "firstName": "Kris", "lastName": "Stehr", "age": 21 }, { "id": 586, "firstName": "Jarret", "lastName": "Gerlach", "age": 9 }, { "id": 587, "firstName": "Letha", "lastName": "Rowe", "age": 23 }, { "id": 588, "firstName": "Anais", "lastName": "Balistreri", "age": 39 }, { "id": 589, "firstName": "Armand", "lastName": "Towne", "age": 2 }, { "id": 590, "firstName": "Ransom", "lastName": "Hermiston-Heaney", "age": 18 }, { "id": 591, "firstName": "Vivien", "lastName": "Waelchi", "age": 36 }, { "id": 592, "firstName": "Everette", "lastName": "Kerluke", "age": 3 }, { "id": 593, "firstName": "Alden", "lastName": "Batz", "age": 7 }, { "id": 594, "firstName": "Marco", "lastName": "Cremin", "age": 3 }, { "id": 595, "firstName": "Virgil", "lastName": "Kub", "age": 38 }, { "id": 596, "firstName": "Horace", "lastName": "Monahan", "age": 10 }, { "id": 597, "firstName": "Megane", "lastName": "Hayes", "age": 12 }, { "id": 598, "firstName": "Barbara", "lastName": "Cummings", "age": 36 }, { "id": 599, "firstName": "Estell", "lastName": "Kshlerin", "age": 4 }, { "id": 600, "firstName": "Price", "lastName": "Keeling", "age": 14 }, { "id": 601, "firstName": "Nelson", "lastName": "Veum", "age": 10 }, { "id": 602, "firstName": "Benjamin", "lastName": "Treutel", "age": 14 }, { "id": 603, "firstName": "Keyshawn", "lastName": "DuBuque", "age": 12 }, { "id": 604, "firstName": "Yasmine", "lastName": "Pollich", "age": 34 }, { "id": 605, "firstName": "Connie", "lastName": "Padberg", "age": 36 }, { "id": 606, "firstName": "Pearl", "lastName": "Adams", "age": 34 }, { "id": 607, "firstName": "Sammie", "lastName": "Berge", "age": 32 }, { "id": 608, "firstName": "Annetta", "lastName": "Predovic", "age": 34 }, { "id": 609, "firstName": "Rodger", "lastName": "Murazik", "age": 25 }, { "id": 610, "firstName": "Devon", "lastName": "Borer", "age": 32 }, { "id": 611, "firstName": "Tre", "lastName": "Murray", "age": 3 }, { "id": 612, "firstName": "Tevin", "lastName": "Krajcik", "age": 28 }, { "id": 613, "firstName": "Nickolas", "lastName": "Hilpert", "age": 22 }, { "id": 614, "firstName": "Horacio", "lastName": "Schumm", "age": 20 }, { "id": 615, "firstName": "Jeffry", "lastName": "Zemlak", "age": 0 }, { "id": 616, "firstName": "Rachael", "lastName": "Greenholt", "age": 3 }, { "id": 617, "firstName": "Arno", "lastName": "Hegmann", "age": 2 }, { "id": 618, "firstName": "Mariah", "lastName": "Berge", "age": 29 }, { "id": 619, "firstName": "Tessie", "lastName": "Hayes", "age": 22 }, { "id": 620, "firstName": "Mandy", "lastName": "Klein", "age": 11 }, { "id": 621, "firstName": "Fae", "lastName": "Corwin", "age": 20 }, { "id": 622, "firstName": "Hellen", "lastName": "Runolfsdottir", "age": 12 }, { "id": 623, "firstName": "Beulah", "lastName": "Yundt", "age": 17 }, { "id": 624, "firstName": "Jarred", "lastName": "Langosh", "age": 16 }, { "id": 625, "firstName": "Myron", "lastName": "Corkery", "age": 31 }, { "id": 626, "firstName": "Miles", "lastName": "Kessler", "age": 40 }, { "id": 627, "firstName": "Sophie", "lastName": "Osinski", "age": 3 }, { "id": 628, "firstName": "Orlando", "lastName": "Stehr", "age": 7 }, { "id": 629, "firstName": "Mohammed", "lastName": "Mann", "age": 26 }, { "id": 630, "firstName": "Ephraim", "lastName": "Wilderman", "age": 2 }, { "id": 631, "firstName": "Loyal", "lastName": "Waelchi", "age": 3 }, { "id": 632, "firstName": "Mavis", "lastName": "Harris", "age": 25 }, { "id": 633, "firstName": "Orin", "lastName": "Lowe", "age": 14 }, { "id": 634, "firstName": "Una", "lastName": "Hodkiewicz", "age": 30 }, { "id": 635, "firstName": "Khalid", "lastName": "Harvey", "age": 14 }, { "id": 636, "firstName": "Lazaro", "lastName": "Doyle", "age": 37 }, { "id": 637, "firstName": "Skyla", "lastName": "Raynor", "age": 24 }, { "id": 638, "firstName": "Esmeralda", "lastName": "Towne", "age": 21 }, { "id": 639, "firstName": "Alberta", "lastName": "Bednar", "age": 35 }, { "id": 640, "firstName": "Josh", "lastName": "Kassulke", "age": 39 }, { "id": 641, "firstName": "Madge", "lastName": "Ernser", "age": 31 }, { "id": 642, "firstName": "Alanna", "lastName": "Reynolds", "age": 14 }, { "id": 643, "firstName": "Elroy", "lastName": "Balistreri", "age": 8 }, { "id": 644, "firstName": "Percival", "lastName": "Heaney", "age": 23 }, { "id": 645, "firstName": "Quinten", "lastName": "Bradtke", "age": 13 }, { "id": 646, "firstName": "Aubrey", "lastName": "Will", "age": 28 }, { "id": 647, "firstName": "Violet", "lastName": "Hirthe", "age": 19 }, { "id": 648, "firstName": "Nels", "lastName": "Leffler", "age": 14 }, { "id": 649, "firstName": "Florian", "lastName": "Stiedemann", "age": 27 }, { "id": 650, "firstName": "Javier", "lastName": "Ritchie", "age": 12 }, { "id": 651, "firstName": "Eriberto", "lastName": "Herzog", "age": 0 }, { "id": 652, "firstName": "Jaycee", "lastName": "Kerluke", "age": 21 }, { "id": 653, "firstName": "Eino", "lastName": "Lemke", "age": 17 }, { "id": 654, "firstName": "Sofia", "lastName": "Schimmel", "age": 17 }, { "id": 655, "firstName": "Dahlia", "lastName": "Nolan-Wilkinson", "age": 38 }, { "id": 656, "firstName": "Jaquan", "lastName": "Conn", "age": 10 }, { "id": 657, "firstName": "Louisa", "lastName": "Murazik", "age": 3 }, { "id": 658, "firstName": "Brittany", "lastName": "Conn", "age": 17 }, { "id": 659, "firstName": "Madisen", "lastName": "Johns", "age": 0 }, { "id": 660, "firstName": "Jaren", "lastName": "Erdman", "age": 27 }, { "id": 661, "firstName": "Maya", "lastName": "Boehm", "age": 38 }, { "id": 662, "firstName": "Vladimir", "lastName": "Mante", "age": 18 }, { "id": 663, "firstName": "Rosalinda", "lastName": "Kuhlman", "age": 30 }, { "id": 664, "firstName": "Ulices", "lastName": "Luettgen", "age": 15 }, { "id": 665, "firstName": "Therese", "lastName": "Leffler", "age": 23 }, { "id": 666, "firstName": "Clinton", "lastName": "Mayer", "age": 40 }, { "id": 667, "firstName": "Flavie", "lastName": "Borer", "age": 21 }, { "id": 668, "firstName": "Mariah", "lastName": "Buckridge", "age": 36 }, { "id": 669, "firstName": "Estelle", "lastName": "Gulgowski", "age": 31 }, { "id": 670, "firstName": "Cayla", "lastName": "Ledner", "age": 24 }, { "id": 671, "firstName": "Franco", "lastName": "Pollich", "age": 25 }, { "id": 672, "firstName": "Abigayle", "lastName": "Herzog", "age": 17 }, { "id": 673, "firstName": "Ellie", "lastName": "Ziemann", "age": 24 }, { "id": 674, "firstName": "Lenore", "lastName": "Beier", "age": 27 }, { "id": 675, "firstName": "William", "lastName": "Boyer", "age": 27 }, { "id": 676, "firstName": "Marlon", "lastName": "Dicki", "age": 17 }, { "id": 677, "firstName": "Vance", "lastName": "Monahan", "age": 14 }, { "id": 678, "firstName": "Rosina", "lastName": "McCullough", "age": 3 }, { "id": 679, "firstName": "Muriel", "lastName": "Walker", "age": 4 }, { "id": 680, "firstName": "Troy", "lastName": "Parisian", "age": 14 }, { "id": 681, "firstName": "Julia", "lastName": "Feest", "age": 2 }, { "id": 682, "firstName": "Branson", "lastName": "Ratke", "age": 27 }, { "id": 683, "firstName": "Rhett", "lastName": "Reichert-Torp", "age": 24 }, { "id": 684, "firstName": "Destin", "lastName": "Bode", "age": 7 }, { "id": 685, "firstName": "Demetrius", "lastName": "Dare-Auer", "age": 10 }, { "id": 686, "firstName": "Tyrique", "lastName": "Hammes", "age": 30 }, { "id": 687, "firstName": "Aurelie", "lastName": "Kilback", "age": 20 }, { "id": 688, "firstName": "Margot", "lastName": "Hahn", "age": 11 }, { "id": 689, "firstName": "Briana", "lastName": "Hoeger", "age": 5 }, { "id": 690, "firstName": "Kennith", "lastName": "Murazik", "age": 9 }, { "id": 691, "firstName": "Amani", "lastName": "Kemmer", "age": 27 }, { "id": 692, "firstName": "Gerry", "lastName": "Wilderman", "age": 5 }, { "id": 693, "firstName": "Abdiel", "lastName": "Wiegand", "age": 35 }, { "id": 694, "firstName": "Emmalee", "lastName": "Konopelski", "age": 13 }, { "id": 695, "firstName": "Stewart", "lastName": "Mitchell", "age": 4 }, { "id": 696, "firstName": "Garfield", "lastName": "Ondricka", "age": 40 }, { "id": 697, "firstName": "Zakary", "lastName": "Little", "age": 19 }, { "id": 698, "firstName": "Vesta", "lastName": "Koch", "age": 30 }, { "id": 699, "firstName": "Mohamed", "lastName": "Rolfson-Prohaska", "age": 14 }, { "id": 700, "firstName": "Sabryna", "lastName": "Langworth", "age": 7 }, { "id": 701, "firstName": "Chaz", "lastName": "Erdman", "age": 34 }, { "id": 702, "firstName": "Annabel", "lastName": "Larkin", "age": 15 }, { "id": 703, "firstName": "Casper", "lastName": "Runolfsdottir", "age": 28 }, { "id": 704, "firstName": "Hoyt", "lastName": "Effertz", "age": 9 }, { "id": 705, "firstName": "Nicolette", "lastName": "Hansen", "age": 35 }, { "id": 706, "firstName": "Ima", "lastName": "Brown", "age": 16 }, { "id": 707, "firstName": "Merl", "lastName": "Volkman", "age": 27 }, { "id": 708, "firstName": "Pamela", "lastName": "Gibson", "age": 22 }, { "id": 709, "firstName": "Susanna", "lastName": "Strosin", "age": 10 }, { "id": 710, "firstName": "Bradford", "lastName": "Wisozk", "age": 30 }, { "id": 711, "firstName": "Jaydon", "lastName": "Muller", "age": 37 }, { "id": 712, "firstName": "Annetta", "lastName": "Kreiger", "age": 28 }, { "id": 713, "firstName": "Geraldine", "lastName": "Hahn", "age": 2 }, { "id": 714, "firstName": "Rosalind", "lastName": "Bauch", "age": 15 }, { "id": 715, "firstName": "Eveline", "lastName": "Legros", "age": 27 }, { "id": 716, "firstName": "Enoch", "lastName": "Witting", "age": 4 }, { "id": 717, "firstName": "Ralph", "lastName": "Grady", "age": 7 }, { "id": 718, "firstName": "Jeanne", "lastName": "Predovic", "age": 22 }, { "id": 719, "firstName": "Camden", "lastName": "Turcotte", "age": 19 }, { "id": 720, "firstName": "Cleveland", "lastName": "Gleichner", "age": 7 }, { "id": 721, "firstName": "Remington", "lastName": "Predovic", "age": 2 }, { "id": 722, "firstName": "Kyra", "lastName": "Mertz", "age": 22 }, { "id": 723, "firstName": "Ephraim", "lastName": "Anderson", "age": 9 }, { "id": 724, "firstName": "Vincent", "lastName": "Rippin", "age": 15 }, { "id": 725, "firstName": "Dianna", "lastName": "Rowe", "age": 8 }, { "id": 726, "firstName": "Jefferey", "lastName": "Spencer", "age": 12 }, { "id": 727, "firstName": "Sim", "lastName": "Dach", "age": 35 }, { "id": 728, "firstName": "Bradly", "lastName": "Reynolds", "age": 37 }, { "id": 729, "firstName": "Annabell", "lastName": "Cummings", "age": 5 }, { "id": 730, "firstName": "Gaetano", "lastName": "Becker", "age": 2 }, { "id": 731, "firstName": "Jacquelyn", "lastName": "Hilll", "age": 26 }, { "id": 732, "firstName": "Cielo", "lastName": "Huels", "age": 31 }, { "id": 733, "firstName": "Lucie", "lastName": "Bechtelar", "age": 10 }, { "id": 734, "firstName": "Tiara", "lastName": "Mosciski", "age": 31 }, { "id": 735, "firstName": "Retha", "lastName": "Langworth", "age": 37 }, { "id": 736, "firstName": "Katarina", "lastName": "Douglas", "age": 2 }, { "id": 737, "firstName": "Herbert", "lastName": "Hyatt", "age": 32 }, { "id": 738, "firstName": "Gerhard", "lastName": "Torphy-Mraz", "age": 34 }, { "id": 739, "firstName": "Jerrell", "lastName": "Schumm", "age": 6 }, { "id": 740, "firstName": "Dashawn", "lastName": "VonRueden", "age": 13 }, { "id": 741, "firstName": "Jake", "lastName": "Klocko", "age": 19 }, { "id": 742, "firstName": "Erin", "lastName": "Kuhn", "age": 35 }, { "id": 743, "firstName": "Kyleigh", "lastName": "Renner", "age": 19 }, { "id": 744, "firstName": "Joana", "lastName": "Fisher", "age": 22 }, { "id": 745, "firstName": "Seamus", "lastName": "Rohan", "age": 26 }, { "id": 746, "firstName": "Karli", "lastName": "Lindgren", "age": 11 }, { "id": 747, "firstName": "Haleigh", "lastName": "Murray", "age": 37 }, { "id": 748, "firstName": "Alisa", "lastName": "Rau", "age": 7 }, { "id": 749, "firstName": "Carolanne", "lastName": "Hoeger", "age": 1 }, { "id": 750, "firstName": "Hans", "lastName": "Grant", "age": 20 }, { "id": 751, "firstName": "Providenci", "lastName": "Breitenberg", "age": 5 }, { "id": 752, "firstName": "Sally", "lastName": "Romaguera", "age": 11 }, { "id": 753, "firstName": "Beryl", "lastName": "Hills", "age": 3 }, { "id": 754, "firstName": "Meagan", "lastName": "Kozey", "age": 35 }, { "id": 755, "firstName": "Maxime", "lastName": "Schaefer", "age": 18 }, { "id": 756, "firstName": "Christop", "lastName": "Collier", "age": 4 }, { "id": 757, "firstName": "Nathaniel", "lastName": "Stokes", "age": 19 }, { "id": 758, "firstName": "Rolando", "lastName": "White", "age": 14 }, { "id": 759, "firstName": "Millie", "lastName": "Upton", "age": 31 }, { "id": 760, "firstName": "Alessandro", "lastName": "Wehner", "age": 36 }, { "id": 761, "firstName": "Abagail", "lastName": "Mitchell", "age": 28 }, { "id": 762, "firstName": "Loy", "lastName": "Bradtke", "age": 11 }, { "id": 763, "firstName": "Kendall", "lastName": "Rolfson", "age": 35 }, { "id": 764, "firstName": "Alisa", "lastName": "Cassin", "age": 18 }, { "id": 765, "firstName": "Larue", "lastName": "Fay", "age": 25 }, { "id": 766, "firstName": "Kianna", "lastName": "Bins", "age": 3 }, { "id": 767, "firstName": "Rhiannon", "lastName": "Hansen-Brekke", "age": 35 }, { "id": 768, "firstName": "Baron", "lastName": "Schaefer", "age": 33 }, { "id": 769, "firstName": "Ernest", "lastName": "Spencer-Terry", "age": 6 }, { "id": 770, "firstName": "Else", "lastName": "Stroman", "age": 35 }, { "id": 771, "firstName": "Johnathon", "lastName": "Littel", "age": 4 }, { "id": 772, "firstName": "Delores", "lastName": "Stehr", "age": 5 }, { "id": 773, "firstName": "Eldon", "lastName": "Walter", "age": 36 }, { "id": 774, "firstName": "Marilie", "lastName": "Torphy", "age": 24 }, { "id": 775, "firstName": "Neva", "lastName": "Hartmann", "age": 13 }, { "id": 776, "firstName": "Morris", "lastName": "Thiel", "age": 14 }, { "id": 777, "firstName": "Carlee", "lastName": "Tillman", "age": 9 }, { "id": 778, "firstName": "Ericka", "lastName": "Kessler", "age": 21 }, { "id": 779, "firstName": "Jazlyn", "lastName": "Parisian", "age": 23 }, { "id": 780, "firstName": "Demetrius", "lastName": "Johnston", "age": 32 }, { "id": 781, "firstName": "Irwin", "lastName": "Nikolaus", "age": 23 }, { "id": 782, "firstName": "Julien", "lastName": "Veum", "age": 31 }, { "id": 783, "firstName": "Estel", "lastName": "Cremin", "age": 13 }, { "id": 784, "firstName": "Edwin", "lastName": "Luettgen", "age": 9 }, { "id": 785, "firstName": "Rudy", "lastName": "Walker", "age": 25 }, { "id": 786, "firstName": "Lisa", "lastName": "Metz", "age": 8 }, { "id": 787, "firstName": "Kelsi", "lastName": "Howell", "age": 6 }, { "id": 788, "firstName": "Alexa", "lastName": "Kemmer", "age": 5 }, { "id": 789, "firstName": "Paxton", "lastName": "Schmeler", "age": 9 }, { "id": 790, "firstName": "Sarai", "lastName": "McKenzie", "age": 2 }, { "id": 791, "firstName": "Ryann", "lastName": "Schinner", "age": 36 }, { "id": 792, "firstName": "Isobel", "lastName": "Cartwright", "age": 32 }, { "id": 793, "firstName": "Myah", "lastName": "O'Conner", "age": 29 }, { "id": 794, "firstName": "Ericka", "lastName": "Marvin", "age": 0 }, { "id": 795, "firstName": "Devyn", "lastName": "Fisher", "age": 27 }, { "id": 796, "firstName": "Orval", "lastName": "Franey", "age": 16 }, { "id": 797, "firstName": "Augusta", "lastName": "Runte", "age": 19 }, { "id": 798, "firstName": "Flossie", "lastName": "Walker", "age": 19 }, { "id": 799, "firstName": "Sydney", "lastName": "Swaniawski", "age": 37 }, { "id": 800, "firstName": "Leanna", "lastName": "Greenfelder", "age": 14 }, { "id": 801, "firstName": "Caesar", "lastName": "Franey", "age": 37 }, { "id": 802, "firstName": "Tyree", "lastName": "Ledner", "age": 2 }, { "id": 803, "firstName": "Joe", "lastName": "Schiller", "age": 3 }, { "id": 804, "firstName": "Elijah", "lastName": "Metz-O'Kon", "age": 29 }, { "id": 805, "firstName": "Kenya", "lastName": "Harber", "age": 19 }, { "id": 806, "firstName": "Brody", "lastName": "Grant", "age": 37 }, { "id": 807, "firstName": "Vince", "lastName": "Ruecker", "age": 30 }, { "id": 808, "firstName": "Sigurd", "lastName": "VonRueden", "age": 31 }, { "id": 809, "firstName": "Ryan", "lastName": "Weissnat", "age": 16 }, { "id": 810, "firstName": "Fernando", "lastName": "Boehm-Heaney", "age": 10 }, { "id": 811, "firstName": "Creola", "lastName": "Rempel-Schaefer", "age": 19 }, { "id": 812, "firstName": "Edmund", "lastName": "Rohan", "age": 7 }, { "id": 813, "firstName": "Trace", "lastName": "Romaguera", "age": 5 }, { "id": 814, "firstName": "Nathaniel", "lastName": "Runolfsdottir-Marks", "age": 26 }, { "id": 815, "firstName": "Donny", "lastName": "Romaguera", "age": 27 }, { "id": 816, "firstName": "Sheridan", "lastName": "Corkery", "age": 40 }, { "id": 817, "firstName": "Rhianna", "lastName": "Pouros", "age": 16 }, { "id": 818, "firstName": "Gerry", "lastName": "Bartell", "age": 10 }, { "id": 819, "firstName": "Finn", "lastName": "Hessel", "age": 30 }, { "id": 820, "firstName": "Graham", "lastName": "Wintheiser-Kirlin", "age": 39 }, { "id": 821, "firstName": "Tod", "lastName": "O'Kon", "age": 19 }, { "id": 822, "firstName": "Mathilde", "lastName": "Rutherford", "age": 21 }, { "id": 823, "firstName": "Orin", "lastName": "Beier", "age": 39 }, { "id": 824, "firstName": "Keara", "lastName": "Hayes", "age": 2 }, { "id": 825, "firstName": "Zelda", "lastName": "Braun", "age": 14 }, { "id": 826, "firstName": "Myrtice", "lastName": "Auer", "age": 15 }, { "id": 827, "firstName": "Anahi", "lastName": "Stoltenberg", "age": 35 }, { "id": 828, "firstName": "Colin", "lastName": "Bergstrom", "age": 22 }, { "id": 829, "firstName": "Dangelo", "lastName": "Greenfelder", "age": 27 }, { "id": 830, "firstName": "Salvador", "lastName": "Borer", "age": 24 }, { "id": 831, "firstName": "Lawson", "lastName": "King", "age": 33 }, { "id": 832, "firstName": "Blanca", "lastName": "Schaden", "age": 26 }, { "id": 833, "firstName": "Maude", "lastName": "Hammes", "age": 31 }, { "id": 834, "firstName": "Bertha", "lastName": "Hoeger", "age": 35 }, { "id": 835, "firstName": "Grover", "lastName": "Bednar", "age": 40 }, { "id": 836, "firstName": "Geovany", "lastName": "Rohan", "age": 38 }, { "id": 837, "firstName": "Antonette", "lastName": "D'Amore", "age": 25 }, { "id": 838, "firstName": "Audrey", "lastName": "O'Hara", "age": 25 }, { "id": 839, "firstName": "Ezequiel", "lastName": "VonRueden", "age": 33 }, { "id": 840, "firstName": "Alyson", "lastName": "Weissnat", "age": 16 }, { "id": 841, "firstName": "Scottie", "lastName": "Bogan", "age": 14 }, { "id": 842, "firstName": "Drake", "lastName": "Crona", "age": 34 }, { "id": 843, "firstName": "Donald", "lastName": "Dooley", "age": 5 }, { "id": 844, "firstName": "Arvilla", "lastName": "Metz", "age": 21 }, { "id": 845, "firstName": "Amie", "lastName": "Schaden", "age": 14 }, { "id": 846, "firstName": "Verdie", "lastName": "Christiansen", "age": 5 }, { "id": 847, "firstName": "Annetta", "lastName": "Labadie", "age": 5 }, { "id": 848, "firstName": "Lesly", "lastName": "Kirlin", "age": 14 }, { "id": 849, "firstName": "Gaston", "lastName": "Toy-Larkin", "age": 19 }, { "id": 850, "firstName": "Nathanael", "lastName": "Durgan", "age": 17 }, { "id": 851, "firstName": "Louie", "lastName": "Torp", "age": 4 }, { "id": 852, "firstName": "Armani", "lastName": "Kertzmann", "age": 13 }, { "id": 853, "firstName": "Jayde", "lastName": "Lakin", "age": 1 }, { "id": 854, "firstName": "Autumn", "lastName": "Wiza", "age": 20 }, { "id": 855, "firstName": "Guido", "lastName": "Kulas", "age": 22 }, { "id": 856, "firstName": "Bud", "lastName": "Runte", "age": 10 }, { "id": 857, "firstName": "Maxime", "lastName": "Funk", "age": 23 }, { "id": 858, "firstName": "Dylan", "lastName": "Jenkins", "age": 31 }, { "id": 859, "firstName": "Yesenia", "lastName": "Ruecker-Wehner", "age": 5 }, { "id": 860, "firstName": "Zion", "lastName": "Schmeler", "age": 38 }, { "id": 861, "firstName": "Zola", "lastName": "Wiegand", "age": 38 }, { "id": 862, "firstName": "Abdullah", "lastName": "Bogan", "age": 11 }, { "id": 863, "firstName": "Issac", "lastName": "Monahan", "age": 14 }, { "id": 864, "firstName": "Patrick", "lastName": "Baumbach", "age": 40 }, { "id": 865, "firstName": "Josefa", "lastName": "Heller", "age": 25 }, { "id": 866, "firstName": "Bulah", "lastName": "Hayes", "age": 15 }, { "id": 867, "firstName": "Brannon", "lastName": "Hahn-Abshire", "age": 13 }, { "id": 868, "firstName": "Corrine", "lastName": "Huels", "age": 38 }, { "id": 869, "firstName": "Nils", "lastName": "Botsford", "age": 28 }, { "id": 870, "firstName": "Shaylee", "lastName": "Windler", "age": 29 }, { "id": 871, "firstName": "Matteo", "lastName": "Pagac", "age": 2 }, { "id": 872, "firstName": "Kyla", "lastName": "Fritsch", "age": 35 }, { "id": 873, "firstName": "Freeman", "lastName": "Spencer", "age": 15 }, { "id": 874, "firstName": "Casimir", "lastName": "Cassin", "age": 15 }, { "id": 875, "firstName": "Waylon", "lastName": "Gleichner", "age": 39 }, { "id": 876, "firstName": "Lina", "lastName": "Skiles", "age": 16 }, { "id": 877, "firstName": "Augustine", "lastName": "Konopelski", "age": 30 }, { "id": 878, "firstName": "Shawn", "lastName": "Herzog", "age": 3 }, { "id": 879, "firstName": "Chadd", "lastName": "Kautzer", "age": 38 }, { "id": 880, "firstName": "Marisol", "lastName": "Collins", "age": 31 }, { "id": 881, "firstName": "Niko", "lastName": "Rippin", "age": 2 }, { "id": 882, "firstName": "Derrick", "lastName": "Klocko", "age": 10 }, { "id": 883, "firstName": "Sofia", "lastName": "Cremin", "age": 23 }, { "id": 884, "firstName": "Josianne", "lastName": "Roob", "age": 2 }, { "id": 885, "firstName": "Emery", "lastName": "Ryan-Stroman", "age": 28 }, { "id": 886, "firstName": "Bobby", "lastName": "Kuhlman", "age": 9 }, { "id": 887, "firstName": "Rhea", "lastName": "Kilback", "age": 25 }, { "id": 888, "firstName": "Tyshawn", "lastName": "Lockman", "age": 0 }, { "id": 889, "firstName": "Sheila", "lastName": "West", "age": 37 }, { "id": 890, "firstName": "Queenie", "lastName": "Farrell", "age": 16 }, { "id": 891, "firstName": "Alexane", "lastName": "Wisoky", "age": 9 }, { "id": 892, "firstName": "Rasheed", "lastName": "Roob", "age": 33 }, { "id": 893, "firstName": "Era", "lastName": "Lehner", "age": 31 }, { "id": 894, "firstName": "Stephany", "lastName": "Renner", "age": 8 }, { "id": 895, "firstName": "Tia", "lastName": "Grimes-Howe", "age": 30 }, { "id": 896, "firstName": "Yadira", "lastName": "Witting", "age": 31 }, { "id": 897, "firstName": "Rosanna", "lastName": "Haley", "age": 36 }, { "id": 898, "firstName": "Bria", "lastName": "Wiegand", "age": 21 }, { "id": 899, "firstName": "Crystal", "lastName": "Cruickshank", "age": 14 }, { "id": 900, "firstName": "Evert", "lastName": "Walker", "age": 9 }, { "id": 901, "firstName": "Mckenna", "lastName": "Rohan", "age": 19 }, { "id": 902, "firstName": "Bradford", "lastName": "Murazik", "age": 2 }, { "id": 903, "firstName": "Rocio", "lastName": "Jakubowski", "age": 38 }, { "id": 904, "firstName": "Fredrick", "lastName": "Daniel", "age": 17 }, { "id": 905, "firstName": "Ewell", "lastName": "Douglas", "age": 8 }, { "id": 906, "firstName": "Darryl", "lastName": "Considine", "age": 3 }, { "id": 907, "firstName": "Cordia", "lastName": "Parisian", "age": 15 }, { "id": 908, "firstName": "Burnice", "lastName": "Veum", "age": 19 }, { "id": 909, "firstName": "Trenton", "lastName": "Lakin-Abbott", "age": 3 }, { "id": 910, "firstName": "Mittie", "lastName": "Kuhn", "age": 6 }, { "id": 911, "firstName": "Dylan", "lastName": "Bashirian", "age": 38 }, { "id": 912, "firstName": "Columbus", "lastName": "Langosh", "age": 9 }, { "id": 913, "firstName": "Gregorio", "lastName": "Schimmel", "age": 22 }, { "id": 914, "firstName": "Fletcher", "lastName": "Rempel", "age": 24 }, { "id": 915, "firstName": "Lincoln", "lastName": "Rowe", "age": 11 }, { "id": 916, "firstName": "Rogelio", "lastName": "Koch", "age": 38 }, { "id": 917, "firstName": "Rosemary", "lastName": "Jerde", "age": 17 }, { "id": 918, "firstName": "Maximus", "lastName": "Quitzon", "age": 16 }, { "id": 919, "firstName": "Robert", "lastName": "Botsford", "age": 22 }, { "id": 920, "firstName": "Brant", "lastName": "Pfannerstill", "age": 25 }, { "id": 921, "firstName": "Maud", "lastName": "Boyle", "age": 21 }, { "id": 922, "firstName": "Sophia", "lastName": "Schmitt", "age": 13 }, { "id": 923, "firstName": "Sibyl", "lastName": "Kub", "age": 25 }, { "id": 924, "firstName": "Myrna", "lastName": "Shields", "age": 34 }, { "id": 925, "firstName": "Melody", "lastName": "Robel", "age": 7 }, { "id": 926, "firstName": "Myah", "lastName": "Sauer", "age": 18 }, { "id": 927, "firstName": "Salvatore", "lastName": "Breitenberg", "age": 30 }, { "id": 928, "firstName": "Casimir", "lastName": "Volkman", "age": 15 }, { "id": 929, "firstName": "Otilia", "lastName": "Littel", "age": 14 }, { "id": 930, "firstName": "Curtis", "lastName": "Hand", "age": 35 }, { "id": 931, "firstName": "Misael", "lastName": "Kling", "age": 29 }, { "id": 932, "firstName": "Laurianne", "lastName": "Sipes", "age": 25 }, { "id": 933, "firstName": "Jennifer", "lastName": "Ortiz", "age": 9 }, { "id": 934, "firstName": "Audreanne", "lastName": "Schamberger", "age": 1 }, { "id": 935, "firstName": "Kiel", "lastName": "Bernier", "age": 26 }, { "id": 936, "firstName": "Aglae", "lastName": "Osinski", "age": 0 }, { "id": 937, "firstName": "Tod", "lastName": "Kuhlman", "age": 20 }, { "id": 938, "firstName": "Verner", "lastName": "Hartmann", "age": 17 }, { "id": 939, "firstName": "Jessyca", "lastName": "Schamberger", "age": 12 }, { "id": 940, "firstName": "Ludwig", "lastName": "Hoppe", "age": 38 }, { "id": 941, "firstName": "Ozella", "lastName": "Kozey", "age": 19 }, { "id": 942, "firstName": "Rebeka", "lastName": "Ledner", "age": 7 }, { "id": 943, "firstName": "Lane", "lastName": "Ratke", "age": 26 }, { "id": 944, "firstName": "Ashtyn", "lastName": "Beer", "age": 21 }, { "id": 945, "firstName": "Jessyca", "lastName": "Baumbach", "age": 17 }, { "id": 946, "firstName": "Jorge", "lastName": "Roberts", "age": 38 }, { "id": 947, "firstName": "Jacey", "lastName": "Zboncak", "age": 18 }, { "id": 948, "firstName": "Demarco", "lastName": "Nicolas", "age": 4 }, { "id": 949, "firstName": "Nathan", "lastName": "Mueller", "age": 21 }, { "id": 950, "firstName": "Francis", "lastName": "Grimes", "age": 26 }, { "id": 951, "firstName": "Eloisa", "lastName": "Nicolas", "age": 37 }, { "id": 952, "firstName": "Harley", "lastName": "Pfannerstill", "age": 2 }, { "id": 953, "firstName": "Gabrielle", "lastName": "Lockman-Conroy", "age": 8 }, { "id": 954, "firstName": "Ignacio", "lastName": "Abernathy", "age": 12 }, { "id": 955, "firstName": "Lexi", "lastName": "Toy", "age": 17 }, { "id": 956, "firstName": "Marietta", "lastName": "Jones", "age": 40 }, { "id": 957, "firstName": "Eliane", "lastName": "Roob", "age": 40 }, { "id": 958, "firstName": "Milan", "lastName": "Corkery", "age": 10 }, { "id": 959, "firstName": "Hubert", "lastName": "D'Amore", "age": 36 }, { "id": 960, "firstName": "Alison", "lastName": "Koelpin", "age": 2 }, { "id": 961, "firstName": "Garrick", "lastName": "Buckridge", "age": 23 }, { "id": 962, "firstName": "Maynard", "lastName": "Ruecker", "age": 30 }, { "id": 963, "firstName": "Charles", "lastName": "Skiles", "age": 7 }, { "id": 964, "firstName": "Jules", "lastName": "Lindgren", "age": 13 }, { "id": 965, "firstName": "Shawn", "lastName": "Stokes", "age": 14 }, { "id": 966, "firstName": "Morgan", "lastName": "Connelly", "age": 15 }, { "id": 967, "firstName": "Mary", "lastName": "Schmidt", "age": 33 }, { "id": 968, "firstName": "Halie", "lastName": "Emmerich", "age": 40 }, { "id": 969, "firstName": "Aubrey", "lastName": "Lynch", "age": 31 }, { "id": 970, "firstName": "Angelita", "lastName": "Blanda-Torphy", "age": 13 }, { "id": 971, "firstName": "Hilbert", "lastName": "Botsford", "age": 31 }, { "id": 972, "firstName": "Shakira", "lastName": "Jakubowski", "age": 37 }, { "id": 973, "firstName": "Montana", "lastName": "Marvin", "age": 31 }, { "id": 974, "firstName": "Eino", "lastName": "Wunsch", "age": 25 }, { "id": 975, "firstName": "Quinten", "lastName": "Berge", "age": 14 }, { "id": 976, "firstName": "Napoleon", "lastName": "Luettgen", "age": 13 }, { "id": 977, "firstName": "Arno", "lastName": "Pagac", "age": 25 }, { "id": 978, "firstName": "Kaden", "lastName": "Mertz", "age": 3 }, { "id": 979, "firstName": "Frank", "lastName": "Jakubowski", "age": 16 }, { "id": 980, "firstName": "Elissa", "lastName": "Skiles", "age": 35 }, { "id": 981, "firstName": "Reinhold", "lastName": "Leannon", "age": 4 }, { "id": 982, "firstName": "Kurtis", "lastName": "Dare", "age": 35 }, { "id": 983, "firstName": "Tyrel", "lastName": "Stiedemann", "age": 9 }, { "id": 984, "firstName": "Turner", "lastName": "Connelly", "age": 18 }, { "id": 985, "firstName": "Katherine", "lastName": "Stamm", "age": 19 }, { "id": 986, "firstName": "Buck", "lastName": "Runolfsdottir", "age": 19 }, { "id": 987, "firstName": "Gerald", "lastName": "Gibson", "age": 33 }, { "id": 988, "firstName": "Janie", "lastName": "Jacobson", "age": 2 }, { "id": 989, "firstName": "Collin", "lastName": "Heller", "age": 9 }, { "id": 990, "firstName": "Merlin", "lastName": "Crist", "age": 34 }, { "id": 991, "firstName": "Rachael", "lastName": "Quigley", "age": 0 }, { "id": 992, "firstName": "Letha", "lastName": "Greenholt", "age": 6 }, { "id": 993, "firstName": "Elvis", "lastName": "Willms", "age": 25 }, { "id": 994, "firstName": "Sherwood", "lastName": "Johnson", "age": 12 }, { "id": 995, "firstName": "Ana", "lastName": "Koch", "age": 33 } ] ================================================ FILE: examples/react/with-tanstack-router/src/api/types.ts ================================================ import type { PaginationState } from '@tanstack/react-table' export type PaginatedData = { result: Array rowCount: number } export type PaginationParams = PaginationState export type SortParams = { sortBy: `${string}.${'asc' | 'desc'}` } export type Filters = Partial ================================================ FILE: examples/react/with-tanstack-router/src/api/user.ts ================================================ import { faker } from '@faker-js/faker' import type { Filters, PaginatedData } from './types' const DEFAULT_PAGE = 0 const DEFAULT_PAGE_SIZE = 10 export type User = { id: number firstName: string lastName: string age: number } export type UserFilters = Filters function makeData(amount: number): Array { return Array(amount) .fill(0) .map((_, index) => { return { id: index + 1, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), } }) } const data = makeData(1000) export async function fetchUsers( filtersAndPagination: UserFilters, ): Promise> { console.log('fetchUsers', filtersAndPagination) const { pageIndex = DEFAULT_PAGE, pageSize = DEFAULT_PAGE_SIZE, sortBy, ...filters } = filtersAndPagination const requestedData = data.slice() if (sortBy) { const [field, order] = sortBy.split('.') requestedData.sort((a, b) => { const aValue = a[field as keyof User] const bValue = b[field as keyof User] if (aValue === bValue) return 0 if (order === 'asc') return aValue > bValue ? 1 : -1 return aValue < bValue ? 1 : -1 }) } const filteredData = requestedData.filter((user) => { return Object.keys(filters).every((key) => { const filter = filters[key as keyof User] if (filter === undefined || filter === '') return true const value = user[key as keyof User] if (typeof value === 'number') return value === +filter return value.toLowerCase().includes(`${filter}`.toLowerCase()) }) }) await new Promise((resolve) => setTimeout(resolve, 100)) return { result: filteredData.slice( pageIndex * pageSize, (pageIndex + 1) * pageSize, ), rowCount: filteredData.length, } } ================================================ FILE: examples/react/with-tanstack-router/src/components/debouncedInput.tsx ================================================ import { useEffect, useState } from 'react' import type { InputHTMLAttributes } from 'react' export function DebouncedInput({ value: initialValue, onChange, debounce = 200, ...props }: { value: string | number onChange: (value: string | number) => void debounce?: number } & Omit, 'onChange'>) { const [value, setValue] = useState(initialValue) useEffect(() => { setValue(initialValue) }, [initialValue]) useEffect(() => { const timeout = setTimeout(() => { onChange(value) }, debounce) return () => clearTimeout(timeout) }, [value]) return ( { if (e.target.value === '') return setValue('') if (props.type === 'number') { setValue(e.target.valueAsNumber) } else { setValue(e.target.value) } }} /> ) } ================================================ FILE: examples/react/with-tanstack-router/src/components/table.tsx ================================================ import { columnFilteringFeature, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, tableFeatures, useTable, } from '@tanstack/react-table' import { useEffect } from 'react' import { DebouncedInput } from './debouncedInput' import type { ColumnDef, OnChangeFn, PaginationState, SortingState, TableOptions_RowPagination, } from '@tanstack/react-table' import type { Filters } from '../api/types' export const _features = tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, }) export const DEFAULT_PAGE_INDEX = 0 export const DEFAULT_PAGE_SIZE = 10 type Props> = { data: Array columns: Array> pagination: PaginationState paginationOptions: Pick< TableOptions_RowPagination, 'onPaginationChange' | 'rowCount' > filters: Filters onFilterChange: (dataFilters: Partial) => void sorting: SortingState onSortingChange: OnChangeFn } export default function Table>({ columns, data, filters, onFilterChange, onSortingChange, pagination, paginationOptions, sorting, }: Props) { const table = useTable( { _features, _rowModels: {}, // no client-side row models since we're doing server-side sorting, filtering, and pagination columns, data, manualFiltering: true, manualPagination: true, manualSorting: true, onSortingChange, ...paginationOptions, }, (state) => state, ) // Sync controlled state with table store useEffect(() => { table.baseStore.setState((prev) => ({ ...prev, pagination, sorting, })) }, [table, pagination, sorting]) return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { const fieldMeta = header.column.columnDef.meta return ( ) })} ))} {table.getRowModel().rows.map((row) => { return ( {row.getAllCells().map((cell) => { return ( ) })} ) })}
{header.isPlaceholder ? null : ( <>
{{ asc: ' 🔼', desc: ' 🔽', false: ' 🔃', }[header.column.getIsSorted() as string] ?? null}
{header.column.getCanFilter() && fieldMeta?.filterKey !== undefined ? ( { onFilterChange({ [fieldMeta.filterKey as keyof T]: value, } as Partial) }} placeholder="Search..." type={ fieldMeta.filterVariant === 'number' ? 'number' : 'text' } value={filters[fieldMeta.filterKey] ?? ''} /> ) : null} )}
Page
{table.store.state.pagination.pageIndex + 1} of{' '} {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} className="border p-1 rounded w-16" />
) } ================================================ FILE: examples/react/with-tanstack-router/src/hooks/useFilters.ts ================================================ import { getRouteApi } from '@tanstack/react-router' import { cleanEmptyParams } from '../utils/cleanEmptyParams' import type { RegisteredRouter, RouteIds } from '@tanstack/react-router' export function useFilters>( routeId: T, ) { const routeApi = getRouteApi(routeId) const navigate = routeApi.useNavigate() const filters = routeApi.useSearch() const setFilters = (partialFilters: Partial) => navigate({ search: (prev) => cleanEmptyParams({ ...prev, ...partialFilters }), replace: true, } as Parameters[0]) const resetFilters = () => { navigate({ search: {}, replace: true, } as Parameters[0]) } return { filters, setFilters, resetFilters } } ================================================ FILE: examples/react/with-tanstack-router/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/react/with-tanstack-router/src/main.tsx ================================================ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' import './index.css' const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( , ) ================================================ FILE: examples/react/with-tanstack-router/src/routeTree.gen.ts ================================================ /* eslint-disable */ // @ts-nocheck // noinspection JSUnusedGlobalSymbols // This file was automatically generated by TanStack Router. // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' import { Route as AnotherRouteRouteImport } from './routes/anotherRoute' import { Route as IndexRouteImport } from './routes/index' const AnotherRouteRoute = AnotherRouteRouteImport.update({ id: '/anotherRoute', path: '/anotherRoute', getParentRoute: () => rootRouteImport, } as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', getParentRoute: () => rootRouteImport, } as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute '/anotherRoute': typeof AnotherRouteRoute } export interface FileRoutesByTo { '/': typeof IndexRoute '/anotherRoute': typeof AnotherRouteRoute } export interface FileRoutesById { __root__: typeof rootRouteImport '/': typeof IndexRoute '/anotherRoute': typeof AnotherRouteRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath fullPaths: '/' | '/anotherRoute' fileRoutesByTo: FileRoutesByTo to: '/' | '/anotherRoute' id: '__root__' | '/' | '/anotherRoute' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute AnotherRouteRoute: typeof AnotherRouteRoute } declare module '@tanstack/react-router' { interface FileRoutesByPath { '/anotherRoute': { id: '/anotherRoute' path: '/anotherRoute' fullPath: '/anotherRoute' preLoaderRoute: typeof AnotherRouteRouteImport parentRoute: typeof rootRouteImport } '/': { id: '/' path: '/' fullPath: '/' preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } } } const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, AnotherRouteRoute: AnotherRouteRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) ._addFileTypes() ================================================ FILE: examples/react/with-tanstack-router/src/routes/__root.tsx ================================================ import { Outlet, createRootRoute } from '@tanstack/react-router' export const Route = createRootRoute({ component: Outlet, }) ================================================ FILE: examples/react/with-tanstack-router/src/routes/anotherRoute.tsx ================================================ import { createFileRoute } from '@tanstack/react-router' // This just exists to validate types are working export const Route = createFileRoute('/anotherRoute')({ validateSearch: () => ({}) as { foo: string; bar: number }, }) ================================================ FILE: examples/react/with-tanstack-router/src/routes/index.tsx ================================================ import { keepPreviousData, useQuery } from '@tanstack/react-query' import { createFileRoute } from '@tanstack/react-router' import { useMemo } from 'react' import { fetchUsers } from '../api/user' import Table, { DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE, } from '../components/table' import { useFilters } from '../hooks/useFilters' import { sortByToState, stateToSortBy } from '../utils/tableSortMapper' import { USER_COLUMNS } from '../utils/userColumns' import type { UserFilters } from '../api/user' export const Route = createFileRoute('/')({ component: UsersPage, validateSearch: () => ({}) as UserFilters, }) function UsersPage() { const { filters, resetFilters, setFilters } = useFilters(Route.fullPath) const { data } = useQuery({ queryKey: ['users', filters], queryFn: () => fetchUsers(filters), placeholderData: keepPreviousData, }) const paginationState = { pageIndex: filters.pageIndex ?? DEFAULT_PAGE_INDEX, pageSize: filters.pageSize ?? DEFAULT_PAGE_SIZE, } const sortingState = sortByToState(filters.sortBy) const columns = useMemo(() => USER_COLUMNS, []) return (

TanStack Table + Query + Router

{ setFilters( typeof pagination === 'function' ? pagination(paginationState) : pagination, ) }, rowCount: data?.rowCount, }} filters={filters} onFilterChange={(filters) => setFilters({ ...filters, pageIndex: DEFAULT_PAGE_INDEX }) } sorting={sortingState} onSortingChange={(updaterOrValue) => { const newSortingState = typeof updaterOrValue === 'function' ? updaterOrValue(sortingState) : updaterOrValue return setFilters({ sortBy: stateToSortBy(newSortingState), pageIndex: DEFAULT_PAGE_INDEX, }) }} />
{data?.rowCount} users found
{JSON.stringify(filters, null, 2)}
) } ================================================ FILE: examples/react/with-tanstack-router/src/utils/cleanEmptyParams.ts ================================================ import { DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE } from '../components/table' export const cleanEmptyParams = >( search: T, ): T => { const newSearch = { ...search } Object.keys(newSearch).forEach((key) => { const value = newSearch[key] if ( value === undefined || value === '' || (typeof value === 'number' && isNaN(value)) ) delete newSearch[key] }) if (search.pageIndex === DEFAULT_PAGE_INDEX) delete newSearch.pageIndex if (search.pageSize === DEFAULT_PAGE_SIZE) delete newSearch.pageSize return newSearch } ================================================ FILE: examples/react/with-tanstack-router/src/utils/tableSortMapper.ts ================================================ import type { SortingState } from '@tanstack/react-table' import type { SortParams } from '../api/types' export const stateToSortBy = (sorting: SortingState | undefined) => { if (!sorting || sorting.length == 0) return undefined const sort = sorting[0] return `${sort.id}.${sort.desc ? 'desc' : 'asc'}` as const } export const sortByToState = (sortBy: SortParams['sortBy'] | undefined) => { if (!sortBy) return [] const [id, desc] = sortBy.split('.') return [{ id, desc: desc === 'desc' }] } ================================================ FILE: examples/react/with-tanstack-router/src/utils/userColumns.tsx ================================================ import type { CellData, ColumnDef, RowData, TableFeatures, } from '@tanstack/react-table' import type { User } from '../api/user' declare module '@tanstack/react-table' { interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { filterKey?: keyof TData filterVariant?: 'text' | 'number' } } export const USER_COLUMNS: Array> = [ { accessorKey: 'id', header: () => ID, meta: { filterKey: 'id', filterVariant: 'number' }, }, { accessorKey: 'firstName', header: () => First Name, meta: { filterKey: 'firstName' }, }, { accessorKey: 'lastName', header: () => Last Name, meta: { filterKey: 'lastName' }, }, { accessorKey: 'age', header: () => 'Age', meta: { filterKey: 'age', filterVariant: 'number' }, }, ] ================================================ FILE: examples/react/with-tanstack-router/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/react/with-tanstack-router/vite.config.js ================================================ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import rollupReplace from '@rollup/plugin-replace' import { TanStackRouterVite } from '@tanstack/router-vite-plugin' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), react(), TanStackRouterVite(), ], }) ================================================ FILE: examples/solid/basic-app-table/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/basic-app-table/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/basic-app-table/index.html ================================================ Solid App
================================================ FILE: examples/solid/basic-app-table/package.json ================================================ { "name": "tanstack-table-example-solid-basic-app-table", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/basic-app-table/src/App.tsx ================================================ import { createTableHook } from '@tanstack/solid-table' import { For, createSignal } from 'solid-js' // This example uses the new `createTableHook` method to create a re-usable table hook factory 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 lastName: string age: number visits: number status: string progress: number } // 2. Create some dummy data with a stable reference (this could be an API response stored in useState or similar) const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 28, visits: 100, status: 'Single', progress: 70, }, ] // 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 { createAppTable, createAppColumnHelper } = createTableHook({ _features: {}, _rowModels: {}, // client-side row models. `Core` row model is now included by default, but you can still override it here debugTable: true, }) // 4. Create a helper object to help define our columns const columnHelper = createAppColumnHelper() // 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, }), ]) export function App() { // 6. Store data with a stable reference const [data, setData] = createSignal([...defaultData]) // Helper to rerender with sorted data (by age ascending) function rerender() { setData((prev) => prev.slice().sort((a: Person, b: Person) => a.age - b.age), ) } // 7. Create the table instance with the required columns and data. // Features and row models are already defined in the createTableHook call above const table = createAppTable({ columns, get data() { return data() }, // add additional table options here or in the createTableHook call above }) // 8. Render your table markup from the table instance APIs return (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )} {(footerGroup) => ( {(header) => ( )} )}
) } ================================================ FILE: examples/solid/basic-app-table/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/basic-app-table/src/index.tsx ================================================ import { render } from 'solid-js/web' import './index.css' import { App } from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/basic-app-table/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/basic-app-table/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/basic-external-state/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/basic-external-state/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/basic-external-state/index.html ================================================ Solid App
================================================ FILE: examples/solid/basic-external-state/package.json ================================================ { "name": "tanstack-table-example-solid-basic-external-state", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/basic-external-state/src/App.tsx ================================================ import { createColumnHelper, createPaginatedRowModel, createSortedRowModel, flexRender, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, createTable, } from '@tanstack/solid-table' import { For, createSignal } from 'solid-js' import { makeData } from './makeData' import type { PaginationState, SortingState } from '@tanstack/solid-table' import type { Person } from './makeData' const _features = tableFeatures({ rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { header: 'Last Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: 'Age', }), columnHelper.accessor('visits', { header: 'Visits', }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', }), ]) function App() { const [data] = createSignal(makeData(1000)) const [sorting, setSorting] = createSignal([]) const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 10, }) const table = createTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, get data() { return data() }, state: { get sorting() { return sorting() }, get pagination() { return pagination() }, }, onSortingChange: setSorting, onPaginationChange: setPagination, }) return (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )}
{header.isPlaceholder ? null : (
{flexRender( header.column.columnDef.header, header.getContext(), )} {{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
Page
{pagination().pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.currentTarget.value ? Number(e.currentTarget.value) - 1 : 0 table.setPageIndex(page) }} class="border p-1 rounded w-16" />
        {JSON.stringify(
          { sorting: sorting(), pagination: pagination() },
          null,
          2,
        )}
      
) } export default App ================================================ FILE: examples/solid/basic-external-state/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/basic-external-state/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/basic-external-state/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/basic-external-state/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/basic-external-state/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/basic-external-store/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/basic-external-store/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/basic-external-store/index.html ================================================ Solid App
================================================ FILE: examples/solid/basic-external-store/package.json ================================================ { "name": "tanstack-table-example-solid-basic-external-store", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/basic-external-store/src/App.tsx ================================================ import { createColumnHelper, createPaginatedRowModel, createSortedRowModel, createTable, flexRender, getInitialTableState, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/solid-table' import { For, createSignal } from 'solid-js' import { makeData } from './makeData' import type { Person } from './makeData' import type { PaginationState, SortingState } from '@tanstack/solid-table' const _features = tableFeatures({ rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { header: 'Last Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: 'Age', }), columnHelper.accessor('visits', { header: 'Visits', }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', }), ]) function App() { const [data] = createSignal(makeData(1000)) const [tableState, setTableState] = createSignal( getInitialTableState(_features, { sorting: [] as SortingState, pagination: { pageIndex: 0, pageSize: 10 } as PaginationState, }), ) const table = createTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), paginatedRowModel: createPaginatedRowModel(), }, columns, get data() { return data() }, state: { get sorting() { return tableState().sorting }, get pagination() { return tableState().pagination }, }, onSortingChange: (updater) => setTableState((prev) => ({ ...prev, sorting: typeof updater === 'function' ? updater(prev.sorting) : updater, })), onPaginationChange: (updater) => setTableState((prev) => ({ ...prev, pagination: typeof updater === 'function' ? updater(prev.pagination) : updater, })), debugTable: true, }) return (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )}
{header.isPlaceholder ? null : (
{flexRender( header.column.columnDef.header, header.getContext(), )} {{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
)}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
Page
{tableState().pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.currentTarget.value ? Number(e.currentTarget.value) - 1 : 0 table.setPageIndex(page) }} class="border p-1 rounded w-16" />
{JSON.stringify(tableState(), null, 2)}
) } export default App ================================================ FILE: examples/solid/basic-external-store/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/basic-external-store/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/basic-external-store/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/basic-external-store/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/basic-external-store/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/basic-use-table/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/basic-use-table/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/basic-use-table/index.html ================================================ Solid App
================================================ FILE: examples/solid/basic-use-table/package.json ================================================ { "name": "tanstack-table-example-solid-basic-use-table", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/basic-use-table/src/App.tsx ================================================ import { createTable, flexRender, tableFeatures } from '@tanstack/solid-table' import { For, createSignal } from 'solid-js' import type { ColumnDef } from '@tanstack/solid-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, { firstName: 'kevin', lastName: 'vandy', age: 12, visits: 100, status: 'Single', progress: 70, }, ] const _features = tableFeatures({}) const columns: Array> = [ { accessorKey: 'firstName', header: 'First Name', cell: (info) => info.getValue(), }, { accessorFn: (row) => row.lastName, id: 'lastName', header: () => Last Name, cell: (info) => {info.getValue()}, }, { accessorFn: (row) => Number(row.age), id: 'age', header: () => 'Age', cell: (info) => info.renderValue(), }, { accessorKey: 'visits', header: () => Visits, }, { accessorKey: 'status', header: 'Status', }, { accessorKey: 'progress', header: 'Profile Progress', }, ] function App() { const [data, setData] = createSignal([...defaultData]) const rerender = () => setData([...defaultData]) const table = createTable({ _features, _rowModels: {}, columns, get data() { return data() }, }) return (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )} {(footerGroup) => ( {(header) => ( )} )}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.footer, header.getContext(), )}
) } export default App ================================================ FILE: examples/solid/basic-use-table/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/basic-use-table/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/basic-use-table/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/basic-use-table/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/column-groups/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/column-groups/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/column-groups/index.html ================================================ Solid App
================================================ FILE: examples/solid/column-groups/package.json ================================================ { "name": "tanstack-table-example-solid-column-groups", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/column-groups/src/App.tsx ================================================ import { For, createSignal } from 'solid-js' import { createTable, flexRender, tableFeatures } from '@tanstack/solid-table' import type { ColumnDef } from '@tanstack/solid-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const _features = tableFeatures({}) const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = createSignal(defaultData) const rerender = () => setData(defaultData) const table = createTable({ _features, get data() { return data() }, columns: defaultColumns, }) return (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )} {(footerGroup) => ( {(header) => ( )} )}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.footer, header.getContext(), )}
) } export default App ================================================ FILE: examples/solid/column-groups/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/column-groups/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/column-groups/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/column-groups/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/column-ordering/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/column-ordering/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/column-ordering/index.html ================================================ Solid App
================================================ FILE: examples/solid/column-ordering/package.json ================================================ { "name": "tanstack-table-example-solid-column-ordering", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/column-ordering/src/App.tsx ================================================ import { For, Show, createSignal } from 'solid-js' import { faker } from '@faker-js/faker' import { columnOrderingFeature, columnVisibilityFeature, createTable, flexRender, tableFeatures, } from '@tanstack/solid-table' import { makeData } from './makeData' import type { Person } from './makeData' import type { ColumnDef } from '@tanstack/solid-table' const _features = tableFeatures({ columnOrderingFeature, columnVisibilityFeature, }) const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = createSignal(makeData(20)) const rerender = () => setData(() => makeData(20)) const table = createTable({ _features, get data() { return data() }, columns: defaultColumns, }) const randomizeColumns = () => { table.setColumnOrder( faker.helpers.shuffle(table.getAllLeafColumns().map((d) => d.id)), ) } return ( ({ columnOrder: state.columnOrder, columnVisibility: state.columnVisibility, })} > {(_state) => (
{(column) => (
)}
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )} {(footerGroup) => ( {(header) => ( )} )}
{flexRender( header.column.columnDef.header, header.getContext(), )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{flexRender( header.column.columnDef.footer, header.getContext(), )}
state}> {(state) =>
{JSON.stringify(state(), null, 2)}
}
)} ) } export default App ================================================ FILE: examples/solid/column-ordering/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/column-ordering/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/column-ordering/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/column-ordering/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/column-ordering/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/column-visibility/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/column-visibility/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/column-visibility/index.html ================================================ Solid App
================================================ FILE: examples/solid/column-visibility/package.json ================================================ { "name": "tanstack-table-example-solid-column-visibility", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/column-visibility/src/App.tsx ================================================ import { columnVisibilityFeature, createTable, flexRender, tableFeatures, } from '@tanstack/solid-table' import { For, Show, createSignal } from 'solid-js' import type { ColumnDef } from '@tanstack/solid-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const _features = tableFeatures({ columnVisibilityFeature }) const defaultColumns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = createSignal(defaultData) const rerender = () => setData(defaultData) const table = createTable({ _features, get data() { return data() }, columns: defaultColumns, }) return ( ({ columnVisibility: state.columnVisibility })} > {(state) => (
{(column) => (
)}
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )} {(footerGroup) => ( {(header) => ( )} )}
{flexRender( header.column.columnDef.header, header.getContext(), )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{flexRender( header.column.columnDef.footer, header.getContext(), )}
state}> {(state) =>
{JSON.stringify(state(), null, 2)}
}
)} ) } export default App ================================================ FILE: examples/solid/column-visibility/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/column-visibility/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/column-visibility/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/column-visibility/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/composable-tables/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/composable-tables/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/composable-tables/index.html ================================================ Solid App
================================================ FILE: examples/solid/composable-tables/package.json ================================================ { "name": "tanstack-table-example-solid-composable-tables", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/composable-tables/src/App.tsx ================================================ import { For, createSignal } from 'solid-js' import { createAppColumnHelper, createAppTable } from './hooks/table' import { makeData, makeProductData } from './makeData' import type { Person, Product } from './makeData' // Import cell components directly - they use useCellContext internally // Create column helpers with TFeatures already bound - only need TData! const personColumnHelper = createAppColumnHelper() const productColumnHelper = createAppColumnHelper() // Users Table Component - Original implementation function UsersTable() { // Data state const [data, setData] = createSignal(makeData(1000)) // Refresh data callback const refreshData = () => { setData(() => makeData(1000)) } // Define columns using the column helper const columns = // NOTE: You must use `createAppColumnHelper` instead of `createColumnHelper` when using pre-bound components like personColumnHelper.columns([ personColumnHelper.accessor('firstName', { header: 'First Name', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('lastName', { header: 'Last Name', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('age', { header: 'Age', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('visits', { header: 'Visits', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('status', { header: 'Status', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.accessor('progress', { header: 'Progress', footer: (props) => props.column.id, cell: ({ cell }) => , }), personColumnHelper.display({ id: 'actions', header: 'Actions', cell: ({ cell }) => , }), ]) // Create the table - _features and _rowModels are already configured! const table = createAppTable({ columns, get data() { return data() }, debugTable: true, // more table options }) return ( // Main selector on AppTable - selects all needed state in one place ({ // subscribe to specific states for re-rendering if you are optimizing for maximum performance pagination: state.pagination, sorting: state.sorting, columnFilters: state.columnFilters, })} > {(state) => { const sorting = () => state().sorting const columnFilters = () => state().columnFilters return (
{/* Table toolbar using pre-bound component */} {/* Table element */} {(headerGroup) => ( {(h) => ( {(header) => ( )} )} )} {(row) => ( {(c) => ( {(cell) => ( )} )} )} {(footerGroup) => ( {(f) => ( {(footer) => { const columnId = footer.column.id const hasFilter = () => columnFilters().some((cf) => cf.id === columnId) return ( ) }} )} )}
{header.isPlaceholder ? null : ( <> {/* Show sort order number when multiple columns sorted */} {sorting().length > 1 && sorting().findIndex( (s) => s.id === header.column.id, ) > -1 && ( {sorting().findIndex( (s) => s.id === header.column.id, ) + 1} )} )}
{/* Cell components are pre-bound via AppCell */}
{footer.isPlaceholder ? null : ( <> {/* Use FooterSum for numeric columns, FooterColumnId for others */} {columnId === 'age' || columnId === 'visits' || columnId === 'progress' ? ( <> {hasFilter() && ( {' '} (filtered) )} ) : columnId === 'actions' ? null : ( <> {hasFilter() && ( {' '} ✓ )} )} )}
{/* Pagination using pre-bound component */} {/* Row count using pre-bound component */}
) }}
) } // Products Table Component - New implementation using same hook and components function ProductsTable() { // Data state const [data, setData] = createSignal(makeProductData(500)) // Refresh data callback const refreshData = () => { setData(makeProductData(500)) } // Define columns using the column helper - different structure than Users table const columns = productColumnHelper.columns([ productColumnHelper.accessor('name', { header: 'Product Name', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('category', { header: 'Category', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('price', { header: 'Price', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('stock', { header: 'In Stock', footer: (props) => props.column.id, cell: ({ cell }) => , }), productColumnHelper.accessor('rating', { header: 'Rating', footer: (props) => props.column.id, cell: ({ cell }) => , }), ]) // Create the table using the same createAppTable hook const table = createAppTable({ columns, get data() { return data() }, getRowId: (row) => row.id, }) return ( ({ pagination: state.pagination, sorting: state.sorting, columnFilters: state.columnFilters, })} > {(state) => { const sorting = () => state().sorting const columnFilters = () => state().columnFilters return (
{/* Table toolbar using the same pre-bound component */} {/* Table element */} {(headerGroup) => ( {(h) => ( {(header) => ( )} )} )} {(row) => ( {(c) => ( {(cell) => ( )} )} )} {(footerGroup) => ( {(f) => ( {(footer) => { const columnId = footer.column.id const hasFilter = () => columnFilters().some((cf) => cf.id === columnId) return ( ) }} )} )}
{header.isPlaceholder ? null : ( <> {sorting().length > 1 && sorting().findIndex( (s) => s.id === header.column.id, ) > -1 && ( {sorting().findIndex( (s) => s.id === header.column.id, ) + 1} )} )}
{/* Cell components are pre-bound via AppCell */}
{footer.isPlaceholder ? null : ( <> {/* Use FooterSum for numeric columns, FooterColumnId for others */} {columnId === 'price' || columnId === 'stock' || columnId === 'rating' ? ( <> {hasFilter() && ( {' '} (filtered) )} ) : ( <> {hasFilter() && ( {' '} ✓ )} )} )}
{/* Pagination using the same pre-bound component */} {/* Row count using the same pre-bound component */}
) }}
) } function App() { return (

Composable Tables Example

Both tables below use the same createAppTable hook and shareable components, but with different data types and column configurations.

{/* Original Users Table */}
{/* New Products Table */}
) } export default App ================================================ FILE: examples/solid/composable-tables/src/components/cell-components.tsx ================================================ /** * Cell-level components that use useCellContext * * These components can be used via the pre-bound cellComponents * in AppCell children, e.g., */ import { useCellContext } from '../hooks/table' /** * Generic text cell renderer */ export function TextCell() { const cell = useCellContext() return {cell.getValue()} } /** * Number cell with locale formatting */ export function NumberCell() { const cell = useCellContext() return {cell.getValue().toLocaleString()} } /** * Status badge cell for status column */ export function StatusCell() { const cell = useCellContext<'relationship' | 'complicated' | 'single'>() const status = cell.getValue() return {status} } /** * Progress bar cell */ export function ProgressCell() { const cell = useCellContext() const progress = cell.getValue() return (
) } /** * Row actions cell - actions for the current row */ export function RowActionsCell() { const cell = useCellContext() const row = cell.row return (
) } /** * Price cell with currency formatting */ export function PriceCell() { const cell = useCellContext() return ( $ {cell.getValue().toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, })} ) } /** * Category badge cell */ export function CategoryCell() { const cell = useCellContext<'electronics' | 'clothing' | 'food' | 'books'>() const category = cell.getValue() return {category} } ================================================ FILE: examples/solid/composable-tables/src/components/header-components.tsx ================================================ /** * Header-level components that use useHeaderContext * * These components can be used via the pre-bound headerComponents * in AppHeader children, e.g., */ import { Show } from 'solid-js' import { useHeaderContext } from '../hooks/table' /** * Sort indicator showing current sort direction */ export function SortIndicator() { const header = useHeaderContext() const sorted = () => header.column.getIsSorted() return ( {(sorted) => ( {sorted() === 'asc' ? '🔼' : '🔽'} )} ) } /** * Column filter input */ export function ColumnFilter() { const header = useHeaderContext() const canFilter = () => header.column.getCanFilter() const columnFilterValue = () => (header.column.getFilterValue() ?? '') as string return (
e.stopPropagation()}> header.column.setFilterValue(e.target.value)} placeholder={`Filter ${header.column.id}...`} />
) } /** * Footer showing the column ID */ export function FooterColumnId() { const header = useHeaderContext() return {header.column.id} } /** * Footer showing a summary/aggregation for numeric columns */ export function FooterSum() { const header = useHeaderContext() const table = header.getContext().table const rows = table.getFilteredRowModel().rows // Calculate sum for numeric columns const sum = () => rows.reduce((acc, row) => { const value = row.getValue(header.column.id) return acc + (typeof value === 'number' ? value : 0) }, 0) return ( {sum() > 0 ? sum().toLocaleString() : '—'} ) } ================================================ FILE: examples/solid/composable-tables/src/components/table-components.tsx ================================================ /** * Table-level components that use useTableContext * * These components can be used via the pre-bound tableComponents * directly on the table object, e.g., */ import { For, createMemo } from 'solid-js' import { useTableContext } from '../hooks/table' /** * Pagination controls for the table */ export function PaginationControls() { const table = useTableContext() const pagination = createMemo(() => table.store.state.pagination) return ( ) } /** * Row count display */ export function RowCount() { const table = useTableContext() return (
Showing {table.getRowModel().rows.length.toLocaleString()} of{' '} {table.getRowCount().toLocaleString()} rows
) } /** * Table toolbar with title and actions */ export function TableToolbar({ title, onRefresh, }: { title: string onRefresh?: () => void }) { const table = useTableContext() return (

{title}

{onRefresh && }
) } ================================================ FILE: examples/solid/composable-tables/src/hooks/table.ts ================================================ /** * Custom table hook setup using createTableHook * * This file creates a custom useAppTable hook with pre-bound components. * Features, row models, and default options are defined once here and shared across all tables. * Context hooks and a pre-bound createAppColumnHelper are also exported. */ import { columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, createTableHook, filterFns, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/solid-table' // Import table-level components import { PaginationControls, RowCount, TableToolbar, } from '../components/table-components' // Import cell-level components import { CategoryCell, NumberCell, PriceCell, ProgressCell, RowActionsCell, StatusCell, TextCell, } from '../components/cell-components' // Import header/footer-level components (both use useHeaderContext) import { ColumnFilter, FooterColumnId, FooterSum, SortIndicator, } from '../components/header-components' /** * Create the custom table hook with all pre-bound components. * This exports: * - createAppColumnHelper: Create column definitions with TFeatures already bound * - useAppTable: Hook for creating tables with TFeatures baked in * - useTableContext: Access table instance in tableComponents * - useCellContext: Access cell instance in cellComponents * - useHeaderContext: Access header instance in headerComponents */ export const { createAppColumnHelper, createAppTable, useTableContext, useCellContext, useHeaderContext, } = createTableHook({ // Features are set once here and shared across all tables _features: tableFeatures({ columnFilteringFeature, rowPaginationFeature, rowSortingFeature, }), // Row models are set once here _rowModels: { sortedRowModel: createSortedRowModel(sortFns), filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, // set any default table options here too getRowId: (row) => row.id, // Register table-level components (accessible via table.ComponentName) tableComponents: { PaginationControls, RowCount, TableToolbar, }, // Register cell-level components (accessible via cell.ComponentName in AppCell) cellComponents: { TextCell, NumberCell, StatusCell, ProgressCell, RowActionsCell, PriceCell, CategoryCell, }, // Register header/footer-level components (accessible via header.ComponentName in AppHeader/AppFooter) headerComponents: { SortIndicator, ColumnFilter, FooterColumnId, FooterSum, }, }) ================================================ FILE: examples/solid/composable-tables/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; border-collapse: collapse; width: 100%; } tbody { border-bottom: 1px solid lightgray; } th, td { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 8px 12px; text-align: left; } th { background-color: #f5f5f5; font-weight: 600; } tfoot { color: gray; } tfoot th { font-weight: normal; } .table-container { padding: 16px; max-width: 1200px; margin: 0 auto; } .pagination { display: flex; align-items: center; gap: 8px; margin-top: 16px; flex-wrap: wrap; } .pagination button { border: 1px solid #ccc; border-radius: 4px; padding: 4px 8px; cursor: pointer; background: white; } .pagination button:disabled { opacity: 0.5; cursor: not-allowed; } .pagination input { border: 1px solid #ccc; border-radius: 4px; padding: 4px; width: 64px; } .pagination select { border: 1px solid #ccc; border-radius: 4px; padding: 4px; } .sort-indicator { margin-left: 4px; } .column-filter { margin-top: 4px; } .column-filter input { border: 1px solid #ccc; border-radius: 4px; padding: 4px; width: 100%; font-size: 12px; } .sortable-header { cursor: pointer; user-select: none; } .sortable-header:hover { background-color: #e8e8e8; } .row-actions { display: flex; gap: 4px; } .row-actions button { border: 1px solid #ccc; border-radius: 4px; padding: 2px 8px; cursor: pointer; background: white; font-size: 12px; } .row-actions button:hover { background-color: #f0f0f0; } .status-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; } .status-badge.relationship { background-color: #d4edda; color: #155724; } .status-badge.complicated { background-color: #fff3cd; color: #856404; } .status-badge.single { background-color: #cce5ff; color: #004085; } .progress-bar { width: 100%; height: 8px; background-color: #e9ecef; border-radius: 4px; overflow: hidden; } .progress-bar-fill { height: 100%; background-color: #007bff; transition: width 0.2s; } .table-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 8px; } .table-toolbar h2 { margin: 0; } .table-toolbar button { border: 1px solid #ccc; border-radius: 4px; padding: 8px 16px; cursor: pointer; background: white; } .table-toolbar button:hover { background-color: #f0f0f0; } .row-count { color: #666; font-size: 14px; margin-top: 8px; } .app { padding: 16px; } .app h1 { text-align: center; margin-bottom: 8px; } .description { text-align: center; color: #666; margin-bottom: 32px; } .description code { background-color: #f5f5f5; padding: 2px 6px; border-radius: 4px; font-size: 13px; } .table-divider { height: 48px; border-bottom: 1px solid #e0e0e0; margin: 32px auto; max-width: 1200px; } .category-badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; text-transform: capitalize; } .category-badge.electronics { background-color: #e3f2fd; color: #1565c0; } .category-badge.clothing { background-color: #fce4ec; color: #c2185b; } .category-badge.food { background-color: #e8f5e9; color: #2e7d32; } .category-badge.books { background-color: #fff8e1; color: #f57c00; } .price { font-weight: 600; color: #2e7d32; } ================================================ FILE: examples/solid/composable-tables/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/composable-tables/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } export type Product = { id: string name: string category: 'electronics' | 'clothing' | 'food' | 'books' price: number stock: number rating: number } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } const newProduct = (): Product => { return { id: faker.string.uuid(), name: faker.commerce.productName(), category: faker.helpers.shuffle([ 'electronics', 'clothing', 'food', 'books', ])[0], price: parseFloat(faker.commerce.price({ min: 5, max: 500 })), stock: faker.number.int({ min: 0, max: 200 }), rating: faker.number.int({ min: 0, max: 100 }), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } export function makeProductData(count: number): Array { return range(count).map(() => newProduct()) } ================================================ FILE: examples/solid/composable-tables/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/composable-tables/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/filters/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/filters/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/filters/index.html ================================================ Solid App
================================================ FILE: examples/solid/filters/package.json ================================================ { "name": "tanstack-table-example-solid-filters", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@solid-primitives/scheduled": "^1.5.2", "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/filters/src/App.tsx ================================================ import { columnFacetingFeature, columnFilteringFeature, createFacetedMinMaxValues, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createTable, filterFns, flexRender, globalFilteringFeature, tableFeatures, } from '@tanstack/solid-table' import { debounce } from '@solid-primitives/scheduled' import { For, createSignal } from 'solid-js' import { makeData } from './makeData' import ColumnFilter from './ColumnFilter' import type { Person } from './makeData' import type { ColumnDef } from '@tanstack/solid-table' export const _features = tableFeatures({ columnFilteringFeature, globalFilteringFeature, columnFacetingFeature, }) const columns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, filterFn: 'inNumberRange', }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, filterFn: 'inNumberRange', }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, filterFn: 'inNumberRange', }, ], }, ], }, ] function App() { const [data, setData] = createSignal(makeData(1_000)) const refreshData = () => setData(makeData(50_000)) // stress test const table = createTable({ _features, _rowModels: { facetedRowModel: createFacetedRowModel(), facetedMinMaxValues: createFacetedMinMaxValues(), facetedUniqueValues: createFacetedUniqueValues(), filteredRowModel: createFilteredRowModel(filterFns), }, get data() { return data() }, columns, globalFilterFn: 'includesString', debugTable: true, debugHeaders: true, debugColumns: false, }) const debounceSetGlobalFilter = debounce((value: string) => { table.setGlobalFilter(value) }, 500) return ( ({ columnFilters: state.columnFilters, globalFilter: state.globalFilter, })} > {(state) => (
debounceSetGlobalFilter(e.currentTarget.value)} placeholder="Search all columns..." />
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )}
{header.isPlaceholder ? null : ( <> {flexRender( header.column.columnDef.header, header.getContext(), )} {header.column.getCanFilter() ? (
) : null} )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{table.getRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state(), null, 2)}
}
)} ) } export default App ================================================ FILE: examples/solid/filters/src/ColumnFilter.tsx ================================================ import { debounce } from '@solid-primitives/scheduled' import { Show } from 'solid-js' import type { Person } from './makeData' import type { _features } from './App' import type { Column, Table } from '@tanstack/solid-table' function ColumnFilter(props: { column: Column table: Table }) { const firstValue = props.table .getPreFilteredRowModel() .flatRows[0]?.getValue(props.column.id) const columnFilterValue = () => props.column.getFilterValue() return ( props.column.setFilterValue(e.target.value), 500, )} placeholder={`Search...`} class="w-36 border shadow rounded" list={`${props.column.id}list`} />
} >
props.column.setFilterValue( (old: [number, number] | undefined) => [ e.target.value, old?.[1] ?? '', ], ), 500, )} placeholder={`Min`} class="w-24 border shadow rounded" /> props.column.setFilterValue( (old: [number, number] | undefined) => [ old?.[0] ?? '', e.target.value, ], ), 500, )} placeholder={`Max`} class="w-24 border shadow rounded" />
) } export default ColumnFilter ================================================ FILE: examples/solid/filters/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/filters/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/filters/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/filters/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/filters/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/filters-faceted/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/filters-faceted/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/filters-faceted/index.html ================================================ Solid App
================================================ FILE: examples/solid/filters-faceted/package.json ================================================ { "name": "tanstack-table-example-solid-filters-faceted", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@solid-primitives/scheduled": "^1.5.2", "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/filters-faceted/src/App.tsx ================================================ import { columnFacetingFeature, columnFilteringFeature, createFacetedMinMaxValues, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createTable, filterFns, flexRender, globalFilteringFeature, tableFeatures, } from '@tanstack/solid-table' import { debounce } from '@solid-primitives/scheduled' import { For, createSignal } from 'solid-js' import { makeData } from './makeData' import ColumnFilter from './ColumnFilter' import type { Person } from './makeData' import type { ColumnDef } from '@tanstack/solid-table' export const _features = tableFeatures({ columnFilteringFeature, globalFilteringFeature, columnFacetingFeature, }) const columns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = createSignal(makeData(1_000)) const refreshData = () => setData(makeData(50_000)) // stress test const table = createTable({ _features, _rowModels: { facetedRowModel: createFacetedRowModel(), facetedMinMaxValues: createFacetedMinMaxValues(), facetedUniqueValues: createFacetedUniqueValues(), filteredRowModel: createFilteredRowModel(filterFns), }, get data() { return data() }, columns, globalFilterFn: 'includesString', debugTable: true, debugHeaders: true, debugColumns: false, }) const debounceSetGlobalFilter = debounce((value: string) => { table.setGlobalFilter(value) }, 500) return ( ({ columnFilters: state.columnFilters, globalFilter: state.globalFilter, })} > {(state) => (
debounceSetGlobalFilter(e.currentTarget.value)} placeholder="Search all columns..." />
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )}
{header.isPlaceholder ? null : ( <> {flexRender( header.column.columnDef.header, header.getContext(), )} {header.column.getCanFilter() ? (
) : null} )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{table.getRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state(), null, 2)}
}
)} ) } export default App ================================================ FILE: examples/solid/filters-faceted/src/ColumnFilter.tsx ================================================ import { debounce } from '@solid-primitives/scheduled' import { For, Show, createMemo } from 'solid-js' import type { Person } from './makeData' import type { _features } from './App' import type { Column, Table } from '@tanstack/solid-table' function ColumnFilter(props: { column: Column table: Table }) { const firstValue = props.table .getPreFilteredRowModel() .flatRows[0]?.getValue(props.column.id) const columnFilterValue = () => props.column.getFilterValue() const sortedUniqueValues = createMemo(() => typeof firstValue === 'number' ? [] : Array.from(props.column.getFacetedUniqueValues().keys()).sort(), ) return ( {(value: string) => props.column.setFilterValue(e.target.value), 500, )} placeholder={`Search... (${props.column.getFacetedUniqueValues().size})`} class="w-36 border shadow rounded" list={`${props.column.id}list`} />
} >
props.column.setFilterValue((old: [number, number]) => [ e.target.value, old[1], ]), 500, )} placeholder={`Min ${ props.column.getFacetedMinMaxValues()?.[0] ? `(${props.column.getFacetedMinMaxValues()?.[0]})` : '' }`} class="w-24 border shadow rounded" /> props.column.setFilterValue((old: [number, number]) => [ old[0], e.target.value, ]), 500, )} placeholder={`Max ${ props.column.getFacetedMinMaxValues()?.[1] ? `(${props.column.getFacetedMinMaxValues()?.[1]})` : '' }`} class="w-24 border shadow rounded" />
) } export default ColumnFilter ================================================ FILE: examples/solid/filters-faceted/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/filters-faceted/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/filters-faceted/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/filters-faceted/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/filters-faceted/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/row-selection/README.md ================================================ # Row Selection Example This example demonstrates row selection functionality with TanStack Table in SolidJS. ## Features - Row selection with checkboxes - Select all / deselect all functionality - Page-level row selection - Filtering and pagination with row selection - Fine-grained reactivity using `table.Subscribe` for optimal performance ## Running the Example - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/row-selection/index.html ================================================ Solid Row Selection Example
================================================ FILE: examples/solid/row-selection/package.json ================================================ { "name": "tanstack-table-example-solid-row-selection", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-devtools": "^0.7.26", "@tanstack/solid-table": "^9.0.0-alpha.10", "@tanstack/solid-table-devtools": "workspace:*", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/row-selection/src/App.tsx ================================================ import type { Column, ColumnDef, SolidTable, Table, } from '@tanstack/solid-table' import { columnFilteringFeature, createFilteredRowModel, createPaginatedRowModel, createTable, filterFns, flexRender, globalFilteringFeature, rowPaginationFeature, rowSelectionFeature, tableFeatures, } from '@tanstack/solid-table' import { For, Show, createEffect, createSignal } from 'solid-js' import type { Person } from './makeData' import { makeData } from './makeData' import './index.css' import { TanStackDevtools } from '@tanstack/solid-devtools' import { tableDevtoolsPlugin } from '@tanstack/solid-table-devtools' export const _features = tableFeatures({ rowPaginationFeature, rowSelectionFeature, columnFilteringFeature, globalFilteringFeature, }) function App() { const [data, setData] = createSignal(makeData(1_000)) const refreshData = () => setData(makeData(100_000)) // stress test const [enableRowSelection, setEnableRowSelection] = createSignal(true) // Create table first with a placeholder for columns let table: SolidTable const columns: Array> = [ { id: 'select', header: () => { return ( state.rowSelection}> {() => ( )} ) }, cell: ({ row }) => { return (
) }, }, { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] table = createTable({ _features, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), paginatedRowModel: createPaginatedRowModel(), }, get data() { return data() }, columns, getRowId: (row) => row.id, get enableRowSelection() { return enableRowSelection() }, debugTable: true, }) return ( // ({ // // don't include row selection state to optimize re-renders // columnFilters: state.columnFilters, // globalFilter: state.globalFilter, // pagination: state.pagination, // })} // > // {(state) => (
({ globalFilter: state.globalFilter })} > {(state) => ( table.setGlobalFilter(e.target.value)} class="p-2 font-lg shadow border border-block" placeholder="Search all columns..." /> )}
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( state.rowSelection[row.id]} // only re-render row when row selection changes (could down move to cell render too) > {() => ( {(cell) => ( )} )} )}
<> {flexRender( header.column.columnDef.header, header.getContext(), )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
state.rowSelection}> {() => ( )} Page Rows ({table.getRowModel().rows.length})
({ pagination: state.pagination })} > {(state) => ( <>
Page
{state().pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} class="border p-1 rounded w-16" /> )}

({ numSelected: Object.keys(state.rowSelection).length, })} > {(state) => <>{state().numSelected} of } {table.getPreFilteredRowModel().rows.length} Total Rows Selected


state}> {(state) =>
{JSON.stringify(state(), null, 2)}
}
) } function Filter(props: { column: Column table: Table }) { const firstValue = props.table .getPreFilteredRowModel() .flatRows[0]?.getValue(props.column.id) return typeof firstValue === 'number' ? (
props.column.setFilterValue((old: any) => [e.target.value, old?.[1]]) } placeholder={`Min`} class="w-24 border shadow rounded" /> props.column.setFilterValue((old: any) => [old?.[0], e.target.value]) } placeholder={`Max`} class="w-24 border shadow rounded" />
) : ( props.column.setFilterValue(e.target.value)} placeholder={`Search...`} class="w-36 border shadow rounded" /> ) } function IndeterminateCheckbox(props: { indeterminate?: boolean class?: string checked?: boolean disabled?: boolean onChange?: (event: Event) => void }) { let ref: HTMLInputElement | undefined createEffect(() => { if (typeof props.indeterminate === 'boolean' && ref) { ref.indeterminate = !props.checked && props.indeterminate } }) return ( ) } export default App ================================================ FILE: examples/solid/row-selection/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/row-selection/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/row-selection/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: string firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { id: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/row-selection/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/row-selection/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/sorting/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/sorting/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/sorting/index.html ================================================ Solid App
================================================ FILE: examples/solid/sorting/package.json ================================================ { "name": "tanstack-table-example-solid-sorting", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/sorting/src/App.tsx ================================================ import { createSortedRowModel, createTable, flexRender, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/solid-table' import { For, Show, createSignal } from 'solid-js' import { makeData } from './makeData' import type { ColumnDef } from '@tanstack/solid-table' import type { Person } from './makeData' const _features = tableFeatures({ rowSortingFeature }) function App() { const [data, setData] = createSignal(makeData(1_000)) const refreshData = () => setData(makeData(100_000)) // stress test const columns: Array> = [ { header: 'Name', footer: (props) => props.column.id, columns: [ { accessorKey: 'firstName', cell: (info) => info.getValue(), footer: (props) => props.column.id, }, { accessorFn: (row) => row.lastName, id: 'lastName', cell: (info) => info.getValue(), header: () => Last Name, footer: (props) => props.column.id, }, ], }, { header: 'Info', footer: (props) => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: (props) => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => Visits, footer: (props) => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: (props) => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: (props) => props.column.id, }, ], }, ], }, ] const table = createTable({ _features, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), }, get data() { return data() }, columns, debugTable: true, }) return ( ({ sorting: state.sorting })}> {(_state) => (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )}
{flexRender( header.column.columnDef.header, header.getContext(), )} {{ asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? null}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
{table.getRowModel().rows.length} Rows
state}> {(state) =>
{JSON.stringify(state(), null, 2)}
}
)}
) } export default App ================================================ FILE: examples/solid/sorting/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/sorting/src/index.tsx ================================================ /* @refresh reload */ import { render } from 'solid-js/web' import './index.css' import App from './App' render(() => , document.getElementById('root') as HTMLElement) ================================================ FILE: examples/solid/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/solid/sorting/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/sorting/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', polyfillDynamicImport: false, }, }) ================================================ FILE: examples/solid/with-tanstack-query/.gitignore ================================================ node_modules dist ================================================ FILE: examples/solid/with-tanstack-query/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/solid/with-tanstack-query/index.html ================================================ Solid App
================================================ FILE: examples/solid/with-tanstack-query/package.json ================================================ { "name": "tanstack-table-example-solid-with-tanstack-query", "version": "0.0.0", "description": "", "scripts": { "start": "vite", "dev": "vite", "build": "vite build", "serve": "vite preview", "lint": "eslint ./src" }, "license": "MIT", "devDependencies": { "@faker-js/faker": "^10.2.0", "typescript": "5.9.3", "vite": "^7.3.1", "vite-plugin-solid": "^2.11.10" }, "dependencies": { "@tanstack/solid-query": "^5.90.20", "@tanstack/solid-store": "^0.9.2", "@tanstack/solid-table": "^9.0.0-alpha.10", "solid-js": "^1.9.11" } } ================================================ FILE: examples/solid/with-tanstack-query/src/App.tsx ================================================ import { keepPreviousData, useQuery } from '@tanstack/solid-query' import { createStore, useStore } from '@tanstack/solid-store' import { createColumnHelper, createTable, flexRender, getInitialTableState, rowPaginationFeature, tableFeatures, } from '@tanstack/solid-table' import { For } from 'solid-js' import { fetchData } from './fetchData' import type { Person } from './fetchData' const _features = tableFeatures({ rowPaginationFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { header: 'First Name', cell: (info) => info.getValue(), }), columnHelper.accessor('lastName', { header: 'Last Name', cell: (info) => info.getValue(), }), columnHelper.accessor('age', { header: 'Age', }), columnHelper.accessor('visits', { header: 'Visits', }), columnHelper.accessor('status', { header: 'Status', }), columnHelper.accessor('progress', { header: 'Profile Progress', }), ]) const myTableStore = createStore( getInitialTableState(_features, { pagination: { pageIndex: 0, pageSize: 10 }, }), ) function App() { const state = useStore(myTableStore) const dataQuery = useQuery(() => ({ queryKey: ['data', state().pagination], queryFn: () => fetchData(state().pagination), placeholderData: keepPreviousData, })) const defaultData: Array = [] const table = createTable({ _features, _rowModels: {}, columns, get data() { return dataQuery.data?.rows ?? defaultData }, get rowCount() { return dataQuery.data?.rowCount }, store: myTableStore, manualPagination: true, debugTable: true, }) return (
{(headerGroup) => ( {(header) => ( )} )} {(row) => ( {(cell) => ( )} )}
{header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext(), )}
{flexRender( cell.column.columnDef.cell, cell.getContext(), )}
Page
{state().pagination.pageIndex + 1} of{' '} {table.getPageCount().toLocaleString()}
| Go to page: { const page = e.currentTarget.value ? Number(e.currentTarget.value) - 1 : 0 table.setPageIndex(page) }} class="border p-1 rounded w-16" /> {dataQuery.isFetching ? 'Loading...' : null}
Showing {table.getRowModel().rows.length.toLocaleString()} of{' '} {dataQuery.data?.rowCount.toLocaleString()} Rows
{JSON.stringify(state(), null, 2)}
) } export default App ================================================ FILE: examples/solid/with-tanstack-query/src/fetchData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } const data = makeData(10000) export async function fetchData(options: { pageIndex: number pageSize: number }) { await new Promise((resolve) => setTimeout(resolve, 500)) return { rows: data.slice( options.pageIndex * options.pageSize, (options.pageIndex + 1) * options.pageSize, ), pageCount: Math.ceil(data.length / options.pageSize), rowCount: data.length, } } ================================================ FILE: examples/solid/with-tanstack-query/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/solid/with-tanstack-query/src/index.tsx ================================================ import { render } from 'solid-js/web' import { QueryClient, QueryClientProvider } from '@tanstack/solid-query' import './index.css' import App from './App' const queryClient = new QueryClient() render( () => ( ), document.getElementById('root') as HTMLElement, ) ================================================ FILE: examples/solid/with-tanstack-query/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "solid-js", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/solid/with-tanstack-query/vite.config.ts ================================================ import { defineConfig } from 'vite' import solidPlugin from 'vite-plugin-solid' export default defineConfig({ plugins: [solidPlugin()], build: { target: 'esnext', }, }) ================================================ FILE: examples/svelte/basic/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/basic/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/basic/index.html ================================================ Vite App
================================================ FILE: examples/svelte/basic/package.json ================================================ { "name": "tanstack-table-example-svelte-basic", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/basic/src/App.svelte ================================================
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getRowModel().rows as row} {#each row.getAllCells() as cell} {/each} {/each} {#each table.getFooterGroups() as footerGroup} {#each footerGroup.headers as header} {/each} {/each}
{#if !header.isPlaceholder} {/if}
{#if !header.isPlaceholder} {/if}
================================================ FILE: examples/svelte/basic/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/basic/src/main.ts ================================================ // @ts-ignore - Svelte type definitions are not properly recognized import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/basic/src/vite-env.d.ts ================================================ /// /// ================================================ FILE: examples/svelte/basic/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/basic/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/basic/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/basic-snippets/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/basic-snippets/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/basic-snippets/index.html ================================================ Vite App
================================================ FILE: examples/svelte/basic-snippets/package.json ================================================ { "name": "tanstack-table-example-svelte-basic-snippets", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/basic-snippets/src/App.svelte ================================================
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getRowModel().rows as row} {#each row.getAllCells() as cell} {/each} {/each}
{#if !header.isPlaceholder} {/if}
================================================ FILE: examples/svelte/basic-snippets/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; font-weight: normal; } ================================================ FILE: examples/svelte/basic-snippets/src/main.ts ================================================ // @ts-ignore - Svelte type definitions are not properly recognized import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/basic-snippets/src/snippets.svelte ================================================ {#snippet capitalized(value: string)}

{value}

{/snippet} {#snippet spectrum({ value, min, max }: SpectrumParams)}
{value}
{/snippet} ================================================ FILE: examples/svelte/basic-snippets/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/basic-snippets/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": [ "../basic-snippets/src/**/*.ts", "../basic-snippets/src/**/*.js", "../basic-snippets/src/**/*.svelte" ] } ================================================ FILE: examples/svelte/basic-snippets/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/basic-table-helper/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/basic-table-helper/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/basic-table-helper/index.html ================================================ Vite App
================================================ FILE: examples/svelte/basic-table-helper/package.json ================================================ { "name": "tanstack-table-example-svelte-basic-table-helper", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/basic-table-helper/src/App.svelte ================================================
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getRowModel().rows as row} {#each row.getAllCells() as cell} {/each} {/each} {#each table.getFooterGroups() as footerGroup} {#each footerGroup.headers as header} {/each} {/each}
{#if !header.isPlaceholder} {/if}
{#if !header.isPlaceholder} {/if}
================================================ FILE: examples/svelte/basic-table-helper/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/basic-table-helper/src/main.ts ================================================ // @ts-ignore - Svelte mount types not properly recognized import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/basic-table-helper/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/basic-table-helper/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/basic-table-helper/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/column-groups/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/column-groups/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/column-groups/index.html ================================================ Vite App
================================================ FILE: examples/svelte/column-groups/package.json ================================================ { "name": "tanstack-table-example-svelte-column-groups", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/column-groups/src/App.svelte ================================================
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getRowModel().rows as row} {#each row.getAllCells() as cell} {/each} {/each} {#each table.getFooterGroups() as footerGroup} {#each footerGroup.headers as header} {/each} {/each}
{#if !header.isPlaceholder} {/if}
{#if !header.isPlaceholder} {/if}
================================================ FILE: examples/svelte/column-groups/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/column-groups/src/main.ts ================================================ // @ts-ignore import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/column-groups/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/column-groups/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/column-groups/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/column-ordering/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/column-ordering/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/column-ordering/index.html ================================================ Vite App
================================================ FILE: examples/svelte/column-ordering/package.json ================================================ { "name": "tanstack-table-example-svelte-column-ordering", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/column-ordering/src/App.svelte ================================================
{#each table.getAllLeafColumns() as column}
{/each}
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getCoreRowModel().rows.slice(0, 20) as row} {#each row.getVisibleCells() as cell} {/each} {/each}
{#if !header.isPlaceholder} {/if}
{JSON.stringify(table.store.state.columnOrder, null, 2)}
================================================ FILE: examples/svelte/column-ordering/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/column-ordering/src/main.ts ================================================ // @ts-ignore import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/column-ordering/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/svelte/column-ordering/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/column-ordering/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/column-ordering/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/column-pinning/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/column-pinning/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/column-pinning/index.html ================================================ Vite App
================================================ FILE: examples/svelte/column-pinning/package.json ================================================ { "name": "tanstack-table-example-svelte-column-pinning", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/column-pinning/src/App.svelte ================================================ {#snippet headerCell(header: Header)}
{#if !header.isPlaceholder} {/if}
{#if !header.isPlaceholder && header.column.getCanPin()}
{#if header.column.getIsPinned() !== 'left'} {/if} {#if header.column.getIsPinned()} {/if} {#if header.column.getIsPinned() !== 'right'} {/if}
{/if} {/snippet}
{#each table.getAllLeafColumns() as column}
{/each}
{#if isSplit} {#each table.getLeftHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {@render headerCell(header)} {/each} {/each} {#each table.getCoreRowModel().rows.slice(0, 20) as row} {#each row.getLeftVisibleCells() as cell} {/each} {/each}
{/if} {#each isSplit ? table.getCenterHeaderGroups() : table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {@render headerCell(header)} {/each} {/each} {#each table.getCoreRowModel().rows.slice(0, 20) as row} {#each isSplit ? row.getCenterVisibleCells() : row.getVisibleCells() as cell} {/each} {/each}
{#if isSplit} {#each table.getRightHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {@render headerCell(header)} {/each} {/each} {#each table.getRowModel().rows.slice(0, 20) as row} {#each row.getRightVisibleCells() as cell} {/each} {/each}
{/if}

{JSON.stringify(table.store.state.columnPinning, null, 2)}
================================================ FILE: examples/svelte/column-pinning/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } td { border-right: 1px solid lightgray; padding: 2px 4px; } td:last-child { border-right: 0; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/column-pinning/src/main.ts ================================================ import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/column-pinning/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/svelte/column-pinning/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/column-pinning/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/column-pinning/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/column-visibility/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/column-visibility/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/column-visibility/index.html ================================================ Vite App
================================================ FILE: examples/svelte/column-visibility/package.json ================================================ { "name": "tanstack-table-example-svelte-column-visibility", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/column-visibility/src/App.svelte ================================================
{#each table.getAllLeafColumns() as column}
{/each}
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getCoreRowModel().rows.slice(0, 20) as row} {#each row.getVisibleCells() as cell} {/each} {/each} {#each table.getFooterGroups() as footerGroup} {#each footerGroup.headers as header} {/each} {/each}
{#if !header.isPlaceholder} {/if}
{#if !header.isPlaceholder} {/if}
{JSON.stringify(table.store.state.columnVisibility, null, 2)}
================================================ FILE: examples/svelte/column-visibility/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/column-visibility/src/main.ts ================================================ // @ts-ignore import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/column-visibility/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/column-visibility/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/column-visibility/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/filtering/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/filtering/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/filtering/index.html ================================================ Vite App
================================================ FILE: examples/svelte/filtering/package.json ================================================ { "name": "tanstack-table-example-svelte-filtering", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/match-sorter-utils": "^9.0.0-alpha.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/filtering/src/App.svelte ================================================ table.setGlobalFilter(e.target.value)} />
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header, idx} {/each} {/each} {#each table.getRowModel().rows as row} {#each row.getVisibleCells() as cell} {/each} {/each}
{#if !header.isPlaceholder} {/if}
"globalFilter": "{table.state.globalFilter}"
================================================ FILE: examples/svelte/filtering/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/filtering/src/main.ts ================================================ // @ts-ignore import { mount } from 'svelte' import App from './App.svelte' import type { FilterFn } from '@tanstack/svelte-table' import type { RankingInfo } from '@tanstack/match-sorter-utils' declare module '@tanstack/svelte-table' { interface FilterFns { fuzzy: FilterFn } interface FilterMeta { itemRank: RankingInfo } } const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/filtering/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/svelte/filtering/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/filtering/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/filtering/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/row-selection/index.html ================================================ Svelte Row Selection Example
================================================ FILE: examples/svelte/row-selection/package.json ================================================ { "name": "tanstack-table-example-svelte-row-selection", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/row-selection/src/App.svelte ================================================
table.setGlobalFilter(e.target.value)} class="p-2 font-lg shadow border border-block" placeholder="Search all columns..." />
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getRowModel().rows as row} {#each row.getAllCells() as cell} {/each} {/each}
{#if !header.isPlaceholder} {#if header.id === 'select'} {:else} {/if} {#if header.column.getCanFilter()}
{/if} {/if}
{#if cell.column.id === 'select'} {:else} {/if}
Page Rows ({table.getRowModel().rows.length})
Page
{table.state.pagination.pageIndex + 1} of {table.getPageCount()}
| Go to page: { const page = e.target.value ? Number(e.target.value) - 1 : 0 table.setPageIndex(page) }} class="border p-1 rounded w-16" />

{Object.keys(table.state.rowSelection).length} of{' '} {table.getPreFilteredRowModel().rows.length} Total Rows Selected


{JSON.stringify(table.state, null, 2)}
{#snippet Filter({ column, table }: { column: Column; table: SvelteTable })} {@const firstValue = table .getPreFilteredRowModel() .flatRows[0]?.getValue(column.id)} {#if typeof firstValue === 'number'}
column.setFilterValue((old: any) => [e.target.value, old?.[1]]) } placeholder={`Min`} class="w-24 border shadow rounded" /> column.setFilterValue((old: any) => [old?.[0], e.target.value]) } placeholder={`Max`} class="w-24 border shadow rounded" />
{:else} column.setFilterValue(e.target.value)} placeholder={`Search...`} class="w-36 border shadow rounded" /> {/if} {/snippet} {#snippet IndeterminateCheckbox({ indeterminate, class: className = '', checked, disabled, onChange }: { indeterminate?: boolean; class?: string; checked?: boolean; disabled?: boolean; onChange?: (event: Event) => void })} {@const ref = $state(null)} $effect(() => { if (typeof indeterminate === 'boolean' && ref) { ref.indeterminate = !checked && indeterminate } }) {/snippet} ================================================ FILE: examples/svelte/row-selection/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/row-selection/src/main.ts ================================================ import App from './App.svelte' const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') new App({ target: rootElement, }) ================================================ FILE: examples/svelte/row-selection/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: string firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { id: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/svelte/row-selection/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/row-selection/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ESNext", "DOM"], "moduleResolution": "bundler", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true, "strict": true }, "include": ["src/**/*.ts", "src/**/*.svelte"], "references": [{ "path": "./tsconfig.node.json" }] } ================================================ FILE: examples/svelte/row-selection/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/svelte/sorting/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local src/**/*.d.ts src/**/*.map ================================================ FILE: examples/svelte/sorting/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/svelte/sorting/index.html ================================================ Vite App
================================================ FILE: examples/svelte/sorting/package.json ================================================ { "name": "tanstack-table-example-svelte-sorting", "version": "0.0.0", "private": true, "type": "module", "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "test:types": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint ./src" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@sveltejs/vite-plugin-svelte": "^6.2.4", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@tsconfig/svelte": "^5.0.6", "svelte": "^5.48.5", "svelte-check": "^4.3.5", "typescript": "5.9.3", "vite": "^7.3.1" } } ================================================ FILE: examples/svelte/sorting/src/App.svelte ================================================
{#each table.getHeaderGroups() as headerGroup} {#each headerGroup.headers as header} {/each} {/each} {#each table.getRowModel().rows.slice(0, 10) as row} {#each row.getAllCells() as cell} {/each} {/each} {#each table.getFooterGroups() as footerGroup} {#each footerGroup.headers as header} {/each} {/each}
{#if !header.isPlaceholder} {/if}
{#if !header.isPlaceholder} {/if}
{table.getRowModel().rows.length} Rows
state} {table}> {#snippet children(state)}
{JSON.stringify(state, null, 2)}
{/snippet}
================================================ FILE: examples/svelte/sorting/src/Header.svelte ================================================ {#if header && header.column} {:else} {label ?? ''} {/if} ================================================ FILE: examples/svelte/sorting/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/svelte/sorting/src/main.ts ================================================ // @ts-ignore import { mount } from 'svelte' import App from './App.svelte' const app = mount(App, { target: document.getElementById('root')!, }) export default app ================================================ FILE: examples/svelte/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/svelte/sorting/src/tableHelper.svelte.ts ================================================ import { rowSortingFeature, tableFeatures } from '@tanstack/svelte-table' export const _features = tableFeatures({ rowSortingFeature, }) ================================================ FILE: examples/svelte/sorting/src/vite-env.d.ts ================================================ /// /// ================================================ FILE: examples/svelte/sorting/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' export default { preprocess: vitePreprocess(), } ================================================ FILE: examples/svelte/sorting/tsconfig.json ================================================ { "extends": "@tsconfig/svelte/tsconfig.json", "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "resolveJsonModule": true, "allowJs": true, "checkJs": true, "isolatedModules": true }, "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] } ================================================ FILE: examples/svelte/sorting/vite.config.js ================================================ import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), svelte(), ], }) ================================================ FILE: examples/vanilla/basic/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/vanilla/basic/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/vanilla/basic/index.html ================================================ Vite + TS
================================================ FILE: examples/vanilla/basic/package.json ================================================ { "name": "tanstack-table-example-vanilla-basic", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite" }, "devDependencies": { "@rollup/plugin-replace": "^6.0.3", "@types/node": "^25.0.10", "typescript": "5.9.3", "vite": "^7.3.1" }, "dependencies": { "@tanstack/table-core": "^9.0.0-alpha.16", "nanostores": "^1.1.0" } } ================================================ FILE: examples/vanilla/basic/src/createTable.ts ================================================ import { atom } from 'nanostores' import { constructTable, coreFeatures, getInitialTableState, } from '@tanstack/table-core' import type { RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' export const flexRender = (comp: any, props: TProps) => { if (typeof comp === 'function') { return comp(props) } return comp } export const createTable = < TFeatures extends TableFeatures, TData extends RowData, >( tableOptions: TableOptions, ): Table => { const _features = { ...coreFeatures, ...tableOptions._features } // const initialState = getInitialTableState(_features) const state = atom(getInitialTableState(_features, tableOptions.initialState)) // Compose in the generic options to the user options const statefulOptions: TableOptions = { ...tableOptions, _features, state: { ...state, ...tableOptions.state }, } // Create a new table const table = constructTable(statefulOptions) // Subscribe to state changes state.subscribe((currentState) => { table.setOptions((prev) => ({ ...prev, ...tableOptions, state: { ...(currentState as TableState), ...tableOptions.state, }, // Similarly, we'll maintain both our internal state and any user-provided state onStateChange: (updater) => { if (typeof updater === 'function') { const newState = updater(currentState as TableState) state.set(newState) } else { state.set(updater) } tableOptions.onStateChange?.(updater) }, })) }) return table } ================================================ FILE: examples/vanilla/basic/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } ================================================ FILE: examples/vanilla/basic/src/main.ts ================================================ import './index.css' import { createColumnHelper, tableFeatures } from '@tanstack/table-core' import { createTable, flexRender } from './createTable' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const data: Array = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const _features = tableFeatures({}) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (info) => info.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => `${info.getValue()}`, header: () => 'Last Name', footer: (info) => info.column.id, }), columnHelper.accessor('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, }), ]) const renderTable = () => { // Create table elements const tableElement = document.createElement('table') const theadElement = document.createElement('thead') const tbodyElement = document.createElement('tbody') const tfootElement = document.createElement('tfoot') tableElement.appendChild(theadElement) tableElement.appendChild(tbodyElement) tableElement.appendChild(tfootElement) // Render table headers table.getHeaderGroups().forEach((headerGroup) => { const trElement = document.createElement('tr') headerGroup.headers.forEach((header) => { const thElement = document.createElement('th') thElement.innerHTML = header.isPlaceholder ? '' : flexRender(header.column.columnDef.header, header.getContext()) trElement.appendChild(thElement) }) theadElement.appendChild(trElement) }) // Render table rows table.getRowModel().rows.forEach((row) => { const trElement = document.createElement('tr') row.getAllCells().forEach((cell) => { const tdElement = document.createElement('td') tdElement.innerHTML = flexRender( cell.column.columnDef.cell, cell.getContext(), ) trElement.appendChild(tdElement) }) tbodyElement.appendChild(trElement) }) // Render table footers table.getFooterGroups().forEach((footerGroup) => { const trElement = document.createElement('tr') footerGroup.headers.forEach((header) => { const thElement = document.createElement('th') thElement.innerHTML = header.isPlaceholder ? '' : flexRender(header.column.columnDef.footer, header.getContext()) trElement.appendChild(thElement) }) tfootElement.appendChild(trElement) }) // Clear previous content and append new content const wrapperElement = document.getElementById('wrapper') as HTMLDivElement wrapperElement.innerHTML = '' wrapperElement.appendChild(tableElement) } const table = createTable({ _features, _rowModels: {}, columns, data, debugAll: true, }) renderTable() ================================================ FILE: examples/vanilla/basic/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "emitDecoratorMetadata": true, "noEmit": true, "jsx": "react-jsx", "experimentalDecorators": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/vanilla/basic/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/vanilla/pagination/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/vanilla/pagination/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/vanilla/pagination/index.html ================================================ Vite + TS
================================================ FILE: examples/vanilla/pagination/package.json ================================================ { "name": "tanstack-table-example-vanilla-pagination", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@types/node": "^25.0.10", "typescript": "5.9.3", "vite": "^7.3.1" }, "dependencies": { "@tanstack/table-core": "^9.0.0-alpha.16", "nanostores": "^1.1.0" } } ================================================ FILE: examples/vanilla/pagination/src/createTable.ts ================================================ import { atom } from 'nanostores' import { constructTable, coreFeatures, getInitialTableState, } from '@tanstack/table-core' import type { RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' export const flexRender = (comp: any, props: TProps) => { if (typeof comp === 'function') { return comp(props) } return comp } export const createTable = < TFeatures extends TableFeatures, TData extends RowData, >( tableOptions: TableOptions, ): Table => { const _features = { ...coreFeatures, ...tableOptions._features } // const initialState = getInitialTableState(_features) const state = atom(getInitialTableState(_features, tableOptions.initialState)) // Compose in the generic options to the user options const statefulOptions: TableOptions = { ...tableOptions, _features, state: { ...state, ...tableOptions.state }, } // Create a new table const table = constructTable(statefulOptions) // Subscribe to state changes state.subscribe((currentState) => { table.setOptions((prev) => ({ ...prev, ...tableOptions, state: { ...(currentState as TableState), ...tableOptions.state, }, // Similarly, we'll maintain both our internal state and any user-provided state onStateChange: (updater) => { if (typeof updater === 'function') { const newState = updater(currentState as TableState) state.set(newState) } else { state.set(updater) } tableOptions.onStateChange?.(updater) }, })) }) return table } ================================================ FILE: examples/vanilla/pagination/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } button:disabled { opacity: 0.5; } ================================================ FILE: examples/vanilla/pagination/src/main.ts ================================================ import './index.css' import { createColumnHelper, createPaginatedRowModel, createSortedRowModel, rowPaginationFeature, rowSortingFeature, sortFns, tableFeatures, } from '@tanstack/table-core' import { makeData } from './makeData' import { createTable, flexRender } from './createTable' import type { Person } from './makeData' import type { Table } from '@tanstack/table-core' const data = makeData(100000) const _features = tableFeatures({ rowPaginationFeature, rowSortingFeature, }) const columnHelper = createColumnHelper() const columns = columnHelper.columns([ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), footer: (info) => info.column.id, }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => `${info.getValue()}`, header: () => 'Last Name', footer: (info) => info.column.id, }), columnHelper.accessor('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, }), ]) const renderTable = (table: Table) => { // Create table elements const tableElement = document.createElement('table') const theadElement = document.createElement('thead') const tbodyElement = document.createElement('tbody') tableElement.classList.add('mb-2') tableElement.appendChild(theadElement) tableElement.appendChild(tbodyElement) // Render table headers table.getHeaderGroups().forEach((headerGroup) => { const trElement = document.createElement('tr') headerGroup.headers.forEach((header) => { const thElement = document.createElement('th') thElement.colSpan = header.colSpan const divElement = document.createElement('div') divElement.classList.add( 'w-36', ...(header.column.getCanSort() ? ['cursor-pointer', 'select-none'] : []), ) ;((divElement.onclick = (e) => header.column.getToggleSortingHandler()?.(e)), (divElement.innerHTML = header.isPlaceholder ? '' : flexRender(header.column.columnDef.header, header.getContext()))) divElement.innerHTML += { asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? '' thElement.appendChild(divElement) trElement.appendChild(thElement) }) theadElement.appendChild(trElement) }) // Render table rows table.getRowModel().rows.forEach((row) => { const trElement = document.createElement('tr') row.getAllCells().forEach((cell) => { const tdElement = document.createElement('td') tdElement.innerHTML = flexRender( cell.column.columnDef.cell, cell.getContext(), ) trElement.appendChild(tdElement) }) tbodyElement.appendChild(trElement) }) // Render pagination const paginationElement = document.createElement('div') paginationElement.classList.add('flex', 'items-center', 'gap-2') // Render pagination first page button const firstPageButton = document.createElement('button') firstPageButton.classList.add('border', 'rounded', 'p-1') firstPageButton.disabled = !table.getCanPreviousPage() firstPageButton.innerHTML = '<<' firstPageButton.onclick = () => table.firstPage() paginationElement.appendChild(firstPageButton) // Render pagination previous page button const prevPageButton = document.createElement('button') prevPageButton.classList.add('border', 'rounded', 'p-1') prevPageButton.disabled = !table.getCanPreviousPage() prevPageButton.innerHTML = '<' prevPageButton.onclick = () => table.previousPage() paginationElement.appendChild(prevPageButton) // Render pagination next page button const nextPageButton = document.createElement('button') nextPageButton.classList.add('border', 'rounded', 'p-1') nextPageButton.disabled = !table.getCanNextPage() nextPageButton.innerHTML = '>' nextPageButton.onclick = () => table.nextPage() paginationElement.appendChild(nextPageButton) // Render pagination last page button const lastPageButton = document.createElement('button') lastPageButton.classList.add('border', 'rounded', 'p-1') lastPageButton.disabled = !table.getCanNextPage() lastPageButton.innerHTML = '>>' lastPageButton.onclick = () => table.lastPage() paginationElement.appendChild(lastPageButton) // Render pagination info const paginationInfoElement = document.createElement('span') paginationInfoElement.classList.add('flex', 'items-center', 'gap-1') paginationInfoElement.innerHTML = `
Page
${table.store.state.pagination.pageIndex + 1} of ${table.getPageCount().toLocaleString()}` paginationElement.appendChild(paginationInfoElement) // Render pagination set page const paginationPageElement = document.createElement('span') paginationPageElement.classList.add('flex', 'items-center', 'gap-1') paginationPageElement.textContent = '| Go to page:' const paginationPageInput = document.createElement('input') paginationPageInput.type = 'number' paginationPageInput.min = String(1) paginationPageInput.max = String(table.getPageCount()) paginationPageInput.defaultValue = String( table.store.state.pagination.pageIndex + 1, ) paginationPageInput.classList.add('border', 'p-1', 'rounded', 'w-16') paginationPageInput.oninput = (e) => { const target = e.target as HTMLInputElement const page = target.value ? Number(target.value) - 1 : 0 table.setPageIndex(page) } paginationPageElement.appendChild(paginationPageInput) paginationElement.appendChild(paginationPageElement) // Render pagiantion page size const paginationPageSizeSelect = document.createElement('select') paginationPageSizeSelect.value = String(table.store.state.pagination.pageSize) paginationPageSizeSelect.onchange = (e) => { const target = e.target as HTMLSelectElement table.setPageSize(Number(target.value)) } ;[10, 20, 30, 40, 50].map((pageSize) => { const option = document.createElement('option') option.value = String(pageSize) option.selected = table.store.state.pagination.pageSize === pageSize option.textContent = `Show ${pageSize}` paginationPageSizeSelect.appendChild(option) }) paginationElement.appendChild(paginationPageSizeSelect) // Render table state info const stateInfoElement = document.createElement('pre') stateInfoElement.textContent = JSON.stringify( { pagination: table.store.state.pagination, sorting: table.store.state.sorting, }, null, 2, ) // Clear previous content and append new content const wrapperElement = document.getElementById('wrapper') as HTMLDivElement wrapperElement.innerHTML = '' wrapperElement.appendChild(tableElement) wrapperElement.appendChild(paginationElement) wrapperElement.appendChild(stateInfoElement) } const table = createTable({ _features, _rowModels: { paginatedRowModel: createPaginatedRowModel(), sortedRowModel: createSortedRowModel(sortFns), }, data, columns, initialState: { pagination: { pageIndex: 0, pageSize: 10, }, sorting: [ { id: 'lastName', desc: false, }, ], }, onStateChange: () => renderTable(table), debugTable: true, }) renderTable(table) ================================================ FILE: examples/vanilla/pagination/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vanilla/pagination/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "emitDecoratorMetadata": true, "noEmit": true, "jsx": "react-jsx", "experimentalDecorators": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/vanilla/pagination/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/vanilla/sorting/.gitignore ================================================ node_modules .DS_Store dist dist-ssr *.local ================================================ FILE: examples/vanilla/sorting/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run start` or `yarn start` ================================================ FILE: examples/vanilla/sorting/index.html ================================================ Vite + TS
================================================ FILE: examples/vanilla/sorting/package.json ================================================ { "name": "tanstack-table-example-vanilla-sorting", "version": "0.0.0", "private": true, "scripts": { "dev": "vite", "build": "vite build", "serve": "vite preview", "start": "vite" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@rollup/plugin-replace": "^6.0.3", "@types/node": "^25.0.10", "typescript": "5.9.3", "vite": "^7.3.1" }, "dependencies": { "@tanstack/table-core": "^9.0.0-alpha.16", "nanostores": "^1.1.0" } } ================================================ FILE: examples/vanilla/sorting/src/createTable.ts ================================================ import { atom } from 'nanostores' import { constructTable, coreFeatures, getInitialTableState, } from '@tanstack/table-core' import type { RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' export const flexRender = (comp: any, props: TProps) => { if (typeof comp === 'function') { return comp(props) } return comp } export const createTable = < TFeatures extends TableFeatures, TData extends RowData, >( tableOptions: TableOptions, ): Table => { const _features = { ...coreFeatures, ...tableOptions._features } // const initialState = getInitialTableState(_features) const state = atom(getInitialTableState(_features, tableOptions.initialState)) // Compose in the generic options to the user options const statefulOptions: TableOptions = { ...tableOptions, _features, state: { ...state, ...tableOptions.state }, } // Create a new table const table = constructTable(statefulOptions) // Subscribe to state changes state.subscribe((currentState) => { table.setOptions((prev) => ({ ...prev, ...tableOptions, state: { ...(currentState as TableState), ...tableOptions.state, }, // Similarly, we'll maintain both our internal state and any user-provided state onStateChange: (updater) => { if (typeof updater === 'function') { const newState = updater(currentState as TableState) state.set(newState) } else { state.set(updater) } tableOptions.onStateChange?.(updater) }, })) }) return table } ================================================ FILE: examples/vanilla/sorting/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border: 1px solid lightgray; } tbody { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; } tfoot { color: gray; } tfoot th { font-weight: normal; } button:disabled { opacity: 0.5; } ================================================ FILE: examples/vanilla/sorting/src/main.ts ================================================ import './index.css' import { constructTableHelper, createSortedRowModel, rowSortingFeature, sortFns, } from '@tanstack/table-core' import { makeData } from './makeData' import { createTable, flexRender } from './createTable' import type { SortFn } from '@tanstack/table-core' const data = makeData(1000) // Custom sorting logic for one of our enum columns const sortStatusFn: SortFn = (rowA, rowB, _columnId) => { const statusA = rowA.original.status const statusB = rowB.original.status const statusOrder = ['single', 'complicated', 'relationship'] return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB) } const tableHelper = constructTableHelper(createTable, { _features: { rowSortingFeature, }, _rowModels: { sortedRowModel: createSortedRowModel(sortFns), }, }) const { columnHelper } = tableHelper const columns = [ columnHelper.accessor('firstName', { cell: (info) => info.getValue(), // This column will sort in ascending order by default since it is a string column }), columnHelper.accessor((row) => row.lastName, { id: 'lastName', cell: (info) => `${info.getValue()}`, header: () => 'Last Name', sortUndefined: 'last', // Force undefined values to the end sortDescFirst: false, // First sort order will be ascending (nullable values can mess up auto detection of sort order) }), columnHelper.accessor('age', { header: () => 'Age', cell: (info) => info.renderValue(), // This column will sort in descending order by default since it is a number column }), columnHelper.accessor('visits', { header: () => 'Visits', sortUndefined: 'last', // Force undefined values to the end }), columnHelper.accessor('status', { header: 'Status', sortFn: sortStatusFn, // Use our custom sorting function for this enum column }), columnHelper.accessor('progress', { header: 'Profile Progress', enableSorting: false, // Disable sorting for this column }), columnHelper.accessor('rank', { header: 'Rank', invertSorting: true, // Invert the sorting order (golf score-like where smaller is better) }), columnHelper.accessor('createdAt', { header: 'Created At', }), ] const renderTable = () => { // Create table elements const tableElement = document.createElement('table') const theadElement = document.createElement('thead') const tbodyElement = document.createElement('tbody') tableElement.classList.add('mb-2') tableElement.appendChild(theadElement) tableElement.appendChild(tbodyElement) // Render table headers table.getHeaderGroups().forEach((headerGroup) => { const trElement = document.createElement('tr') headerGroup.headers.forEach((header) => { const thElement = document.createElement('th') thElement.colSpan = header.colSpan const divElement = document.createElement('div') divElement.classList.add( 'w-36', ...(header.column.getCanSort() ? ['cursor-pointer', 'select-none'] : []), ) ;((divElement.onclick = (e) => header.column.getToggleSortingHandler()?.(e)), (divElement.innerHTML = header.isPlaceholder ? '' : flexRender(header.column.columnDef.header, header.getContext()))) divElement.innerHTML += { asc: ' 🔼', desc: ' 🔽', }[header.column.getIsSorted() as string] ?? '' thElement.appendChild(divElement) trElement.appendChild(thElement) }) theadElement.appendChild(trElement) }) // Render table rows table .getRowModel() .rows.slice(0, 10) .forEach((row) => { const trElement = document.createElement('tr') row.getAllCells().forEach((cell) => { const tdElement = document.createElement('td') tdElement.innerHTML = flexRender( cell.column.columnDef.cell, cell.getContext(), ) trElement.appendChild(tdElement) }) tbodyElement.appendChild(trElement) }) // Render table state info const stateInfoElement = document.createElement('pre') stateInfoElement.textContent = JSON.stringify( { sorting: table.store.state.sorting, }, null, 2, ) // Clear previous content and append new content const wrapperElement = document.getElementById('wrapper') as HTMLDivElement wrapperElement.innerHTML = '' wrapperElement.appendChild(tableElement) wrapperElement.appendChild(stateInfoElement) } const table = tableHelper.tableCreator({ data, columns, onStateChange: () => renderTable(), debugTable: true, }) renderTable() ================================================ FILE: examples/vanilla/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' rank: number createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], rank: faker.number.int(100), createdAt: faker.date.anytime(), } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((_d): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vanilla/sorting/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "emitDecoratorMetadata": true, "noEmit": true, "jsx": "react-jsx", "experimentalDecorators": true, "useDefineForClassFields": false, /* Linting */ "strict": true, "noUnusedLocals": false, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"] } ================================================ FILE: examples/vanilla/sorting/vite.config.js ================================================ import { defineConfig } from 'vite' import rollupReplace from '@rollup/plugin-replace' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ rollupReplace({ preventAssignment: true, values: { __DEV__: JSON.stringify(true), 'process.env.NODE_ENV': JSON.stringify('development'), }, }), ], }) ================================================ FILE: examples/vue/basic/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/basic/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/basic/env.d.ts ================================================ /// ================================================ FILE: examples/vue/basic/index.html ================================================ Vite App
================================================ FILE: examples/vue/basic/package.json ================================================ { "name": "tanstack-table-example-vue-basic", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/basic/src/App.vue ================================================ ================================================ FILE: examples/vue/basic/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/basic/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/basic/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/basic/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/column-ordering/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules .DS_Store dist dist-ssr coverage *.local /cypress/videos/ /cypress/screenshots/ # Editor directories and files .vscode/* !.vscode/extensions.json .idea *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/column-ordering/.vscode/extensions.json ================================================ { "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] } ================================================ FILE: examples/vue/column-ordering/README.md ================================================ # column-ordering This template should help get you started developing with Vue 3 in Vite. ## Recommended IDE Setup [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). ## Type Support for `.vue` Imports in TS TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: 1. Disable the built-in TypeScript Extension 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. ## Customize configuration See [Vite Configuration Reference](https://vitejs.dev/config/). ## Project Setup ```sh npm install ``` ### Compile and Hot-Reload for Development ```sh npm run dev ``` ### Type-Check, Compile and Minify for Production ```sh npm run build ``` ================================================ FILE: examples/vue/column-ordering/env.d.ts ================================================ /// ================================================ FILE: examples/vue/column-ordering/index.html ================================================ Vite App
================================================ FILE: examples/vue/column-ordering/package.json ================================================ { "name": "tanstack-table-example-vue-column-ordering", "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/column-ordering/src/App.vue ================================================ ================================================ FILE: examples/vue/column-ordering/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/column-ordering/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/column-ordering/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vue/column-ordering/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/column-ordering/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/column-pinning/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules .DS_Store dist dist-ssr coverage *.local /cypress/videos/ /cypress/screenshots/ # Editor directories and files .vscode/* !.vscode/extensions.json .idea *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/column-pinning/.vscode/extensions.json ================================================ { "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] } ================================================ FILE: examples/vue/column-pinning/README.md ================================================ # column-ordering This template should help get you started developing with Vue 3 in Vite. ## Recommended IDE Setup [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). ## Type Support for `.vue` Imports in TS TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: 1. Disable the built-in TypeScript Extension 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. ## Customize configuration See [Vite Configuration Reference](https://vitejs.dev/config/). ## Project Setup ```sh npm install ``` ### Compile and Hot-Reload for Development ```sh npm run dev ``` ### Type-Check, Compile and Minify for Production ```sh npm run build ``` ================================================ FILE: examples/vue/column-pinning/env.d.ts ================================================ /// ================================================ FILE: examples/vue/column-pinning/index.html ================================================ Vite App
================================================ FILE: examples/vue/column-pinning/package.json ================================================ { "name": "tanstack-table-example-vue-column-pinning", "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/column-pinning/src/App.vue ================================================ ================================================ FILE: examples/vue/column-pinning/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/column-pinning/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/column-pinning/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vue/column-pinning/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/column-pinning/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/filters/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/filters/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/filters/env.d.ts ================================================ /// ================================================ FILE: examples/vue/filters/index.html ================================================ Vite App
================================================ FILE: examples/vue/filters/package.json ================================================ { "name": "tanstack-table-example-vue-filters", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/filters/src/App.vue ================================================ ================================================ FILE: examples/vue/filters/src/DebouncedInput.vue ================================================ ================================================ FILE: examples/vue/filters/src/Filter.vue ================================================ ================================================ FILE: examples/vue/filters/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/filters/src/tableHelper.ts ================================================ import { columnFacetingFeature, columnFilteringFeature, createFacetedMinMaxValues, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createTableHelper, filterFns, globalFilteringFeature, } from '@tanstack/vue-table' export type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } export const tableHelper = createTableHelper({ _features: { columnFilteringFeature, globalFilteringFeature, columnFacetingFeature, }, _rowModels: { filteredRowModel: createFilteredRowModel(filterFns), facetedRowModel: createFacetedRowModel(), facetedMinMaxValues: createFacetedMinMaxValues(), facetedUniqueValues: createFacetedUniqueValues(), }, TData: {} as Person, }) ================================================ FILE: examples/vue/filters/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/filters/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/pagination/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/pagination/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/pagination/env.d.ts ================================================ /// ================================================ FILE: examples/vue/pagination/index.html ================================================ Vite App
================================================ FILE: examples/vue/pagination/package.json ================================================ { "name": "tanstack-table-example-vue-pagination", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/pagination/src/App.vue ================================================ ================================================ FILE: examples/vue/pagination/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/pagination/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/pagination/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vue/pagination/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/pagination/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/pagination-controlled/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/pagination-controlled/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/pagination-controlled/env.d.ts ================================================ /// ================================================ FILE: examples/vue/pagination-controlled/index.html ================================================ Vite App
================================================ FILE: examples/vue/pagination-controlled/package.json ================================================ { "name": "tanstack-table-example-vue-pagination-controlled", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/pagination-controlled/src/App.vue ================================================ ================================================ FILE: examples/vue/pagination-controlled/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/pagination-controlled/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/pagination-controlled/src/useService.ts ================================================ import { computed, ref, watchEffect } from 'vue' import type { PaginationState } from '@tanstack/vue-table' import type { Ref } from 'vue' const DEFAULT_PAGE_COUNT = -1 const DEFAULT_RESULT_COUNT = -1 const endpoint = 'https://jsonplaceholder.typicode.com/posts' export default function useService(pagination: Ref) { const data = ref(null) const totalResultCount = ref(DEFAULT_RESULT_COUNT) const error = ref(null) const isLoading = ref(false) const request = ref | null>(null) const requestParams = computed(() => { const { pageSize, pageIndex } = pagination.value const currentPage = pageIndex + 1 return { _limit: pageSize.toString(), _page: currentPage.toString(), } }) const url = computed(() => { const searchParams = new URLSearchParams(requestParams.value) return `${endpoint}?${searchParams}` }) const pageCount = computed(() => { const { pageSize } = pagination.value return Math.ceil(totalResultCount.value / pageSize) }) watchEffect(() => { isLoading.value = true request.value = fetch(url.value) .then(async (response) => { const responseData = await response.json() if (response.ok) { data.value = responseData error.value = null totalResultCount.value = Number( response.headers.get('x-total-count') ?? DEFAULT_PAGE_COUNT, ) } else { throw new Error('Network response was not OK') } }) .catch((error) => { error.value = error data.value = null totalResultCount.value = DEFAULT_PAGE_COUNT console.log('error!', error) }) .finally(() => { isLoading.value = false }) }) return { data, totalResultCount, pageCount, error, isLoading, } } ================================================ FILE: examples/vue/pagination-controlled/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/pagination-controlled/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/row-selection/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/row-selection/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/row-selection/env.d.ts ================================================ /// ================================================ FILE: examples/vue/row-selection/index.html ================================================ Vite App
================================================ FILE: examples/vue/row-selection/package.json ================================================ { "name": "tanstack-table-example-vue-row-selection", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "@vitejs/plugin-vue-jsx": "^5.1.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/row-selection/src/App.vue ================================================ ================================================ FILE: examples/vue/row-selection/src/IndeterminateCheckbox.vue ================================================ ================================================ FILE: examples/vue/row-selection/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/row-selection/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/row-selection/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vue/row-selection/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/row-selection/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue(), vueJsx()], }) ================================================ FILE: examples/vue/sorting/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/sorting/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/sorting/env.d.ts ================================================ /// ================================================ FILE: examples/vue/sorting/index.html ================================================ Vite App
================================================ FILE: examples/vue/sorting/package.json ================================================ { "name": "tanstack-table-example-vue-sorting", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/sorting/src/App.vue ================================================ ================================================ FILE: examples/vue/sorting/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/sorting/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/sorting/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' createdAt: Date subRows?: Array } const range = (len: number) => { const arr: Array = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (): Person => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0], } } export function makeData(...lens: Array) { const makeDataLevel = (depth = 0): Array => { const len = lens[depth] return range(len).map((): Person => { return { ...newPerson(), subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } ================================================ FILE: examples/vue/sorting/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/sorting/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/sub-components/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/sub-components/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/sub-components/env.d.ts ================================================ /// ================================================ FILE: examples/vue/sub-components/index.html ================================================ Vite App
================================================ FILE: examples/vue/sub-components/package.json ================================================ { "name": "tanstack-table-example-vue-subcomponents", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "lint": "eslint ./src", "test:types": "vue-tsc" }, "dependencies": { "@faker-js/faker": "^10.2.0", "@tanstack/vue-table": "^9.0.0-alpha.10", "vue": "^3.5.27" }, "devDependencies": { "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/sub-components/src/App.vue ================================================ ================================================ FILE: examples/vue/sub-components/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/sub-components/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/sub-components/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: examples/vue/virtualized-rows/.gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-ssr *.local # Editor directories and files .vscode/* !.vscode/extensions.json .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: examples/vue/virtualized-rows/README.md ================================================ # Example To run this example: - `npm install` or `yarn` - `npm run dev` or `yarn dev` ================================================ FILE: examples/vue/virtualized-rows/env.d.ts ================================================ /// ================================================ FILE: examples/vue/virtualized-rows/index.html ================================================ Vite App
================================================ FILE: examples/vue/virtualized-rows/package.json ================================================ { "name": "tanstack-table-example-vue-virtualized-rows", "private": true, "version": "0.0.0", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview", "test:types": "vue-tsc" }, "dependencies": { "@tanstack/vue-table": "^9.0.0-alpha.10", "@tanstack/vue-virtual": "^3.13.18", "vue": "^3.5.27" }, "devDependencies": { "@faker-js/faker": "^10.2.0", "@types/node": "^25.0.10", "@vitejs/plugin-vue": "^6.0.3", "typescript": "5.9.3", "vite": "^7.3.1", "vue-tsc": "^3.2.4" } } ================================================ FILE: examples/vue/virtualized-rows/src/App.vue ================================================ ================================================ FILE: examples/vue/virtualized-rows/src/env.d.ts ================================================ /// declare module '*.vue' { import type { DefineComponent } from 'vue' // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any> export default component } ================================================ FILE: examples/vue/virtualized-rows/src/index.css ================================================ html { font-family: sans-serif; font-size: 14px; } table { border-collapse: collapse; border-spacing: 0; font-family: arial, sans-serif; table-layout: fixed; } thead { background: lightgray; } tr { border-bottom: 1px solid lightgray; } th { border-bottom: 1px solid lightgray; border-right: 1px solid lightgray; padding: 2px 4px; text-align: left; } td { padding: 6px; } .container { border: 1px solid lightgray; margin: 1rem auto; } .cursor-pointer { cursor: pointer; } .select-none { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .text-left { text-align: left; } ================================================ FILE: examples/vue/virtualized-rows/src/main.ts ================================================ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') ================================================ FILE: examples/vue/virtualized-rows/src/makeData.ts ================================================ import { faker } from '@faker-js/faker' export type Person = { id: number firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' createdAt: Date } const range = (len: number) => { const arr: number[] = [] for (let i = 0; i < len; i++) { arr.push(i) } return arr } const newPerson = (index: number): Person => { return { id: index + 1, firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), createdAt: faker.date.anytime(), status: faker.helpers.shuffle([ 'relationship', 'complicated', 'single', ])[0]!, } } export function makeData(...lens: number[]) { const makeDataLevel = (depth = 0): Person[] => { const len = lens[depth]! return range(len).map((d): Person => { return { ...newPerson(d), } }) } return makeDataLevel() } ================================================ FILE: examples/vue/virtualized-rows/tsconfig.json ================================================ { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } ================================================ FILE: examples/vue/virtualized-rows/vite.config.ts ================================================ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], }) ================================================ FILE: knip.json ================================================ { "$schema": "https://unpkg.com/knip@5/schema.json", "ignoreDependencies": ["@faker-js/faker"], "ignoreWorkspaces": ["examples/**"], "ignore": ["**/*benchmark*", "**/benchmarks/**"], "workspaces": { "packages/table-core": { "ignore": ["**/tests/**"] }, "packages/match-sorter-utils": { "ignoreDependencies": ["remove-accents"] }, "packages/react-table": { "ignore": ["**/*.notest.*", "**/makeTestData.ts"] } } } ================================================ FILE: nx.json ================================================ { "$schema": "./node_modules/nx/schemas/nx-schema.json", "defaultBase": "main", "nxCloudId": "6435ee4cd7387c45c0e4bf4c", "useInferencePlugins": false, "parallel": 5, "tui": { "enabled": false }, "namedInputs": { "sharedGlobals": [ "{workspaceRoot}/.nvmrc", "{workspaceRoot}/package.json", "{workspaceRoot}/tsconfig.json" ], "default": [ "sharedGlobals", "{projectRoot}/**/*", "!{projectRoot}/**/*.md" ], "public": [ "default", "{projectRoot}/build", "{projectRoot}/dist", "!{projectRoot}/.eslintrc.cjs", "!{projectRoot}/tsconfig.eslint.json" ] }, "targetDefaults": { "test:lib": { "dependsOn": ["^build"], "inputs": ["default", "^public"], "outputs": ["{projectRoot}/coverage"], "cache": true }, "test:eslint": { "dependsOn": ["^build"], "inputs": ["default", "^public"], "cache": true }, "test:types": { "dependsOn": ["^build"], "inputs": ["default", "^public"], "cache": true }, "test:build": { "dependsOn": ["build"], "inputs": ["default", "^public"], "cache": true }, "build": { "dependsOn": ["^build"], "inputs": ["default", "^public"], "outputs": ["{projectRoot}/build", "{projectRoot}/dist"], "cache": true }, "test:knip": { "cache": true, "inputs": ["{workspaceRoot}/**/*"] }, "test:sherif": { "cache": true, "inputs": ["{workspaceRoot}/**/package.json"] } } } ================================================ FILE: package.json ================================================ { "name": "table", "private": true, "repository": { "type": "git", "url": "git+https://github.com/TanStack/table.git" }, "packageManager": "pnpm@10.28.2", "type": "module", "scripts": { "build": "nx run-many --targets=build -p @tanstack/table-core @tanstack/react-table @tanstack/table-devtools @tanstack/react-table-devtools @tanstack/preact-table @tanstack/angular-table && size-limit", "build:all": "nx run-many --targets=build -p @tanstack/table-core @tanstack/react-table @tanstack/table-devtools @tanstack/react-table-devtools @tanstack/preact-table @tanstack/angular-table && size-limit", "build:core": "nx build @tanstack/table-core && size-limit", "cipublish": "node scripts/publish.js", "clean": "find . -name 'dist' -type d -prune -exec rm -rf {} +", "clean:node_modules": "find . -name 'node_modules' -type d -prune -exec rm -rf {} +", "dev": "pnpm run watch", "generate-docs": "node scripts/generateDocs.js", "format": "prettier --experimental-cli --ignore-unknown '**/*' --write", "lint:fix:all": "pnpm run format && nx run-many --targets=lint --fix --exclude=packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}", "lint:fix": "nx affected --target=lint:fix --exclude=examples/**,packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}", "preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm", "size": "size-limit", "test": "pnpm run test:ci", "test:build": "nx affected --target=test:build --exclude='examples/{lit,solid,svelte,vanilla,vue}/**' --exclude='packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}'", "test:ci": "nx run-many --targets=test:eslint,test:sherif,test:knip,test:lib,test:types,test:build,build -p @tanstack/table-core @tanstack/react-table @tanstack/table-devtools @tanstack/react-table-devtools @tanstack/preact-table @tanstack/angular-table 'examples/react/**' 'examples/preact/**' 'examples/angular/**'", "test:docs": "node scripts/verify-links.ts", "test:eslint": "nx affected --target=test:eslint --exclude='examples/{lit,solid,svelte,vanilla,vue}/**' --exclude='packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}'", "test:knip": "NODE_OPTIONS='--max-old-space-size=4096' knip", "test:lib": "nx affected --targets=test:lib --exclude='examples/{lit,solid,svelte,vanilla,vue}/**' --exclude='packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}'", "test:lib:dev": "pnpm test:lib && nx watch --all -- pnpm test:lib", "test:pr": "nx affected --targets=test:eslint,test:sherif,test:knip,test:lib,test:types,test:build,build --exclude='examples/{lit,solid,svelte,vanilla,vue}/**' --exclude='packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}'", "test:sherif": "sherif", "test:types": "nx affected --targets=test:types --exclude='examples/{lit,solid,svelte,vanilla,vue}/**' --exclude='packages/{lit-table,solid-table,svelte-table,vue-table,match-sorter-utils}'", "watch": "pnpm run build:all && nx watch --all -- pnpm run build:all" }, "nx": { "includedScripts": [ "test:docs", "test:knip", "test:sherif" ] }, "size-limit": [ { "path": "packages/table-core/dist/esm/index.js", "limit": "20 KB" } ], "devDependencies": { "@faker-js/faker": "^10.2.0", "@size-limit/preset-small-lib": "^12.0.0", "@tanstack/eslint-config": "0.3.4", "@tanstack/publish-config": "0.2.2", "@tanstack/typedoc-config": "0.3.3", "@tanstack/vite-config": "0.4.3", "@testing-library/jest-dom": "^6.9.1", "@types/node": "^25.0.10", "eslint": "^9.39.2", "jsdom": "^27.4.0", "knip": "^5.82.1", "markdown-link-extractor": "^4.0.3", "nx": "^22.4.2", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.4.1", "publint": "^0.3.17", "rimraf": "^6.1.2", "sherif": "^1.10.0", "size-limit": "^12.0.0", "tinyglobby": "^0.2.15", "typescript": "5.9.3", "vite": "^7.3.1", "vitest": "^4.0.18" } } ================================================ FILE: packages/angular-table/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [ ...rootConfig, { rules: {}, }, ] export default config ================================================ FILE: packages/angular-table/ng-package.json ================================================ { "$schema": "./node_modules/ng-packagr/ng-package.schema.json", "dest": "./dist", "lib": { "entryFile": "src/index.ts" }, "deleteDestPath": false, "allowedNonPeerDependencies": [ "@tanstack/table-core", "@tanstack/angular-store" ] } ================================================ FILE: packages/angular-table/package.json ================================================ { "name": "@tanstack/angular-table", "version": "9.0.0-alpha.17", "description": "Headless UI for building powerful tables & datagrids for Angular.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/TanStack/table.git", "directory": "packages/angular-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "angular", "table", "angular-table", "datagrid" ], "type": "module", "module": "dist/fesm2022/tanstack-angular-table.mjs", "types": "dist/types/tanstack-angular-table.d.ts", "exports": { ".": { "types": "./dist/types/tanstack-angular-table.d.ts", "default": "./dist/fesm2022/tanstack-angular-table.mjs" }, "./package.json": { "default": "./package.json" } }, "engines": { "node": ">=18" }, "files": [ "dist", "src" ], "scripts": { "build": "ng-packagr -p ng-package.json -c tsconfig.build.json && rimraf ./dist/package.json", "build:types": "tsc --emitDeclarationOnly", "clean": "rimraf ./build && rimraf ./dist", "test:build": "publint --strict", "test:eslint": "eslint ./src", "test:lib": "vitest", "test:benchmark": "vitest bench", "test:lib:dev": "vitest --watch", "test:types": "tsc && vitest --typecheck" }, "dependencies": { "@tanstack/angular-store": "^0.9.2", "@tanstack/table-core": "workspace:*", "tslib": "^2.8.1" }, "devDependencies": { "@analogjs/vite-plugin-angular": "^2.2.2", "@analogjs/vitest-angular": "^2.2.2", "@angular/core": "^21.1.1", "@angular/platform-browser": "^21.1.1", "ng-packagr": "^21.1.0", "typescript": "5.9.3" }, "peerDependencies": { "@angular/core": ">=19" }, "sideEffects": false } ================================================ FILE: packages/angular-table/src/flex-render/context.ts ================================================ import { InjectionToken, inject } from '@angular/core' export const FlexRenderComponentProps = new InjectionToken< NonNullable >('[@tanstack/angular-table] Flex render component context props') /** * Inject the flex render context props. * * Can be used in components rendered via FlexRender directives. */ export function injectFlexRenderContext>(): T { return inject(FlexRenderComponentProps) } ================================================ FILE: packages/angular-table/src/flex-render/flags.ts ================================================ /** * Flags used to manage and optimize the rendering lifecycle of the content of the cell * while using {@link FlexViewRenderer}. */ export const FlexRenderFlags = { /** * Indicates that the view is being created for the first time or will be cleared during the next update phase. * This is the initial state and will transition after the first ngDoCheck. */ ViewFirstRender: 1 << 0, /** * Indicates the `content` property has been modified or the view requires a complete re-render. * When this flag is enabled, the view will be cleared and recreated from scratch. */ ContentChanged: 1 << 1, /** * Indicates that the `props` property reference has changed. * When this flag is enabled, the view context is updated based on the type of the content. * * For Component view, inputs will be updated and view will be marked as dirty. * For TemplateRef and primitive values, view will be marked as dirty */ PropsReferenceChanged: 1 << 2, /** * Indicates that the current rendered view needs to be checked for changes. * This will be set to true when `content(props)` result has changed or during * forced update */ Dirty: 1 << 3, /** * Indicates that the first render effect has been checked at least one time. */ RenderEffectChecked: 1 << 4, } as const ================================================ FILE: packages/angular-table/src/flex-render/flexRenderComponent.ts ================================================ import { reflectComponentType } from '@angular/core' import type { Binding, ComponentMirror, Injector, InputSignal, OutputEmitterRef, Type, createComponent, } from '@angular/core' type CreateComponentOptions = Parameters[1] type CreateComponentBindings = CreateComponentOptions['bindings'] type CreateComponentDirectives = CreateComponentOptions['directives'] interface FlexRenderOptions< TInputs extends Record, TOutputs extends Record, > { /** * Native Angular bindings applied at component creation time via `createComponent`. * Use this option to set inputs, outputs, or two-way bindings at creation time. * Shouldn't be used together with {@link FlexRenderOptions#inputs} or {@link FlexRenderOptions#outputs} option. * * Binding input/outputs at creation time: {@link https://angular.dev/guide/components/programmatic-rendering#binding-inputs-outputs-and-setting-host-directives-at-creation} * * Two-way binding: {@link https://angular.dev/api/core/twoWayBinding} * * Output binding: {@link https://angular.dev/api/core/outputBinding} * * Input binding: {@link https://angular.dev/api/core/inputBinding} * * @example * ```ts * import {flexRenderComponent} from '@tanstack/angular-table'; * flexRenderComponent(MyComponent, { * bindings: [ * // Will update `value` input every time `mySignalValue` changes * inputBinding('value', mySignalValue), * // Set myProperty to 1 when the component is created * inputBinding('myProperty', () => 1), * // Callback called every time `valueChange` output emit * outputBinding('valueChange', value => { * console.log("my value changed to", value) * }), * // Two-way binding between `value` input and `valueChange` output * // Useful while using `model` inputs. * twoWayBinding('value', mySignal) * ] * }) * ``` */ readonly bindings?: Array /** * Directives to apply to the component at creation time. * * Binding directives at creation time: {@link https://angular.dev/guide/components/programmatic-rendering#binding-inputs-outputs-and-setting-host-directives-at-creation} * * Two-way binding: {@link https://angular.dev/api/core/twoWayBinding} * * Output binding: {@link https://angular.dev/api/core/outputBinding} * * Input binding: {@link https://angular.dev/api/core/inputBinding} * * @example * ```ts * import {flexRenderComponent} from '@tanstack/angular-table'; * flexRenderComponent(MyComponent, { * bindings: [ * // ... * ], * directives: [ * DirectiveA, * { * type: DirectiveB, * bindings: [ * inputBinding('value', mySignalValue), * // ... * ] * } * ] * }) * ``` */ readonly directives?: CreateComponentDirectives /** * Component instance inputs. * * These values are assigned after the component has been created using * [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput). * * Shouldn't be used together with {@link FlexRenderOptions#bindings} option */ readonly inputs?: TInputs /** * Component instance outputs. * * Outputs are wired imperatively after component creation using {@link OutputEmitterRef#subscribe}. * * Shouldn't be used together with {@link FlexRenderOptions#bindings} option */ readonly outputs?: TOutputs /** * Optional {@link Injector} that will be used when rendering the component */ readonly injector?: Injector } type Inputs = { [K in keyof T as T[K] extends InputSignal ? K : never]?: T[K] extends InputSignal ? R : never } type Outputs = { [K in keyof T as T[K] extends OutputEmitterRef ? K : never]?: T[K] extends OutputEmitterRef ? OutputEmitterRef['emit'] : never } /** * Helper function to create a {@link FlexRenderComponent} instance, with better type-safety. * * @example * ```ts * import {flexRenderComponent} from '@tanstack/angular-table' * import {inputBinding, outputBinding} from '@angular/core'; * * const columns = [ * { * cell: ({ row }) => { * return flexRenderComponent(MyComponent, { * inputs: { value: mySignalValue() }, * outputs: { valueChange: (val) => {} } * // or using angular native createComponent#binding api * bindings: [ * inputBinding('value', mySignalValue), * outputBinding('valueChange', value => { * console.log("my value changed to", value) * }) * ] * }) * }, * }, * ] * ``` */ export function flexRenderComponent( component: Type, options?: FlexRenderOptions, Outputs>, ): FlexRenderComponent { const { inputs, injector, outputs, directives, bindings } = options ?? {} return new FlexRenderComponentInstance( component, inputs, injector, outputs, directives, bindings, ) } /** * Wrapper interface for a component that will be used as content for {@link FlexRenderDirective}. * Can be created using {@link flexRenderComponent} helper. * * @example * * ```ts * import {flexRenderComponent} from '@tanstack/angular-table' * * // Usage in cell/header/footer definition * const columns = [ * { * cell: ({ row }) => { * return flexRenderComponent(MyComponent, { * inputs: { value: mySignalValue() }, * outputs: { valueChange: (val) => {} } * // or using angular createComponent#bindings api * bindings: [ * inputBinding('value', mySignalValue), * outputBinding('valueChange', value => { * console.log("my value changed to", value) * }) * ] * }) * }, * }, * ] * * import {input, output} from '@angular/core'; * * @Component({ * selector: 'my-component', * }) * class MyComponent { * readonly value = input(0); * readonly valueChange = output(); * } * * ``` */ export interface FlexRenderComponent { /** * The component type */ readonly component: Type /** * Reflected metadata about the component. */ readonly mirror: ComponentMirror /** * List of allowed input names. */ readonly allowedInputNames: Array /** * List of allowed output names. */ readonly allowedOutputNames: Array /** * Component instance outputs. Subscribed via {@link OutputEmitterRef#subscribe} * * @see {@link FlexRenderOptions#outputs} */ readonly outputs?: Outputs /** * Component instance inputs. Set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)) * * @see {@link FlexRenderOptions#inputs} */ readonly inputs?: Inputs /** * Optional {@link Injector} that will be used when rendering the component. * * @see {@link FlexRenderOptions#injector} */ readonly injector?: Injector /** * Bindings to apply to the root component * * @see {@link FlexRenderOptions#bindings} */ bindings?: CreateComponentBindings /** * Directives that should be applied to the component. * * @see {FlexRenderOptions#directives} */ directives?: CreateComponentDirectives } /** * Wrapper class for a component that will be used as content for {@link FlexRenderDirective} * * Prefer {@link flexRenderComponent} helper for better type-safety */ export class FlexRenderComponentInstance< TComponent = any, > implements FlexRenderComponent { readonly mirror: ComponentMirror readonly allowedInputNames: Array = [] readonly allowedOutputNames: Array = [] constructor( readonly component: Type, readonly inputs?: Inputs, readonly injector?: Injector, readonly outputs?: Outputs, readonly directives?: CreateComponentDirectives, readonly bindings?: CreateComponentBindings, ) { const mirror = reflectComponentType(component) if (!mirror) { throw new Error( `[@tanstack-table/angular] The provided symbol is not a component`, ) } this.mirror = mirror for (const input of this.mirror.inputs) { this.allowedInputNames.push(input.propName) } for (const output of this.mirror.outputs) { this.allowedOutputNames.push(output.propName) } } } ================================================ FILE: packages/angular-table/src/flex-render/flexRenderComponentFactory.ts ================================================ import { ChangeDetectorRef, ComponentRef, Injectable, Injector, KeyValueDiffer, KeyValueDiffers, OutputEmitterRef, OutputRefSubscription, ViewContainerRef, } from '@angular/core' import { FlexRenderComponent } from './flexRenderComponent' @Injectable() export class FlexRenderComponentFactory { readonly #viewContainerRef: ViewContainerRef constructor(viewContainerRef: ViewContainerRef) { this.#viewContainerRef = viewContainerRef } createComponent( flexRenderComponent: FlexRenderComponent, componentInjector: Injector, ): FlexRenderComponentRef { const componentRef = this.#viewContainerRef.createComponent( flexRenderComponent.component, { injector: componentInjector, directives: flexRenderComponent.directives, bindings: flexRenderComponent.bindings ?? [], }, ) const view = new FlexRenderComponentRef( componentRef, flexRenderComponent, componentInjector, ) const { inputs, outputs } = flexRenderComponent if (inputs) view.setInputs(inputs) if (outputs) view.setOutputs(outputs) return view } } export class FlexRenderComponentRef { readonly #keyValueDiffersFactory: KeyValueDiffers #componentData: FlexRenderComponent #inputValueDiffer: KeyValueDiffer readonly #outputRegistry: FlexRenderComponentOutputManager constructor( readonly componentRef: ComponentRef, componentData: FlexRenderComponent, readonly componentInjector: Injector, ) { this.#componentData = componentData this.#keyValueDiffersFactory = componentInjector.get(KeyValueDiffers) this.#outputRegistry = new FlexRenderComponentOutputManager( this.#keyValueDiffersFactory, this.outputs, ) this.#inputValueDiffer = this.#keyValueDiffersFactory .find(this.inputs) .create() this.#inputValueDiffer.diff(this.inputs) this.componentRef.onDestroy(() => this.#outputRegistry.unsubscribeAll()) } get component() { return this.#componentData.component } get inputs() { return this.#componentData.inputs ?? {} } get outputs() { return this.#componentData.outputs ?? {} } /** * Get component input and output diff by the given item */ diff(item: FlexRenderComponent) { return { inputDiff: this.#inputValueDiffer.diff(item.inputs ?? {}), outputDiff: this.#outputRegistry.diff(item.outputs ?? {}), } } /** * * @param compare Whether the current ref component instance is the same as the given one */ eqType(compare: FlexRenderComponent): boolean { return compare.component === this.component } /** * Tries to update current component refs input by the new given content component. */ update(content: FlexRenderComponent) { const eq = this.eqType(content) if (!eq) return const { inputDiff, outputDiff } = this.diff(content) if (inputDiff) { inputDiff.forEachAddedItem((item) => this.setInput(item.key, item.currentValue), ) inputDiff.forEachChangedItem((item) => this.setInput(item.key, item.currentValue), ) inputDiff.forEachRemovedItem((item) => this.setInput(item.key, undefined)) } if (outputDiff) { outputDiff.forEachAddedItem((item) => { this.setOutput(item.key, item.currentValue) }) outputDiff.forEachChangedItem((item) => { if (item.currentValue) { this.#outputRegistry.setListener(item.key, item.currentValue) } else { this.#outputRegistry.unsubscribe(item.key) } }) outputDiff.forEachRemovedItem((item) => { this.#outputRegistry.unsubscribe(item.key) }) } this.#componentData = content } markAsDirty(): void { this.componentRef.injector.get(ChangeDetectorRef).markForCheck() } setInputs(inputs: Record) { for (const prop in inputs) { this.setInput(prop, inputs[prop]) } } setInput(key: string, value: unknown) { if (this.#componentData.allowedInputNames.includes(key)) { this.componentRef.setInput(key, value) } } setOutputs( outputs: Record< string, OutputEmitterRef['emit'] | null | undefined >, ) { this.#outputRegistry.unsubscribeAll() for (const prop in outputs) { this.setOutput(prop, outputs[prop]) } } setOutput( outputName: string, emit: OutputEmitterRef['emit'] | undefined | null, ): void { if (!this.#componentData.allowedOutputNames.includes(outputName)) return if (!emit) { this.#outputRegistry.unsubscribe(outputName) return } const hasListener = this.#outputRegistry.hasListener(outputName) this.#outputRegistry.setListener(outputName, emit) if (hasListener) { return } const instance = this.componentRef.instance const output = instance[outputName as keyof typeof instance] if (output && output instanceof OutputEmitterRef) { output.subscribe((value) => { this.#outputRegistry.getListener(outputName)?.(value) }) } } } class FlexRenderComponentOutputManager { readonly #outputSubscribers: Record = {} readonly #outputListeners: Record) => void> = {} readonly #valueDiffer: KeyValueDiffer< string, undefined | null | OutputEmitterRef['emit'] > constructor(keyValueDiffers: KeyValueDiffers, initialOutputs: any) { this.#valueDiffer = keyValueDiffers.find(initialOutputs).create() if (initialOutputs) { this.#valueDiffer.diff(initialOutputs) } } hasListener(outputName: string) { return outputName in this.#outputListeners } setListener(outputName: string, callback: (...args: Array) => void) { this.#outputListeners[outputName] = callback } getListener(outputName: string) { return this.#outputListeners[outputName] } unsubscribeAll(): void { for (const prop in this.#outputSubscribers) { this.unsubscribe(prop) } } unsubscribe(outputName: string) { if (outputName in this.#outputSubscribers) { this.#outputSubscribers[outputName]?.unsubscribe() delete this.#outputSubscribers[outputName] delete this.#outputListeners[outputName] } } diff(outputs: Record['emit'] | undefined>) { return this.#valueDiffer.diff(outputs ?? {}) } } ================================================ FILE: packages/angular-table/src/flex-render/renderer.ts ================================================ import { Injector, computed, effect, runInInjectionContext, untracked, } from '@angular/core' import { TanStackTableToken } from '../helpers/table' import { TanStackTableCellToken } from '../helpers/cell' import { TanStackTableHeaderToken } from '../helpers/header' import { FlexRenderComponentProps } from './context' import { FlexRenderFlags } from './flags' import { FlexRenderComponentView, FlexRenderTemplateView, mapToFlexRenderTypedContent, } from './view' import { flexRenderComponent } from './flexRenderComponent' import { FlexRenderComponentFactory } from './flexRenderComponentFactory' import type { FlexRenderComponent } from './flexRenderComponent' import type { EffectRef, TemplateRef, Type, ViewContainerRef, } from '@angular/core' import type { FlexRenderTypedContent, FlexRenderView } from './view' import type { CellContext, CellData, HeaderContext, RowData, TableFeatures, } from '@tanstack/table-core' /** * Content supported by the `flexRender` directive when declaring * a table column header/cell. */ export type FlexRenderContent> = | string | number | Type | FlexRenderComponent | TemplateRef<{ $implicit: TProps }> | null | Record | undefined /** * Input content supported by the `flexRender` directives. */ export type FlexRenderInputContent> = | number | string | ((props: TProps) => FlexRenderContent) | null | undefined /** * Options used to create a {@link FlexViewRenderer}. * * This renderer is designed to be embedded inside a directive/component that owns the * `ViewContainerRef` and possibly a fallback `TemplateRef`. */ interface RendererViewOptions> { /** * Signal-like getter that returns the latest renderable content. */ content: () => FlexRenderInputContent /** * Signal-like getter returning the current props/context object. */ props: () => NoInfer /** * Getter returning the base injector to evaluate render functions in. * * If `content` is a function, it will be executed inside this injection context * via `runInInjectionContext` so Angular DI works as expected. */ injector: () => Injector /** * Container that will host the dynamically created view/component. */ viewContainerRef: ViewContainerRef /** * Fallback template used for primitive rendering. * * The template is instantiated with `$implicit` set to the primitive string/number. */ templateRef: TemplateRef } /** * Internal view renderer used by Angular TanStack Table to implement `flexRender` directives. * * @internal Use FlexRender directives instead. */ export class FlexViewRenderer< TFeatures extends TableFeatures, TRowData extends RowData, TValue extends CellData, TProps extends | NonNullable | CellContext | HeaderContext, > { #renderFlags = FlexRenderFlags.ViewFirstRender #renderView: FlexRenderView | null = null #currentRenderEffectRef: EffectRef | null = null #content: () => FlexRenderInputContent #props: () => TProps #injector: () => Injector #viewContainerRef: ViewContainerRef #templateRef: TemplateRef #flexRenderComponentFactory: FlexRenderComponentFactory readonly #getLatestContentValue = () => { const content = this.#content() const props = this.#props() return typeof content !== 'function' ? content : runInInjectionContext(this.#injector(), () => content(props)) } readonly #latestContent = computed(() => this.#getLatestContentValue()) #getContentValue = computed(() => { const latestContent = this.#latestContent() return mapToFlexRenderTypedContent(latestContent) }) constructor(options: RendererViewOptions) { this.#content = options.content this.#props = options.props this.#injector = options.injector this.#templateRef = options.templateRef this.#viewContainerRef = options.viewContainerRef this.#flexRenderComponentFactory = new FlexRenderComponentFactory( this.#viewContainerRef, ) } mount(): EffectRef { let previousContent: FlexRenderInputContent let previousProps: TProps return effect(() => { const props = this.#props() const content = this.#content() if (!(this.#renderFlags & FlexRenderFlags.ViewFirstRender)) { if (previousContent !== content) { this.#renderFlags |= FlexRenderFlags.ContentChanged } if (previousProps !== props) { this.#renderFlags |= FlexRenderFlags.PropsReferenceChanged } } untracked(() => this.#update()) if (FlexRenderFlags.ViewFirstRender & this.#renderFlags) { this.#renderFlags &= ~FlexRenderFlags.ViewFirstRender } previousContent = content previousProps = props }) } destroy(): void { if (this.#currentRenderEffectRef) { this.#currentRenderEffectRef.destroy() this.#currentRenderEffectRef = null } if (this.#renderView) { this.#renderView.unmount() this.#renderView = null } } #update() { if ( this.#renderFlags & (FlexRenderFlags.ContentChanged | FlexRenderFlags.ViewFirstRender) ) { this.#render() return } if (this.#renderFlags & FlexRenderFlags.PropsReferenceChanged) { if (this.#renderView) this.#renderView.updateProps(this.#props()) this.#renderFlags &= ~FlexRenderFlags.PropsReferenceChanged } if (this.#renderFlags & FlexRenderFlags.Dirty) { if (this.#renderView) this.#renderView.dirtyCheck() this.#renderFlags &= ~FlexRenderFlags.Dirty } } #render() { // When the view is recreated from scratch (content change or first render), // we have to destroy the current effect listener since it will be recreated // skipping the first call (FlexRenderFlags.RenderEffectChecked) if (this.#shouldRecreateEntireView() && this.#currentRenderEffectRef) { this.#currentRenderEffectRef.destroy() this.#currentRenderEffectRef = null this.#renderFlags &= ~FlexRenderFlags.RenderEffectChecked } this.#viewContainerRef.clear() if (this.#renderView) { this.#renderView.unmount() this.#renderView = null } this.#renderFlags = (this.#renderFlags & FlexRenderFlags.ViewFirstRender) | (this.#renderFlags & FlexRenderFlags.RenderEffectChecked) const resolvedContent = this.#getContentValue() this.#renderView = this.#renderViewByContent(resolvedContent) // If the content is a function `content(props)`, we initialize an effect // to react to changes. If the current fn uses signals, we will set the DirtySignal flag // to re-schedule the component updates if ( !this.#currentRenderEffectRef && typeof untracked(this.#content) === 'function' ) { this.#currentRenderEffectRef = effect( () => { this.#latestContent() if (!(this.#renderFlags & FlexRenderFlags.RenderEffectChecked)) { this.#renderFlags |= FlexRenderFlags.RenderEffectChecked return } this.#renderFlags |= FlexRenderFlags.Dirty this.#doCheck() }, { injector: this.#viewContainerRef.injector }, ) } } #shouldRecreateEntireView() { return ( this.#renderFlags & FlexRenderFlags.ContentChanged & FlexRenderFlags.ViewFirstRender ) } #doCheck() { const latestContent = this.#getContentValue() if (latestContent.kind === 'null' || !this.#renderView) { this.#renderFlags |= FlexRenderFlags.ContentChanged } else { this.#renderView.content = latestContent const { kind: previousKind } = this.#renderView.previousContent if (latestContent.kind !== previousKind) { this.#renderFlags |= FlexRenderFlags.ContentChanged } } this.#update() } #renderViewByContent( content: FlexRenderTypedContent, ): FlexRenderView | null { if (content.kind === 'primitive') { return this.#renderStringContent(content) } else if (content.kind === 'templateRef') { return this.#renderTemplateRefContent(content) } else if (content.kind === 'flexRenderComponent') { return this.#renderComponent(content) } else if (content.kind === 'component') { return this.#renderCustomComponent(content) } else { return null } } #renderStringContent( template: Extract, ): FlexRenderTemplateView { const context = () => { const content = this.#content() return typeof content === 'string' || typeof content === 'number' ? content : runInInjectionContext(this.#injector(), () => content?.(this.#props()), ) } const ref = this.#viewContainerRef.createEmbeddedView(this.#templateRef, { get $implicit() { return context() }, }) return new FlexRenderTemplateView(template, ref) } #renderTemplateRefContent( template: Extract, ): FlexRenderTemplateView { const latestContext = () => this.#props() const view = this.#viewContainerRef.createEmbeddedView( template.content, { get $implicit() { return latestContext() }, }, { injector: this.#getInjector() }, ) return new FlexRenderTemplateView(template, view) } #renderComponent( flexRenderComponent: Extract< FlexRenderTypedContent, { kind: 'flexRenderComponent' } >, ): FlexRenderComponentView { const { injector } = flexRenderComponent.content const componentInjector = this.#getInjector(injector) const view = this.#flexRenderComponentFactory.createComponent( flexRenderComponent.content, componentInjector, ) return new FlexRenderComponentView(flexRenderComponent, view) } #renderCustomComponent( component: Extract, ): FlexRenderComponentView { const instance = flexRenderComponent(component.content, { inputs: this.#props(), }) const injector = this.#getInjector(instance.injector) const view = this.#flexRenderComponentFactory.createComponent( instance, injector, ) return new FlexRenderComponentView(component, view) } #getInjector(parentInjector?: Injector) { const getContext = () => this.#props() const proxy = new Proxy(this.#props(), { get: (_, key) => getContext()[key as keyof typeof _], }) const staticProviders = [] if ('table' in proxy) { staticProviders.push({ provide: TanStackTableToken, useValue: () => proxy.table, }) } if ('cell' in proxy) { staticProviders.push({ provide: TanStackTableCellToken, useValue: () => proxy.cell, }) } if ('header' in proxy) { staticProviders.push({ provide: TanStackTableHeaderToken, useValue: () => proxy.header, }) } return Injector.create({ parent: parentInjector ?? this.#injector(), providers: [ ...staticProviders, { provide: FlexRenderComponentProps, useValue: proxy }, ], }) } } ================================================ FILE: packages/angular-table/src/flex-render/view.ts ================================================ import { TemplateRef, Type } from '@angular/core' import { FlexRenderComponentInstance } from './flexRenderComponent' import type { FlexRenderComponent } from './flexRenderComponent' import type { FlexRenderContent } from './renderer' import type { EmbeddedViewRef } from '@angular/core' import type { FlexRenderComponentRef } from './flexRenderComponentFactory' export type FlexRenderTypedContent = | { kind: 'null' } | { kind: 'primitive' content: string | number | Record } | { kind: 'flexRenderComponent'; content: FlexRenderComponent } | { kind: 'templateRef'; content: TemplateRef } | { kind: 'component'; content: Type } export function mapToFlexRenderTypedContent( content: FlexRenderContent, ): FlexRenderTypedContent { if (content === null || content === undefined) { return { kind: 'null' } } if (typeof content === 'string' || typeof content === 'number') { return { kind: 'primitive', content } } if (content instanceof FlexRenderComponentInstance) { return { kind: 'flexRenderComponent', content } } else if (content instanceof TemplateRef) { return { kind: 'templateRef', content } } else if (content instanceof Type) { return { kind: 'component', content } } else { return { kind: 'primitive', content } } } export abstract class FlexRenderView< TView extends FlexRenderComponentRef | EmbeddedViewRef | null, > { readonly view: TView #previousContent: FlexRenderTypedContent | undefined #content: FlexRenderTypedContent protected constructor( initialContent: Exclude, view: TView, ) { this.#content = initialContent this.view = view } get previousContent(): FlexRenderTypedContent { return this.#previousContent ?? { kind: 'null' } } get content() { return this.#content } set content(content: FlexRenderTypedContent) { this.#previousContent = this.#content this.#content = content } abstract updateProps(props: Record): void abstract dirtyCheck(): void abstract onDestroy(callback: Function): void abstract unmount(): void } export class FlexRenderTemplateView extends FlexRenderView< EmbeddedViewRef > { constructor( initialContent: Extract< FlexRenderTypedContent, { kind: 'primitive' | 'templateRef' } >, view: EmbeddedViewRef, ) { super(initialContent, view) } override updateProps(props: Record) { this.view.markForCheck() } override dirtyCheck() { // Basically a no-op. When the view is created via EmbeddedViewRef, we don't need to do any manual update // since this type of content has a proxy as a context, then every time the root component is checked for changes, // the property getter will be re-evaluated. // // If in a future we need to manually mark the view as dirty, just uncomment next line // this.view.markForCheck() } override unmount() { this.view.destroy() } override onDestroy(callback: Function) { this.view.onDestroy(callback) } } export class FlexRenderComponentView extends FlexRenderView< FlexRenderComponentRef > { constructor( initialContent: Extract< FlexRenderTypedContent, { kind: 'component' | 'flexRenderComponent' } >, view: FlexRenderComponentRef, ) { super(initialContent, view) } override updateProps(props: Record) { switch (this.content.kind) { case 'component': { this.view.setInputs(props) break } case 'flexRenderComponent': { // No-op. When FlexRenderFlags.PropsReferenceChanged is set, // FlexRenderComponent will be updated into `dirtyCheck`. break } } } override dirtyCheck() { switch (this.content.kind) { case 'component': { // Component context is currently valuated with the cell context. Since it's reference // shouldn't change, we force mark the component as dirty in order to re-evaluate function invocation in view. // NOTE: this should behave like having a component with ChangeDetectionStrategy.Default this.view.markAsDirty() break } case 'flexRenderComponent': { // Given context instance will always have a different reference than the previous one, // so instead of recreating the entire view, we will only update the current view if (this.view.eqType(this.content.content)) { this.view.update(this.content.content) } this.view.markAsDirty() break } } } override unmount() { this.view.componentRef.destroy() } override onDestroy(callback: Function) { this.view.componentRef.onDestroy(callback) } } ================================================ FILE: packages/angular-table/src/flexRender.ts ================================================ import { DestroyRef, Directive, Injector, InputSignal, TemplateRef, ViewContainerRef, inject, input, } from '@angular/core' import { FlexRenderInputContent, FlexViewRenderer, } from './flex-render/renderer' import type { CellContext, CellData, HeaderContext, RowData, TableFeatures, } from '@tanstack/table-core' export { injectFlexRenderContext, type FlexRenderComponentProps, } from './flex-render/context' export type { FlexRenderInputContent, FlexRenderContent, } from './flex-render/renderer' /** * Use this utility directive to render headers, cells, or footers with custom markup. * * Note: If you are rendering cell, header, or footer without custom context or other props, * you can use the {@link FlexRenderCell} directive as shorthand instead . * * @example * ```ts * import {FlexRender} from '@tanstack/angular-table'; * * @Component({ * imports: [FlexRender], * template: ` * * {{cell}} * * * * {{header}} * * * * {{footer}} * * `, * }) * class App { * } * ``` * * Can be imported through {@link FlexRenderDirective} or {@link FlexRender} import, * which the latter is preferred. */ @Directive({ selector: 'ng-template[flexRender]', }) export class FlexRenderDirective< TFeatures extends TableFeatures, TRowData extends RowData, TValue extends CellData, TProps extends | NonNullable | CellContext | HeaderContext, > { readonly content: InputSignal> = input( undefined as FlexRenderInputContent, { alias: 'flexRender' }, ) readonly props = input({} as TProps, { alias: 'flexRenderProps', }) readonly injector = input(inject(Injector), { alias: 'flexRenderInjector', }) readonly #viewContainerRef = inject(ViewContainerRef) readonly #templateRef = inject(TemplateRef) constructor() { const renderer = new FlexViewRenderer({ content: this.content, props: this.props, injector: this.injector, templateRef: this.#templateRef, viewContainerRef: this.#viewContainerRef, }) renderer.mount() inject(DestroyRef).onDestroy(() => { renderer.destroy() }) } } ================================================ FILE: packages/angular-table/src/helpers/cell.ts ================================================ import { Directive, InjectionToken, inject, input } from '@angular/core' import { Cell, CellData, RowData, TableFeatures } from '@tanstack/table-core' import type { Signal } from '@angular/core' /** * DI context shape for a TanStack Table cell. * * This exists to make the current `Cell` injectable by any nested component/directive * without having to pass it through inputs/props manually. */ export interface TanStackTableCellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, > { /** Signal that returns the current cell instance. */ cell: Signal> } /** * Injection token that provides access to the current cell. * * This token is provided by the {@link TanStackTableCell} directive. */ export const TanStackTableCellToken = new InjectionToken< TanStackTableCellContext['cell'] >('[TanStack Table] CellContext') /** * Provides a TanStack Table `Cell` instance in Angular DI. * * The cell can be injected by: * - any descendant of an element using `[tanStackTableCell]="..."` * - any component instantiated by `*flexRender` when the render props contains `cell` * * @example * Inject from the nearest `[tanStackTableCell]`: * ```html * * * * ``` * * ```ts * @Component({ * selector: 'app-cell-actions', * template: `{{ cell().id }}`, * }) * export class CellActionsComponent { * readonly cell = injectTableCellContext() * } * ``` * * @example * Inject inside a component rendered via `flexRender`: * ```ts * @Component({ * selector: 'app-price-cell', * template: `{{ cell().getValue() }}`, * }) * export class PriceCellComponent { * readonly cell = injectTableCellContext() * } * ``` */ @Directive({ selector: '[tanStackTableCell]', exportAs: 'cell', providers: [ { provide: TanStackTableCellToken, useFactory: () => inject(TanStackTableCell).cell, }, ], }) export class TanStackTableCell< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, > implements TanStackTableCellContext { /** * The current TanStack Table cell. * * Provided as a required signal input so DI consumers always read the latest value. */ readonly cell = input.required>({ alias: 'tanStackTableCell', }) } /** * Injects the current TanStack Table cell signal. * * Available when: * - there is a nearest `[tanStackTableCell]` directive in the DI tree, or * - the caller is rendered via `*flexRender` with render props containing `cell` */ export function injectTableCellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, >(): TanStackTableCellContext['cell'] { return inject(TanStackTableCellToken) } ================================================ FILE: packages/angular-table/src/helpers/createTableHook.ts ================================================ import { createColumnHelper as coreCreateColumnHelper } from '@tanstack/table-core' import { injectTable } from '../injectTable' import { injectFlexRenderContext } from '../flexRender' import { injectTableHeaderContext as _injectTableHeaderContext } from './header' import { injectTableContext as _injectTableContext } from './table' import { injectTableCellContext as _injectTableCellContext } from './cell' import type { FlexRenderContent } from '../flexRender' import type { AngularTable } from '../injectTable' import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, Cell, CellContext, CellData, Column, ColumnDef, DeepKeys, DeepValue, DisplayColumnDef, GroupColumnDef, Header, HeaderContext, IdentifiedColumnDef, Row, RowData, Table, TableFeature, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { Signal, Type } from '@angular/core' type RenderableComponent = | Type | (>(props: T) => FlexRenderContent) // ============================================================================= // Enhanced Context Types with Pre-bound Components // ============================================================================= /** * Enhanced CellContext with pre-bound cell components. * The `cell` property includes the registered cellComponents. */ export type AppCellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record, > = { cell: Cell & TCellComponents & { FlexRender: () => unknown } column: Column getValue: CellContext['getValue'] renderValue: CellContext['renderValue'] row: Row table: Table } /** * Enhanced HeaderContext with pre-bound header components. * The `header` property includes the registered headerComponents. */ export type AppHeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record, > = { column: Column header: Header & THeaderComponents & { FlexRender: () => unknown } table: Table } // ============================================================================= // Enhanced Column Definition Types // ============================================================================= /** * Template type for column definitions that can be a string or a function. */ type AppColumnDefTemplate = | string | ((props: TProps) => any) /** * Enhanced column definition base with pre-bound components in cell/header/footer contexts. */ type AppColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record, THeaderComponents extends Record, > = Omit< IdentifiedColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced display column definition with pre-bound components. */ type AppDisplayColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record, THeaderComponents extends Record, > = Omit< DisplayColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced group column definition with pre-bound components. */ type AppGroupColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record, THeaderComponents extends Record, > = Omit< GroupColumnDef, 'cell' | 'header' | 'footer' | 'columns' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > columns?: ReadonlyArray> } // ============================================================================= // Enhanced Column Helper Type // ============================================================================= /** * Enhanced column helper with pre-bound components in cell/header/footer contexts. * This enables TypeScript to know about the registered components when defining columns. */ export type AppColumnHelper< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record, THeaderComponents extends Record, > = { /** * Creates a data column definition with an accessor key or function. * The cell, header, and footer contexts include pre-bound components. */ accessor: < TAccessor extends AccessorFn | DeepKeys, TValue extends TAccessor extends AccessorFn ? TReturn : TAccessor extends DeepKeys ? DeepValue : never, >( accessor: TAccessor, column: TAccessor extends AccessorFn ? AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents > & { id: string } : AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents >, ) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef /** * Wraps an array of column definitions to preserve each column's individual TValue type. */ columns: >>( columns: [...TColumns], ) => Array> & [...TColumns] /** * Creates a display column definition for non-data columns. * The cell, header, and footer contexts include pre-bound components. */ display: ( column: AppDisplayColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => DisplayColumnDef /** * Creates a group column definition with nested child columns. * The cell, header, and footer contexts include pre-bound components. */ group: ( column: AppGroupColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => GroupColumnDef } /** * Extended table API returned by useAppTable with all App wrapper components */ export type AppAngularTable< TFeatures extends TableFeatures, TData extends RowData, TSelected, TTableComponents extends Record, TCellComponents extends Record, THeaderComponents extends Record, > = AngularTable & NoInfer & { appCell: ( cell: Cell, ) => Cell & NoInfer appHeader: ( header: Header, ) => Header & NoInfer appFooter: ( footer: Header, ) => Header & NoInfer } // ============================================================================= // CreateTableHook Options and Props // ============================================================================= /** * Options for creating a table hook with pre-bound components and default table options. * Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. */ export type CreateTableContextOptions< TFeatures extends TableFeatures, TTableComponents extends Record, TCellComponents extends Record, THeaderComponents extends Record, > = Omit< TableOptions, 'columns' | 'data' | 'store' | 'state' | 'initialState' > & { /** * Table-level components that need access to the table instance. * These are available directly on the table object returned by useAppTable. * Use `useTableContext()` inside these components. * @example { PaginationControls, GlobalFilter, RowCount } */ tableComponents?: TTableComponents /** * Cell-level components that need access to the cell instance. * These are available on the cell object passed to AppCell's children. * Use `useCellContext()` inside these components. * @example { TextCell, NumberCell, DateCell, CurrencyCell } */ cellComponents?: TCellComponents /** * Header-level components that need access to the header instance. * These are available on the header object passed to AppHeader/AppFooter's children. * Use `useHeaderContext()` inside these components. * @example { SortIndicator, ColumnFilter, ResizeHandle } */ headerComponents?: THeaderComponents } export type CreateTableHookResult< TFeatures extends TableFeatures, TTableComponents extends Record, TCellComponents extends Record, THeaderComponents extends Record, > = { createAppColumnHelper: () => AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > injectTableContext: () => Signal< AngularTable > injectTableHeaderContext: < TValue extends CellData = CellData, TRowData extends RowData = RowData, >() => Signal> injectTableCellContext: < TValue extends CellData = CellData, TRowData extends RowData = RowData, >() => Signal> injectFlexRenderHeaderContext: < TData extends RowData, TValue extends CellData, >() => HeaderContext injectFlexRenderCellContext: < TData extends RowData, TValue extends CellData, >() => CellContext injectAppTable: >( tableOptions: () => Omit< TableOptions, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ) => AppAngularTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > } export function createTableHook< TFeatures extends TableFeatures, const TTableComponents extends Record, const TCellComponents extends Record, const THeaderComponents extends Record, >({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableContextOptions< TFeatures, TTableComponents, TCellComponents, THeaderComponents >): CreateTableHookResult< TFeatures, TTableComponents, TCellComponents, THeaderComponents > { function injectTableContext(): Signal< AngularTable > { return _injectTableContext() } function injectTableHeaderContext< TValue extends CellData = CellData, TRowData extends RowData = RowData, >(): Signal> { return _injectTableHeaderContext() } function injectTableCellContext< TValue extends CellData = CellData, TRowData extends RowData = RowData, >(): Signal> { return _injectTableCellContext() } function injectFlexRenderHeaderContext< TData extends RowData, TValue extends CellData, >(): HeaderContext { return injectFlexRenderContext>() } function injectFlexRenderCellContext< TData extends RowData, TValue extends CellData, >(): CellContext { return injectFlexRenderContext>() } function injectAppTable( tableOptions: () => Omit< TableOptions, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ): AppAngularTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > { function appCell(cell: Cell) { return cell as Cell & TCellComponents } function appHeader(header: Header) { return header as Header & THeaderComponents } function appFooter(footer: Header) { return footer as Header & THeaderComponents } const appTableFeatures: TableFeature<{}> = { constructTableAPIs: (table) => { Object.assign(table, tableComponents, { appCell, appHeader, appFooter }) }, assignCellPrototype(prototype) { Object.assign(prototype, cellComponents) }, assignHeaderPrototype(prototype) { Object.assign(prototype, headerComponents) }, } return injectTable(() => { const options = { ...defaultTableOptions, ...tableOptions(), } as TableOptions options._features = { ...options._features, appTableFeatures } return options }, selector) as AngularTable } function createAppColumnHelper(): AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > { // The runtime implementation is the same - components are attached at render time // This cast provides the enhanced types for column definitions return coreCreateColumnHelper() as AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > } return { createAppColumnHelper, injectTableContext, injectTableHeaderContext, injectTableCellContext, injectFlexRenderHeaderContext, injectFlexRenderCellContext, injectAppTable, } } ================================================ FILE: packages/angular-table/src/helpers/flexRenderCell.ts ================================================ import { DestroyRef, Directive, Injector, TemplateRef, ViewContainerRef, computed, inject, input, } from '@angular/core' import { Cell, CellData, Header, RowData, TableFeatures, } from '@tanstack/table-core' import { FlexViewRenderer } from '../flex-render/renderer' import type { FlexRenderInputContent } from '../flex-render/renderer' import type { CellContext, HeaderContext } from '@tanstack/table-core' /** * Simplified directive wrapper of `*flexRender`. * * Use this utility component to render headers, cells, or footers with custom markup. * * Only one prop (`cell`, `header`, or `footer`) may be passed based on the used selector. * * @example * ```html * {{cell}} * {{header}} * {{footer}} * ``` * * This replaces calling `*flexRender` directly like this: * ```html * {{cell}} * {{header}} * {{footer}} * ``` * * Can be imported through {@link FlexRenderCell} or {@link FlexRender} import, * which the latter is preferred. * * @example * ```ts * import {FlexRender} from '@tanstack/angular-table * * @Component({ * // ... * imports: [ * FlexRender * ] * }) * ``` */ @Directive({ selector: 'ng-template[flexRenderCell], ng-template[flexRenderFooter], ng-template[flexRenderHeader]', }) export class FlexRenderCell< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, > { readonly cell = input>(undefined, { alias: 'flexRenderCell', }) readonly header = input>(undefined, { alias: 'flexRenderHeader', }) readonly footer = input>(undefined, { alias: 'flexRenderFooter', }) readonly #renderData = computed< | [ content: FlexRenderInputContent>, props: CellContext, ] | [ content: FlexRenderInputContent< HeaderContext >, props: HeaderContext, ] | [content: null, props: null] >( () => { const cell = this.cell() const header = this.header() const footer = this.footer() if (cell) { return [cell.column.columnDef.cell, cell.getContext()] } if (header) { return [header.column.columnDef.header, header.getContext()] } if (footer) { return [footer.column.columnDef.footer, footer.getContext()] } return [null, null] }, { equal: (a, b) => { return a[0] === b[0] && a[1] === b[1] }, }, ) readonly #injector = inject(Injector) readonly #templateRef = inject(TemplateRef) readonly #viewContainerRef = inject(ViewContainerRef) constructor() { const content = computed(() => this.#renderData()[0]) const props = computed(() => this.#renderData()[1]) const renderer = new FlexViewRenderer({ content: content, props: props, injector: () => this.#injector, templateRef: this.#templateRef, viewContainerRef: this.#viewContainerRef, }) renderer.mount() inject(DestroyRef).onDestroy(() => { renderer.destroy() }) } } ================================================ FILE: packages/angular-table/src/helpers/header.ts ================================================ import { Directive, InjectionToken, inject, input } from '@angular/core' import { CellData, Header, RowData, TableFeatures } from '@tanstack/table-core' import type { Signal } from '@angular/core' /** * DI context shape for a TanStack Table header. * * This exists to make the current `Header` injectable by any nested component/directive * without passing it through inputs/props. */ export interface TanStackTableHeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, > { /** Signal that returns the current header instance. */ header: Signal> } /** * Injection token that provides access to the current header. * * This token is provided by the {@link TanStackTableHeader} directive. */ export const TanStackTableHeaderToken = new InjectionToken< TanStackTableHeaderContext['header'] >('[TanStack Table] HeaderContext') /** * Provides a TanStack Table `Header` instance in Angular DI. * * The header can be injected by: * - any descendant of an element using `[tanStackTableHeader]="..."` * - any component instantiated by `*flexRender` when the render props contains `header` * * @example * ```html * * * * ``` * * ```ts * @Component({ * selector: 'app-sort-indicator', * template: ` * * `, * }) * export class SortIndicatorComponent { * readonly header = injectTableHeaderContext() * * toggle() { * this.header().column.toggleSorting() * } * } * ``` */ @Directive({ selector: '[tanStackTableHeader]', exportAs: 'header', providers: [ { provide: TanStackTableHeaderToken, useFactory: () => inject(TanStackTableHeader).header, }, ], }) export class TanStackTableHeader< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, > implements TanStackTableHeaderContext { /** * The current TanStack Table header. * * Provided as a required signal input so DI consumers always read the latest value. */ readonly header = input.required>({ alias: 'tanStackTableHeader', }) } /** * Injects the current TanStack Table header signal. * * Available when: * - there is a nearest `[tanStackTableHeader]` directive in the DI tree, or * - the caller is rendered via `*flexRender` with render props containing `header` */ export function injectTableHeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, >(): TanStackTableHeaderContext['header'] { return inject(TanStackTableHeaderToken) } ================================================ FILE: packages/angular-table/src/helpers/table.ts ================================================ import { Directive, InjectionToken, inject, input } from '@angular/core' import { RowData, TableFeatures, TableState } from '@tanstack/table-core' import { AngularTable } from '../injectTable' import type { Signal } from '@angular/core' /** * Injection token that provides access to the current {@link AngularTable} instance. * * This token is provided by the {@link TanStackTable} directive. */ export const TanStackTableToken = new InjectionToken< Signal> >('[TanStack Table] Table Context') /** * Provides a TanStack Table instance (`AngularTable`) in Angular DI. * * The table can be injected by: * - any descendant of an element using `[tanStackTable]="..."` * - any component instantiated by `*flexRender` when the render props contains `table` * * @example * ```html *
* *
* ``` * * ```ts * @Component({ * selector: 'app-pagination', * template: ` * * * `, * }) * export class PaginationComponent { * readonly table = injectTableContext() * * prev() { * this.table().previousPage() * } * next() { * this.table().nextPage() * } * } * ``` */ @Directive({ selector: '[tanStackTable]', exportAs: 'table', providers: [ { provide: TanStackTableToken, useFactory: () => inject(TanStackTable).table, }, ], }) export class TanStackTable< TFeatures extends TableFeatures, TData extends RowData, TSelected extends {} = TableState, > { /** * The current TanStack Table instance. * * Provided as a required signal input so DI consumers always read the latest value. */ readonly table = input.required>({ alias: 'tanStackTable', }) } /** * Injects the current TanStack Table instance signal. * * Available when: * - there is a nearest `[tanStackTable]` directive in the DI tree, or * - the caller is rendered via `*flexRender` with render props containing `table` */ export function injectTableContext< TFeatures extends TableFeatures, TData extends RowData, TSelected extends {} = TableState, >(): Signal> { return inject(TanStackTableToken) } ================================================ FILE: packages/angular-table/src/index.ts ================================================ import { FlexRenderCell } from './helpers/flexRenderCell' import { FlexRenderDirective } from './flexRender' export * from '@tanstack/table-core' export * from './flexRender' export * from './injectTable' export * from './flex-render/flexRenderComponent' export * from './helpers/cell' export * from './helpers/header' export * from './helpers/table' export * from './helpers/createTableHook' export * from './helpers/flexRenderCell' /** * Constant helper to import FlexRender directives. * * You should prefer to use this constant over importing the directives separately, * as it ensures you always have the correct set of directives over library updates. * * @see {@link FlexRenderDirective} and {@link FlexRenderCell} for more details on the directives included in this export. */ export const FlexRender = [FlexRenderDirective, FlexRenderCell] as const ================================================ FILE: packages/angular-table/src/injectTable.ts ================================================ import { Injector, assertInInjectionContext, computed, effect, inject, signal, untracked, } from '@angular/core' import { constructReactivityFeature, constructTable, } from '@tanstack/table-core' import { injectStore } from '@tanstack/angular-store' import { lazyInit } from './lazySignalInitializer' import type { RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { Signal, ValueEqualityFn } from '@angular/core' export type AngularTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState, > = Table & { /** * The selected state from the table store, based on the selector provided. */ readonly state: Signal> /** * A signal that returns the entire table instance. Will update on table/options change. */ readonly value: Signal> /** * Creates a computed that subscribe to changes in the table store with a custom selector. * Default equality function is "shallow". */ computed: (props: { selector: (state: TableState) => TSubSelected equal?: ValueEqualityFn }) => Signal> } /** * Creates and returns an Angular-reactive table instance. * * The initializer is intentionally re-evaluated whenever any signal read inside it changes. * This is how the adapter keeps the table in sync with Angular's reactivity model. * * Because of that behavior, keep expensive/static values (for example `columns`, feature setup, row models) * as stable references outside the initializer, and only read reactive state (`data()`, pagination/filter/sorting signals, etc.) * inside it. * * The returned table is also signal-reactive: table state and table APIs are wired for Angular signals, so you can safely consume table methods inside `computed(...)` and `effect(...)`. * * @example * 1. Register the table features you need * ```ts * // Register only the features you need * import {tableFeatures, rowPaginationFeature} from '@tanstack/angular-table'; * const _features = tableFeatures({ * rowPaginationFeature, * // ...all other features you need * }) * * // Use all table core features * import {stockFeatures} from '@tanstack/angular-table'; * const _features = tableFeatures(stockFeatures); * ``` * 2. Prepare the table columns * ```ts * import {ColumnDef} from '@tanstack/angular-table'; * * type MyData = {} * * const columns: ColumnDef[] = [ * // ...column definitions * ] * * // or using createColumnHelper * import {createColumnHelper} from '@tanstack/angular-table'; * const columnHelper = createColumnHelper(); * const columns = columnHelper.columns([ * columnHelper.accessor(...), * // ...other columns * ]) * ``` * 3. Create the table instance with `injectTable` * ```ts * const table = injectTable(() => { * // ...table options, * _features, * columns: columns, * data: myDataSignal(), * }) * ``` * * @returns An Angular-reactive TanStack Table instance. */ export function injectTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState, >( options: () => TableOptions, selector: (state: TableState) => TSelected = (state) => state as TSelected, ): AngularTable { assertInInjectionContext(injectTable) const injector = inject(Injector) const stateNotifier = signal(0) const angularReactivityFeature = constructReactivityFeature({ stateNotifier: () => stateNotifier(), }) return lazyInit(() => { const resolvedOptions: TableOptions = { ...options(), _features: { ...options()._features, angularReactivityFeature, }, } as TableOptions const table = constructTable(resolvedOptions) as AngularTable< TFeatures, TData, TSelected > const tableState = injectStore(table.store, (state) => state, { injector }) const tableOptions = injectStore(table.optionsStore, (state) => state, { injector, }) const updatedOptions = computed>(() => { const tableOptionsValue = options() const result: TableOptions = { ...untracked(() => table.options), ...tableOptionsValue, _features: { ...tableOptionsValue._features, angularReactivityFeature }, } if (tableOptionsValue.state) { result.state = tableOptionsValue.state } return result }) effect( () => { const newOptions = updatedOptions() untracked(() => table.setOptions(newOptions)) }, { injector, debugName: 'tableOptionsUpdate' }, ) let isMount = true effect( () => { void [tableOptions(), tableState()] if (!isMount) untracked(() => stateNotifier.update((n) => n + 1)) isMount && (isMount = false) }, { injector, debugName: 'tableStateNotifier' }, ) table.computed = function Subscribe(props: { selector: (state: TableState) => TSubSelected equal?: ValueEqualityFn }) { return injectStore(table.store, props.selector, { injector, equal: props.equal, }) } Object.defineProperty(table, 'state', { value: injectStore(table.store, selector, { injector }), }) Object.defineProperty(table, 'value', { value: computed(() => { tableOptions() tableState() return table }), }) return table }) } ================================================ FILE: packages/angular-table/src/lazySignalInitializer.ts ================================================ import { untracked } from '@angular/core' /** * Implementation from @tanstack/angular-query * {https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/util/lazy-init/lazy-init.ts} */ export function lazyInit(initializer: () => T): T { let object: T | null = null const initializeObject = () => { if (!object) { object = untracked(() => initializer()) } } queueMicrotask(() => initializeObject()) const table = () => {} return new Proxy(table as T, { apply(target: T, thisArg: any, argArray: Array): any { initializeObject() if (typeof object === 'function') { return Reflect.apply(object, thisArg, argArray) } return Reflect.apply(target as any, thisArg, argArray) }, get(_, prop, receiver) { initializeObject() return Reflect.get(object as T, prop, receiver) }, has(_, prop) { initializeObject() return Reflect.has(object as T, prop) }, ownKeys() { initializeObject() return Reflect.ownKeys(object as T) }, getOwnPropertyDescriptor() { return { enumerable: true, configurable: true, } }, }) } ================================================ FILE: packages/angular-table/tests/angularReactivityFeature.test.ts ================================================ import { describe, expect, test, vi } from 'vitest' import { computed, effect, signal } from '@angular/core' import { TestBed } from '@angular/core/testing' import { injectTable, stockFeatures } from '../src' import type { ColumnDef } from '../src' import type { WritableSignal } from '@angular/core' describe('angularReactivityFeature', () => { type Data = { id: string; title: string } const data = signal>([{ id: '1', title: 'Title' }]) const columns: Array> = [ { id: 'id', header: 'Id', accessorKey: 'id', cell: (context) => context.getValue(), }, { id: 'title', header: 'Title', accessorKey: 'title', cell: (context) => context.getValue(), }, ] function createTestTable(_data: WritableSignal> = data) { return TestBed.runInInjectionContext(() => injectTable(() => ({ data: _data(), _features: { ...stockFeatures }, columns: columns, getRowId: (row) => row.id, reactivity: { column: true, cell: true, row: true, header: true, }, })), ) } const table = createTestTable() describe('Integration', () => { test('methods within effect will be re-trigger when options/state changes', () => { const data = signal>([{ id: '1', title: 'Title' }]) const table = createTestTable(data) const isSelectedRow1Captor = vi.fn<(val: boolean) => void>() const cellGetValueCaptor = vi.fn<(val: unknown) => void>() const cellGetValueMemoizedCaptor = vi.fn<(val: unknown) => void>() const columnIsVisibleCaptor = vi.fn<(val: boolean) => void>() // This will test a case where you put in the effect a single cell property method // which will trigger effect reschedule only when the value changes, acting like // its a computed value const cell = computed( () => table.getRowModel().rows[0]!.getAllCells()[0]!, ) const cellGetValue = computed(() => cell().getValue()) TestBed.runInInjectionContext(() => { effect(() => { isSelectedRow1Captor(cell().row.getIsSelected()) }) effect(() => { cellGetValueCaptor(cell().getValue()) }) effect(() => { cellGetValueMemoizedCaptor(cellGetValue()) }) effect(() => { columnIsVisibleCaptor(cell().column.getIsVisible()) }) }) TestBed.tick() expect(isSelectedRow1Captor).toHaveBeenCalledTimes(1) expect(cellGetValueMemoizedCaptor).toHaveBeenCalledTimes(1) expect(cellGetValueCaptor).toHaveBeenCalledTimes(1) expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(1) cell().row.toggleSelected(true) TestBed.tick() expect(isSelectedRow1Captor).toHaveBeenCalledTimes(2) expect(cellGetValueCaptor).toHaveBeenCalledTimes(1) expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(2) data.set([{ id: '1', title: 'Title 3' }]) TestBed.tick() // In this case it will be called twice since `data` will change and // the cell instance will be recreated expect(isSelectedRow1Captor).toHaveBeenCalledTimes(3) expect(cellGetValueCaptor).toHaveBeenCalledTimes(2) expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(3) cell().column.toggleVisibility(false) TestBed.tick() expect(isSelectedRow1Captor).toHaveBeenCalledTimes(4) expect(cellGetValueCaptor).toHaveBeenCalledTimes(2) expect(columnIsVisibleCaptor).toHaveBeenCalledTimes(4) expect(isSelectedRow1Captor.mock.calls).toEqual([ [false], [true], [true], [true], ]) expect(cellGetValueCaptor.mock.calls).toEqual([['1'], ['1']]) expect(columnIsVisibleCaptor.mock.calls).toEqual([ [true], [true], [true], [false], ]) }) }) }) ================================================ FILE: packages/angular-table/tests/benchmarks/injectTable.benchmark.ts ================================================ import { setTimeout } from 'node:timers/promises' import { bench, describe } from 'vitest' import { benchCases, columns, createTestTable, dataMap } from './setup' const nIteration = 5 for (const benchCase of benchCases) { describe(`injectTable - ${benchCase.size} elements`, () => { const data = dataMap[benchCase.size]! bench( `No reactivity`, async () => { const table = createTestTable(false, data, columns) await setTimeout(0) table.getRowModel() }, { iterations: nIteration, }, ) bench( `Full reactivity`, async () => { const table = createTestTable(true, data, columns) await setTimeout(0) table.getRowModel() }, { iterations: nIteration, }, ) }) } ================================================ FILE: packages/angular-table/tests/benchmarks/setup.ts ================================================ import { injectTable, stockFeatures } from '../../src' import type { ColumnDef } from '../../src' export function createData(size: number) { return Array.from({ length: size }, (_, index) => ({ id: index, title: `title-${index}`, name: `name-${index}`, })) } export const columns: Array> = [ { id: 'col1' }, { id: 'col2' }, { id: 'col3' }, { id: 'col4' }, { id: 'col5' }, { id: 'col6' }, { id: 'col7' }, ] export function createTestTable( enableGranularReactivity: boolean, data: Array, columns: Array, ) { return injectTable(() => ({ _features: stockFeatures, columns: columns, data, reactivity: { table: enableGranularReactivity, row: enableGranularReactivity, column: enableGranularReactivity, cell: enableGranularReactivity, header: enableGranularReactivity, }, })) } export const benchCases = [ { size: 100, max: 5, threshold: 10 }, { size: 1000, max: 25, threshold: 50 }, { size: 2000, max: 50, threshold: 100 }, { size: 5000, max: 100, threshold: 500 }, { size: 10_000, max: 200, threshold: 1000 }, { size: 25_000, max: 500, threshold: 1000 }, { size: 50_000, max: 1500, threshold: 1000 }, { size: 100_000, max: 2000, threshold: 1500 }, ] console.log('Seeding data...') export const dataMap = {} as Record> for (const benchCase of benchCases) { dataMap[benchCase.size] = createData(benchCase.size) } console.log('Seed data completed') ================================================ FILE: packages/angular-table/tests/flex-render/flex-render-component.test-d.ts ================================================ import { input } from '@angular/core' import { test } from 'vitest' import { flexRenderComponent } from '../../src' test('Infer component inputs', () => { class Test { readonly input1 = input() } // @ts-expect-error Must pass right type as a value flexRenderComponent(Test, { inputs: { input1: 1 } }) // Input is optional so we can skip passing the property flexRenderComponent(Test, { inputs: {} }) }) ================================================ FILE: packages/angular-table/tests/flex-render/flex-render-table.test.ts ================================================ import { ChangeDetectionStrategy, Component, ViewChild, input, inputBinding, output, outputBinding, signal, } from '@angular/core' import { ColumnDef, createCoreRowModel, stockFeatures, } from '@tanstack/table-core' import { TestBed } from '@angular/core/testing' import { describe, expect, test, vi } from 'vitest' import { By } from '@angular/platform-browser' import { FlexRender, flexRenderComponent, injectFlexRenderContext, injectTable, } from '../../src' import type { FlexRenderContent } from '../../src' import type { CellContext, ExpandedState, TableOptions, } from '@tanstack/table-core' import type { TemplateRef } from '@angular/core' const defaultData: Array = [ { id: '1', title: 'My title' }, ] as Array const defaultColumns: Array> = [ { id: 'title', accessorKey: 'title', header: 'Title', cell: (props) => props.renderValue(), }, ] describe('FlexRenderDirective', () => { test.each([null, undefined])('Render %s as empty', (value) => { const { fixture, dom } = createTestTable(defaultData, [ { id: 'first_cell', header: 'header', cell: () => value }, ]) const row = dom.getBodyRow(0)! const firstCell = row.querySelector('td') expect(firstCell!.matches(':empty')).toBe(true) }) test.each([ ['String column via function', () => 'My string'], ['String column', () => 'My string'], ['Number column via function', () => 0], ['Number column', 0], ])('Render primitive (%s)', (columnName, columnValue) => { const { fixture, dom } = createTestTable(defaultData, [ { id: 'first_cell', header: columnName, cell: columnValue as any }, ]) const row = dom.getBodyRow(0)! const firstCell = row.querySelector('td') expectPrimitiveValueIs( firstCell, String(typeof columnValue === 'function' ? columnValue() : columnValue), ) }) test('Render TemplateRef', () => { @Component({ template: ` Cell id: {{ context.cell.id }} `, standalone: true, }) class FakeTemplateRefComponent { @ViewChild('template', { static: true }) templateRef!: TemplateRef } const templateRef = TestBed.createComponent(FakeTemplateRefComponent) .componentInstance.templateRef const { dom } = createTestTable(defaultData, [ { id: 'first_cell', header: 'Header', cell: () => templateRef }, ]) const row = dom.getBodyRow(0)! const firstCell = row.querySelector('td') expect(firstCell!.textContent).toEqual('Cell id: 0_first_cell') }) test('Render component with FlexRenderComponent', async () => { const status = signal('Initial status') const { dom, fixture } = createTestTable(defaultData, [ { id: 'first_cell', header: 'Status', cell: () => { return flexRenderComponent(TestBadgeComponent, { inputs: { status: status(), }, }) }, }, ]) const row = dom.getBodyRow(0)! const firstCell = row.querySelector('td') expect(firstCell!.textContent).toEqual('Initial status') status.set('Updated status') await fixture.whenStable() expect(firstCell!.textContent).toEqual('Updated status') }) test('Render content reactively based on signal value', async () => { const statusComponent = signal>('Initial status') const { dom, fixture } = createTestTable(defaultData, [ { id: 'first_cell', header: 'Status', cell: () => { return statusComponent() }, }, ]) const row = dom.getBodyRow(0)! const firstCell = row.querySelector('td') expect(firstCell!.textContent).toEqual('Initial status') statusComponent.set(null) await fixture.whenRenderingDone() expect(firstCell!.matches(':empty')).toBe(true) statusComponent.set( flexRenderComponent(TestBadgeComponent, { inputs: { status: 'Updated status' }, }), ) await fixture.whenRenderingDone() const el = firstCell!.firstElementChild as HTMLElement expect(el.tagName).toEqual('APP-TEST-BADGE') expect(el.textContent).toEqual('Updated status') }) test('Cell content always get the latest context value', async () => { const contextCaptor = vi.fn() @Component({ template: ``, }) class EmptyCell {} const { dom, fixture } = createTestTable(defaultData, [ { id: 'cell', header: 'Header', cell: (context) => { contextCaptor(context) return flexRenderComponent(EmptyCell) }, }, ]) const latestCall = () => contextCaptor.mock.lastCall![0] as CellContext< typeof stockFeatures, TestData, any > expect(contextCaptor).toHaveBeenCalledTimes(1) expect(latestCall().row.getIsExpanded()).toEqual(false) const table = fixture.componentInstance.table table.getRow('0').toggleSelected(true) await fixture.whenStable() expect(contextCaptor).toHaveBeenCalledTimes(1) expect(latestCall().row.getIsSelected()).toEqual(true) table.getRow('0').toggleSelected(false) table.getRow('0').toggleExpanded(true) await fixture.whenStable() expect(contextCaptor).toHaveBeenCalledTimes(1) expect(latestCall().row.getIsSelected()).toEqual(false) expect(latestCall().row.getIsExpanded()).toEqual(true) }) test('Support cell with component output', async () => { const callExpandRender = vi.fn<(val: boolean) => void>() const columns = [ { id: 'expand', header: 'Expand', cell: ({ row }: any) => { callExpandRender(row.getIsExpanded()) return flexRenderComponent(ExpandCell, { inputs: { expanded: row.getIsExpanded() }, outputs: { toggleExpand: () => row.toggleExpanded() }, }) }, }, ] satisfies Array> @Component({ selector: 'expand-cell', template: ` `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, }) class ExpandCell { readonly expanded = input(false) readonly toggleExpand = output() } @Component({ template: ` @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
`, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, selector: 'app-table-test', imports: [FlexRender], }) class TestComponent { readonly expandState = signal({}) readonly table = injectTable(() => { return { columns: columns, data: defaultData, _features: stockFeatures, _rowModels: { coreRowModel: createCoreRowModel(), }, state: { expanded: this.expandState() }, onExpandedChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.expandState.update(updaterOrValue) : this.expandState.set(updaterOrValue) }, } as TableOptions }) } const fixture = TestBed.createComponent(TestComponent) fixture.detectChanges() const expandCell = fixture.debugElement.query(By.directive(ExpandCell)) expect(fixture.componentInstance.expandState()).toEqual({}) expect(expandCell.componentInstance.expanded()).toEqual(false) const buttonEl = expandCell.query(By.css('button')) expect(buttonEl.nativeElement.innerHTML).toEqual(' Not expanded ') buttonEl.triggerEventHandler('click') expect(fixture.componentInstance.expandState()).toEqual({ '0': true, }) await fixture.whenStable() expect(callExpandRender).toHaveBeenCalledTimes(2) expect(callExpandRender).toHaveBeenNthCalledWith(1, false) expect(callExpandRender).toHaveBeenNthCalledWith(2, true) expect(buttonEl.nativeElement.innerHTML).toEqual(' Expanded ') }) test('Support cell with component input/output binding', async () => { const callExpandRender = vi.fn<() => void>() const columns = [ { id: 'expand', header: 'Expand', cell: ({ row }: any) => { callExpandRender() return flexRenderComponent(ExpandCell, { bindings: [ inputBinding('expanded', () => row.getIsExpanded()), outputBinding('toggleExpand', () => row.toggleExpanded()), ], }) }, }, ] satisfies Array> @Component({ selector: 'expand-cell', template: ` `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, }) class ExpandCell { readonly expanded = input(false) readonly toggleExpand = output() } @Component({ template: ` @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
`, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, selector: 'app-table-test', imports: [FlexRender], }) class TestComponent { readonly expandState = signal({}) readonly table = injectTable(() => { return { columns: columns, data: defaultData, _features: stockFeatures, _rowModels: { coreRowModel: createCoreRowModel(), }, state: { expanded: this.expandState() }, onExpandedChange: (updaterOrValue) => { typeof updaterOrValue === 'function' ? this.expandState.update(updaterOrValue) : this.expandState.set(updaterOrValue) }, } as TableOptions }) } const fixture = TestBed.createComponent(TestComponent) await fixture.whenStable() const expandCell = fixture.debugElement.query(By.directive(ExpandCell)) expect(fixture.componentInstance.expandState()).toEqual({}) expect(expandCell.componentInstance.expanded()).toEqual(false) const buttonEl = expandCell.query(By.css('button')) expect(buttonEl.nativeElement.innerHTML).toEqual(' Not expanded ') buttonEl.triggerEventHandler('click') expect(fixture.componentInstance.expandState()).toEqual({ '0': true, }) await fixture.whenStable() expect(callExpandRender).toHaveBeenCalledTimes(1) expect(buttonEl.nativeElement.innerHTML).toEqual(' Expanded ') }) }) function expectPrimitiveValueIs( cell: HTMLTableCellElement | null, value: unknown, ) { expect(cell).not.toBeNull() expect(cell!.matches(':empty')).toBe(false) const span = cell!.querySelector('span')! expect(span).toBeDefined() expect(span.innerHTML).toEqual(value) } type TestData = { id: string; title: string } export function createTestTable( data: Array, columns: Array>, optionsFn?: () => Partial>, ) { @Component({ template: ` @for (headerGroup of table.getHeaderGroups(); track headerGroup.id) { @for (header of headerGroup.headers; track header.id) { @if (!header.isPlaceholder) { } } } @for (row of table.getRowModel().rows; track row.id) { @for (cell of row.getVisibleCells(); track cell.id) { } }
{{ count() }} `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, selector: 'app-table-test', imports: [FlexRender], }) class TestComponent { readonly columns = input>>(columns) readonly data = input>(data) readonly count = signal(0) readonly table = injectTable(() => { return { ...(optionsFn?.() ?? {}), _features: stockFeatures, _rowModels: { coreRowModel: createCoreRowModel(), }, columns: this.columns(), data: this.data(), } as TableOptions }) } const fixture = TestBed.createComponent(TestComponent) fixture.detectChanges() return { fixture, dom: { getTable() { return fixture.nativeElement.querySelector('table') as HTMLTableElement }, getHeader() { return this.getTable().querySelector('thead') as HTMLTableSectionElement }, getHeaderRow() { return this.getHeader().querySelector('tr') as HTMLTableRowElement }, getBody() { return this.getTable().querySelector('tbody') as HTMLTableSectionElement }, getBodyRow(index: number) { return this.getBody().rows.item(index) }, }, } } @Component({ selector: 'app-test-badge', template: `{{ status() }} `, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) class TestBadgeComponent { readonly context = injectFlexRenderContext>() readonly status = input.required() } ================================================ FILE: packages/angular-table/tests/flex-render/flex-render.unit.test.ts ================================================ import { Component, ViewChild, input } from '@angular/core' import { TestBed } from '@angular/core/testing' import { createColumnHelper } from '@tanstack/table-core' import { describe, expect, test } from 'vitest' import { FlexRender, FlexRenderDirective, flexRenderComponent, injectFlexRenderContext, } from '../../src' import { setFixtureSignalInput, setFixtureSignalInputs } from '../test-utils' import type { TemplateRef } from '@angular/core' import type { ComponentFixture } from '@angular/core/testing' interface Data { id: string title: string description: string status: 'success' | 'failed' | 'pending' favorite?: boolean } describe('FlexRenderDirective', () => { const helper = createColumnHelper<{}, Data>() test('should render primitives', () => { const fixture = TestBed.createComponent(TestRenderComponent) // Null setFixtureSignalInputs(fixture, { content: () => null, context: {}, }) expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true) // Undefined setFixtureSignalInputs(fixture, { content: () => undefined, context: {}, }) expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true) // String setFixtureSignalInputs(fixture, { content: 'My value', context: {}, }) expectPrimitiveValueIs(fixture, 'My value') // Numbers setFixtureSignalInputs(fixture, { content: 0, context: {}, }) expectPrimitiveValueIs(fixture, '0') // Functions that returns primitives setFixtureSignalInputs(fixture, { content: () => 'My value 2', context: {}, }) expectPrimitiveValueIs(fixture, 'My value 2') // Set again to null to be sure content has been destroyed setFixtureSignalInputs(fixture, { content: () => null, context: {}, }) expect((fixture.nativeElement as HTMLElement).matches(':empty')).toBe(true) }) test('should render TemplateRef', () => { @Component({ template: ` {{ context.property }} `, standalone: true, }) class FakeTemplateRefComponent { @ViewChild('template', { static: true }) templateRef!: TemplateRef } const templateRef = TestBed.createComponent(FakeTemplateRefComponent) .componentInstance.templateRef const fixture = TestBed.createComponent(TestRenderComponent) setFixtureSignalInputs(fixture, { content: () => templateRef, context: { property: 'Property context value', }, }) expect(fixture.nativeElement.textContent).toEqual('Property context value') setFixtureSignalInput(fixture, 'context', { property: 'Updated value' }) fixture.detectChanges() expect(fixture.nativeElement.textContent).toEqual('Updated value') }) test('should render components', () => { @Component({ template: `{{ context.property }}`, standalone: true, }) class FakeComponent { context = injectFlexRenderContext<{ property: string }>() } const fixture = TestBed.createComponent(TestRenderComponent) setFixtureSignalInputs( fixture, { content: () => flexRenderComponent(FakeComponent), context: { property: 'Context value', }, }, { detectChanges: true }, ) expect(fixture.nativeElement.textContent).toEqual('Context value') setFixtureSignalInput(fixture, 'context', { property: 'Updated value' }) fixture.detectChanges() expect(fixture.nativeElement.textContent).toEqual('Updated value') }) // Skip for now, test framework (using ComponentRef.setInput) cannot recognize signal inputs // as component inputs test('should render custom components', async () => { @Component({ template: `{{ row().property }}`, standalone: true, }) class FakeComponent { row = input.required<{ property: string }>() constructor() {} } const fixture = TestBed.createComponent(TestRenderComponent) setFixtureSignalInputs(fixture, { content: () => FakeComponent, context: { row: { property: 'Row value', }, }, }) expect(fixture.nativeElement.textContent).toEqual('Row value') setFixtureSignalInput(fixture, 'context', { row: { property: 'Updated value' }, }) await fixture.whenRenderingDone() fixture.detectChanges() expect(fixture.nativeElement.textContent).toEqual('Updated value') }) }) @Component({ selector: 'app-test-render', template: ` `, standalone: true, imports: [FlexRender], }) class TestRenderComponent { readonly content = input.required() readonly context = input.required>() } type FlexRenderAllowedContent = ReturnType< FlexRenderDirective< any, any, NonNullable, NonNullable >['content'] > function expectPrimitiveValueIs( fixture: ComponentFixture, value: unknown, ) { expect(fixture.nativeElement.matches(':empty')).toBe(false) const span = fixture.nativeElement.querySelector('span') expect(span).toBeDefined() expect(span.innerHTML).toEqual(value) } ================================================ FILE: packages/angular-table/tests/injectTable.test.ts ================================================ import { isProxy } from 'node:util/types' import { describe, expect, test, vi } from 'vitest' import { ChangeDetectionStrategy, Component, effect, input, signal, } from '@angular/core' import { TestBed } from '@angular/core/testing' import { ColumnDef, createPaginatedRowModel, stockFeatures, } from '@tanstack/table-core' import { RowModel, injectTable } from '../src' import type { PaginationState } from '../src' describe('injectTable', () => { test('should support required signal inputs', () => { @Component({ selector: 'app-table', template: ``, standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, }) class TableComponent { data = input.required>() table = injectTable(() => ({ data: this.data(), _features: stockFeatures, columns: [], })) } @Component({ selector: 'app-root', imports: [TableComponent], template: ` `, changeDetection: ChangeDetectionStrategy.OnPush, }) class RootComponent {} const fixture = TestBed.createComponent(RootComponent) fixture.detectChanges() fixture.whenRenderingDone() }) describe('Proxy table', () => { type Data = { id: string; title: string } const data = signal>([{ id: '1', title: 'Title' }]) const columns: Array> = [ { id: 'id', header: 'Id', cell: (context) => context.getValue() }, { id: 'title', header: 'Title', cell: (context) => context.getValue() }, ] const table = TestBed.runInInjectionContext(() => injectTable(() => ({ data: data(), _features: stockFeatures, columns: columns, getRowId: (row) => row.id, })), ) test('table is proxy', () => { expect(isProxy(table)).toBe(true) }) test('supports "in" operator', () => { expect('_features' in table).toBe(true) expect('options' in table).toBe(true) expect('notFound' in table).toBe(false) }) test('supports "Object.keys"', () => { const keys = Object.keys(table) expect(keys.some((k) => ['state', 'getRowModel'].includes(k))) }) test('Row model is reactive', () => { const coreRowModelFn = vi.fn<(model: RowModel) => void>() const rowModelFn = vi.fn<(model: RowModel) => void>() const pagination = signal({ pageSize: 5, pageIndex: 0, }) const data = Array.from({ length: 10 }, (_, i) => ({ id: String(i), title: `Title ${i}`, })) TestBed.runInInjectionContext(() => { const table = injectTable(() => ({ data, columns: columns, _features: stockFeatures, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, getRowId: (row) => row.id, state: { pagination: pagination(), }, onPaginationChange: (updater) => { typeof updater === 'function' ? pagination.update(updater) : pagination.set(updater) }, })) effect(() => coreRowModelFn(table.getCoreRowModel())) effect(() => rowModelFn(table.getRowModel())) TestBed.tick() pagination.set({ pageIndex: 0, pageSize: 3 }) TestBed.tick() expect(coreRowModelFn).toHaveBeenCalledOnce() expect(coreRowModelFn.mock.calls[0]![0].rows.length).toEqual(10) expect(rowModelFn).toHaveBeenCalledTimes(2) expect(rowModelFn.mock.calls[0]![0].rows.length).toEqual(5) expect(rowModelFn.mock.calls[1]![0].rows.length).toEqual(3) }) }) }) }) ================================================ FILE: packages/angular-table/tests/lazy-init.test.ts ================================================ import { describe, expect, test, vi } from 'vitest' import { ChangeDetectionStrategy, Component, computed, effect, input, signal, } from '@angular/core' import { TestBed } from '@angular/core/testing' import { lazyInit } from '../src/lazySignalInitializer' import { flushQueue, setFixtureSignalInputs } from './test-utils' import type { WritableSignal } from '@angular/core' describe('lazyInit', () => { test('should init lazily in next tick when not accessing manually', async () => { const mockFn = vi.fn() TestBed.runInInjectionContext(() => { lazyInit(() => { mockFn() return { data: signal(true), } }) }) expect(mockFn).not.toHaveBeenCalled() await new Promise(setImmediate) expect(mockFn).toHaveBeenCalled() }) test('should init eagerly accessing manually', () => { const mockFn = vi.fn() TestBed.runInInjectionContext(() => { const lazySignal = lazyInit(() => { mockFn() return { data: signal(true), } }) lazySignal.data() }) expect(mockFn).toHaveBeenCalled() }) test('should init lazily and only once', async () => { const initCallFn = vi.fn() const registerDataValue = vi.fn<(arg0: number) => void>() let value!: { data: WritableSignal } const outerSignal = signal(0) TestBed.runInInjectionContext(() => { value = lazyInit(() => { initCallFn() void outerSignal() return { data: signal(0) } }) effect(() => registerDataValue(value.data())) }) value.data() TestBed.flushEffects() expect(outerSignal).toBeDefined() expect(initCallFn).toHaveBeenCalledTimes(1) outerSignal.set(1) await flushQueue() outerSignal.set(2) await flushQueue() value.data.set(4) await flushQueue() expect(initCallFn).toHaveBeenCalledTimes(1) expect(registerDataValue).toHaveBeenCalledTimes(1) }) test('should support required signal input', async () => { @Component({ standalone: true, template: `{{ call }} - {{ lazySignal.data() }}`, changeDetection: ChangeDetectionStrategy.OnPush, }) class Test { readonly title = input.required() call = 0 lazySignal = lazyInit(() => { this.call++ return { data: computed(() => this.title()), } }) } const fixture = TestBed.createComponent(Test) setFixtureSignalInputs(fixture, { title: 'newValue' }) expect(fixture.debugElement.nativeElement.textContent).toBe('0 - newValue') await flushQueue() setFixtureSignalInputs(fixture, { title: 'updatedValue' }) expect(fixture.debugElement.nativeElement.textContent).toBe( '1 - updatedValue', ) setFixtureSignalInputs(fixture, { title: 'newUpdatedValue' }) expect(fixture.debugElement.nativeElement.textContent).toBe( '1 - newUpdatedValue', ) }) }) ================================================ FILE: packages/angular-table/tests/test-setup.ts ================================================ import '@analogjs/vitest-angular/setup-snapshots' import '@testing-library/jest-dom/vitest' import { setupTestBed } from '@analogjs/vitest-angular/setup-testbed' setupTestBed() ================================================ FILE: packages/angular-table/tests/test-utils.ts ================================================ import type { InputSignal } from '@angular/core' import type { ComponentFixture } from '@angular/core/testing' type ToSignalInputUpdatableMap = { [K in keyof T as T[K] extends InputSignal ? K : never]?: T[K] extends infer Input ? Input extends InputSignal ? T : never : never } export function setFixtureSignalInputs>( componentFixture: ComponentFixture, inputs: ToSignalInputUpdatableMap, options: { detectChanges: boolean } = { detectChanges: true }, ) { for (const inputKey in inputs) { componentFixture.componentRef.setInput(inputKey, inputs[inputKey]) } if (options.detectChanges) { componentFixture.detectChanges() } } export function setFixtureSignalInput< T extends NonNullable, InputMaps extends ToSignalInputUpdatableMap, InputName extends keyof InputMaps, >( componentFixture: ComponentFixture, inputName: InputName, value: InputMaps[InputName], ) { setFixtureSignalInputs(componentFixture, { [inputName]: value, } as ToSignalInputUpdatableMap) } export async function flushQueue() { await new Promise(setImmediate) } ================================================ FILE: packages/angular-table/tsconfig.build.json ================================================ { "extends": "./node_modules/ng-packagr/src/lib/ts/conf/tsconfig.ngc.json", "compilerOptions": { "allowJs": true, "module": "ESNext", "moduleDetection": "force", "moduleResolution": "Bundler", "stripInternal": true }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true, "compilationMode": "partial" }, "include": ["src"] } ================================================ FILE: packages/angular-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "useDefineForClassFields": false, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true }, "include": ["src", "tests", "eslint.config.js", "vite.config.ts"] } ================================================ FILE: packages/angular-table/tsconfig.test.json ================================================ { "compilerOptions": { "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "esModuleInterop": true, "sourceMap": true, "declaration": false, "downlevelIteration": true, "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, "target": "ES2022", "module": "ES2022", "useDefineForClassFields": false, "lib": ["ES2022", "dom"], "types": ["vitest/globals", "node"] }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, "strictTemplates": true }, "include": ["src", "tests"] } ================================================ FILE: packages/angular-table/vite.config.ts ================================================ import * as path from 'node:path' import { defineConfig } from 'vitest/config' import angular from '@analogjs/vite-plugin-angular' import packageJson from './package.json' const tsconfigPath = path.join(import.meta.dirname, 'tsconfig.test.json') const testDirPath = path.join(import.meta.dirname, 'tests') const angularPlugin = angular({ tsconfig: tsconfigPath, jit: true }) export default defineConfig({ plugins: [angularPlugin], test: { name: packageJson.name, watch: false, dir: testDirPath, pool: 'threads', environment: 'jsdom', setupFiles: [path.join(testDirPath, 'test-setup.ts')], globals: true, reporters: 'default', disableConsoleIntercept: true, }, }) ================================================ FILE: packages/lit-table/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' export default [ ...rootConfig, { rules: {}, }, ] ================================================ FILE: packages/lit-table/package.json ================================================ { "name": "@tanstack/lit-table", "version": "9.0.0-alpha.10", "description": "Headless UI for building powerful tables & datagrids for Lit.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/lit-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "lit", "table", "lit-table", "datagrid" ], "type": "module", "types": "dist/esm/index.d.ts", "main": "dist/esm/index.js", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "dependencies": { "@tanstack/table-core": "workspace:*" }, "devDependencies": { "lit": "^3.3.2" }, "peerDependencies": { "lit": "^3.1.3" } } ================================================ FILE: packages/lit-table/src/TableController.ts ================================================ import { constructTable, coreFeatures } from '@tanstack/table-core' import type { RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { ReactiveController, ReactiveControllerHost } from 'lit' export class TableController< TFeatures extends TableFeatures, TData extends RowData, > implements ReactiveController { host: ReactiveControllerHost private _table: Table | null = null private _subscription?: () => void private _allState: TableState | null = null constructor(host: ReactiveControllerHost) { ;(this.host = host).addController(this) } public table( tableOptions: TableOptions, selector: (state: TableState) => any = () => ({}), ): Table & { state: any } { if (!this._table) { const _features = { ...coreFeatures, ...tableOptions._features } const statefulOptions: TableOptions = { ...tableOptions, _features, // Remove state and onStateChange - store handles it internally mergeOptions: ( defaultOptions: TableOptions, newOptions: Partial>, ) => { return { ...defaultOptions, ...newOptions, } }, } this._table = constructTable(statefulOptions) this._allState = this._table.store.state // Wrap all "get*" methods to make them reactive Object.keys(this._table).forEach((key) => { const value = (this._table as any)[key] if (typeof value === 'function' && key.startsWith('get')) { const originalMethod = value.bind(this._table) ;(this._table as any)[key] = (...args: Array) => { // Access state to create reactive dependency this._allState return originalMethod(...args) } } }) // Set up subscription immediately when table is created // This ensures reactivity works even if hostConnected() was called before table creation this._setupSubscription() // Add Subscribe function // For Lit, this could be used with a directive or component // This is a basic implementation that can be enhanced ;(this._table as any).Subscribe = function Subscribe(props: { selector: (state: TableState) => TSelected children: ((state: Readonly) => any) | any }) { // This is a simplified version - in practice, you'd want to use // a Lit directive or component to handle the subscription and rendering const selectedState = props.selector(this.store.state) if (typeof props.children === 'function') { return props.children(selectedState) } return props.children } } // Update options when they change this._table.setOptions((prev) => ({ ...prev, ...tableOptions, })) // Capture selector and table for the state getter const selectorFn = selector const tableInstance = this._table return { ...this._table, get state() { return selectorFn(tableInstance.store.state) }, } as Table & { state: any } } private _setupSubscription() { // Only set up if not already subscribed if (this._table && !this._subscription) { this._subscription = this._table.store.subscribe(({ currentVal }) => { this._allState = currentVal // Request update to trigger re-render this.host.requestUpdate() }) } } hostConnected() { // Set up subscription if table exists but subscription wasn't set up yet // (This handles the case where hostConnected() is called before table creation) this._setupSubscription() } hostDisconnected() { this._subscription?.() this._subscription = undefined } } ================================================ FILE: packages/lit-table/src/flexRender.ts ================================================ import type { TemplateResult } from 'lit' export function flexRender( Comp: ((props: TProps) => string) | string | TemplateResult | undefined, props: TProps, ): TemplateResult | string | null { if (!Comp) return null if (typeof Comp === 'function') { return Comp(props) } return Comp } ================================================ FILE: packages/lit-table/src/index.ts ================================================ export * from '@tanstack/table-core' export * from './flexRender' export * from './TableController' ================================================ FILE: packages/lit-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "include": ["src", "eslint.config.js", "vite.config.ts"] } ================================================ FILE: packages/lit-table/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' const config = defineConfig({}) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: './src/index.ts', srcDir: './src', }), ) ================================================ FILE: packages/match-sorter-utils/package.json ================================================ { "name": "@tanstack/match-sorter-utils", "version": "9.0.0-alpha.4", "description": "A fork of match-sorter with separated filtering and sorting phases", "contributors": [ "Kent C. Dodds", "Tanner Linsley" ], "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/match-sorter-utils" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "react", "table", "match-sorter", "utils", "split", "separate", "datagrid" ], "type": "module", "types": "dist/esm/index.d.ts", "main": "dist/esm/index.js", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:lib": "vitest", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "dependencies": { "remove-accents": "0.5.0" } } ================================================ FILE: packages/match-sorter-utils/src/index.ts ================================================ /** * @name match-sorter * @license MIT license. * @copyright (c) 2099 Kent C. Dodds * @author Kent C. Dodds (https://kentcdodds.com) */ // This is a fork of match-sorter. Instead of offering // a unified API for filtering and sorting in a single pass, // match-sorter-utils provides the lower-level utilities of // ranking items and comparing ranks in a way that can // be incrementally applied to a system rather than // all-at-once. // 1. Use the rankItem function to rank an item // 2. Use the resulting rankingInfo.passed to filter // 3. Use the resulting rankingInfo.rank to sort // For bundling purposes (mainly remove-accents not being esm safe/ready), // we've also hard-coded remove-accents into this source. // The remove-accents package is still included as a dependency // for attribution purposes, but it will not be imported and bundled. import { removeAccents } from './remove-accents' export type AccessorAttributes = { threshold?: Ranking maxRanking: Ranking minRanking: Ranking } export interface RankingInfo { rankedValue: any rank: Ranking accessorIndex: number accessorThreshold: Ranking | undefined passed: boolean } export interface AccessorOptions { accessor: AccessorFn threshold?: Ranking maxRanking?: Ranking minRanking?: Ranking } export type AccessorFn = (item: TItem) => string | Array export type Accessor = AccessorFn | AccessorOptions export interface RankItemOptions { accessors?: ReadonlyArray> threshold?: Ranking keepDiacritics?: boolean } export const rankings = { CASE_SENSITIVE_EQUAL: 7, EQUAL: 6, STARTS_WITH: 5, WORD_STARTS_WITH: 4, CONTAINS: 3, ACRONYM: 2, MATCHES: 1, NO_MATCH: 0, } as const export type Ranking = (typeof rankings)[keyof typeof rankings] /** * Gets the highest ranking for value for the given item based on its values for the given keys * @param {*} item - the item to rank * @param {String} value - the value to rank against * @param {Object} options - options to control the ranking * @return {{rank: Number, accessorIndex: Number, accessorThreshold: Number}} - the highest ranking */ export function rankItem( item: TItem, value: string, options?: RankItemOptions, ): RankingInfo { options = options || {} options.threshold = options.threshold ?? rankings.MATCHES if (!options.accessors) { // if keys is not specified, then we assume the item given is ready to be matched const rank = getMatchRanking(item as unknown as string, value, options) return { // ends up being duplicate of 'item' in matches but consistent rankedValue: item, rank, accessorIndex: -1, accessorThreshold: options.threshold, passed: rank >= options.threshold, } } const valuesToRank = getAllValuesToRank(item, options.accessors) const rankingInfo: RankingInfo = { rankedValue: item, rank: rankings.NO_MATCH as Ranking, accessorIndex: -1, accessorThreshold: options.threshold, passed: false, } for (let i = 0; i < valuesToRank.length; i++) { const rankValue = valuesToRank[i]! let newRank = getMatchRanking(rankValue.itemValue, value, options) const { minRanking, maxRanking, threshold = options.threshold, } = rankValue.attributes if (newRank < minRanking && newRank >= rankings.MATCHES) { newRank = minRanking } else if (newRank > maxRanking) { newRank = maxRanking } newRank = Math.min(newRank, maxRanking) as Ranking if (newRank >= threshold && newRank > rankingInfo.rank) { rankingInfo.rank = newRank rankingInfo.passed = true rankingInfo.accessorIndex = i rankingInfo.accessorThreshold = threshold rankingInfo.rankedValue = rankValue.itemValue } } return rankingInfo } /** * Gives a rankings score based on how well the two strings match. * @param {String} testString - the string to test against * @param {String} stringToRank - the string to rank * @param {Object} options - options for the match (like keepDiacritics for comparison) * @returns {Number} the ranking for how well stringToRank matches testString */ function getMatchRanking( testString: string, stringToRank: string, options: RankItemOptions, ): Ranking { testString = prepareValueForComparison(testString, options) stringToRank = prepareValueForComparison(stringToRank, options) // too long if (stringToRank.length > testString.length) { return rankings.NO_MATCH } // case sensitive equals if (testString === stringToRank) { return rankings.CASE_SENSITIVE_EQUAL } // Lower casing before further comparison testString = testString.toLowerCase() stringToRank = stringToRank.toLowerCase() // case insensitive equals if (testString === stringToRank) { return rankings.EQUAL } // starts with if (testString.startsWith(stringToRank)) { return rankings.STARTS_WITH } // word starts with if (testString.includes(` ${stringToRank}`)) { return rankings.WORD_STARTS_WITH } // contains if (testString.includes(stringToRank)) { return rankings.CONTAINS } else if (stringToRank.length === 1) { // If the only character in the given stringToRank // isn't even contained in the testString, then // it's definitely not a match. return rankings.NO_MATCH } // acronym if (getAcronym(testString).includes(stringToRank)) { return rankings.ACRONYM } // will return a number between rankings.MATCHES and // rankings.MATCHES + 1 depending on how close of a match it is. return getClosenessRanking(testString, stringToRank) } /** * Generates an acronym for a string. * * @param {String} string the string for which to produce the acronym * @returns {String} the acronym */ function getAcronym(string: string): string { let acronym = '' const wordsInString = string.split(' ') wordsInString.forEach((wordInString) => { const splitByHyphenWords = wordInString.split('-') splitByHyphenWords.forEach((splitByHyphenWord) => { acronym += splitByHyphenWord.substr(0, 1) }) }) return acronym } /** * Returns a score based on how spread apart the * characters from the stringToRank are within the testString. * A number close to rankings.MATCHES represents a loose match. A number close * to rankings.MATCHES + 1 represents a tighter match. * @param {String} testString - the string to test against * @param {String} stringToRank - the string to rank * @returns {Number} the number between rankings.MATCHES and * rankings.MATCHES + 1 for how well stringToRank matches testString */ function getClosenessRanking( testString: string, stringToRank: string, ): Ranking { let matchingInOrderCharCount = 0 let charNumber = 0 function findMatchingCharacter( matchChar: undefined | string, string: string, index: number, ) { for (let j = index, J = string.length; j < J; j++) { const stringChar = string[j] if (stringChar === matchChar) { matchingInOrderCharCount += 1 return j + 1 } } return -1 } function getRanking(spread: number) { const spreadPercentage = 1 / spread const inOrderPercentage = matchingInOrderCharCount / stringToRank.length const ranking = rankings.MATCHES + inOrderPercentage * spreadPercentage return ranking as Ranking } const firstIndex = findMatchingCharacter(stringToRank[0], testString, 0) if (firstIndex < 0) { return rankings.NO_MATCH } charNumber = firstIndex for (let i = 1, I = stringToRank.length; i < I; i++) { const matchChar = stringToRank[i] charNumber = findMatchingCharacter(matchChar, testString, charNumber) const found = charNumber > -1 if (!found) { return rankings.NO_MATCH } } const spread = charNumber - firstIndex return getRanking(spread) } /** * Sorts items that have a rank, index, and accessorIndex * @param {Object} a - the first item to sort * @param {Object} b - the second item to sort * @return {Number} -1 if a should come first, 1 if b should come first, 0 if equal */ export function compareItems(a: RankingInfo, b: RankingInfo): number { return a.rank === b.rank ? 0 : a.rank > b.rank ? -1 : 1 } /** * Prepares value for comparison by stringifying it, removing diacritics (if specified) * @param {String} value - the value to clean * @param {Object} options - {keepDiacritics: whether to remove diacritics} * @return {String} the prepared value */ function prepareValueForComparison( value: string, { keepDiacritics }: RankItemOptions, ): string { // value might not actually be a string at this point (we don't get to choose) // so part of preparing the value for comparison is ensure that it is a string value = `${value}` // toString if (!keepDiacritics) { value = removeAccents(value) } return value } /** * Gets value for key in item at arbitrarily nested keypath * @param {Object} item - the item * @param {Object|Function} key - the potentially nested keypath or property callback * @return {Array} - an array containing the value(s) at the nested keypath */ function getItemValues( item: TItem, accessor: Accessor, ): Array { let accessorFn = accessor as AccessorFn if (typeof accessor === 'object') { accessorFn = accessor.accessor } const value = accessorFn(item) // because `value` can also be undefined if (value == null) { return [] } if (Array.isArray(value)) { return value } return [String(value)] } /** * Gets all the values for the given keys in the given item and returns an array of those values * @param item - the item from which the values will be retrieved * @param keys - the keys to use to retrieve the values * @return objects with {itemValue, attributes} */ function getAllValuesToRank( item: TItem, accessors: ReadonlyArray>, ) { const allValues: Array<{ itemValue: string attributes: AccessorAttributes }> = [] for (let j = 0, J = accessors.length; j < J; j++) { const accessor = accessors[j]! const attributes = getAccessorAttributes(accessor) const itemValues = getItemValues(item, accessor) for (let i = 0, I = itemValues.length; i < I; i++) { allValues.push({ itemValue: itemValues[i]!, attributes, }) } } return allValues } const defaultKeyAttributes = { maxRanking: Infinity as Ranking, minRanking: -Infinity as Ranking, } /** * Gets all the attributes for the given accessor * @param accessor - the accessor from which the attributes will be retrieved * @return object containing the accessor's attributes */ function getAccessorAttributes( accessor: Accessor, ): AccessorAttributes { if (typeof accessor === 'function') { return defaultKeyAttributes } return { ...defaultKeyAttributes, ...accessor } } ================================================ FILE: packages/match-sorter-utils/src/remove-accents.ts ================================================ const characterMap: Record = { À: 'A', Á: 'A', Â: 'A', Ã: 'A', Ä: 'A', Å: 'A', Ấ: 'A', Ắ: 'A', Ẳ: 'A', Ẵ: 'A', Ặ: 'A', Æ: 'AE', Ầ: 'A', Ằ: 'A', Ȃ: 'A', Ç: 'C', Ḉ: 'C', È: 'E', É: 'E', Ê: 'E', Ë: 'E', Ế: 'E', Ḗ: 'E', Ề: 'E', Ḕ: 'E', Ḝ: 'E', Ȇ: 'E', Ì: 'I', Í: 'I', Î: 'I', Ï: 'I', Ḯ: 'I', Ȋ: 'I', Ð: 'D', Ñ: 'N', Ò: 'O', Ó: 'O', Ô: 'O', Õ: 'O', Ö: 'O', Ø: 'O', Ố: 'O', Ṍ: 'O', Ṓ: 'O', Ȏ: 'O', Ù: 'U', Ú: 'U', Û: 'U', Ü: 'U', Ý: 'Y', à: 'a', á: 'a', â: 'a', ã: 'a', ä: 'a', å: 'a', ấ: 'a', ắ: 'a', ẳ: 'a', ẵ: 'a', ặ: 'a', æ: 'ae', ầ: 'a', ằ: 'a', ȃ: 'a', ç: 'c', ḉ: 'c', è: 'e', é: 'e', ê: 'e', ë: 'e', ế: 'e', ḗ: 'e', ề: 'e', ḕ: 'e', ḝ: 'e', ȇ: 'e', ì: 'i', í: 'i', î: 'i', ï: 'i', ḯ: 'i', ȋ: 'i', ð: 'd', ñ: 'n', ò: 'o', ó: 'o', ô: 'o', õ: 'o', ö: 'o', ø: 'o', ố: 'o', ṍ: 'o', ṓ: 'o', ȏ: 'o', ù: 'u', ú: 'u', û: 'u', ü: 'u', ý: 'y', ÿ: 'y', Ā: 'A', ā: 'a', Ă: 'A', ă: 'a', Ą: 'A', ą: 'a', Ć: 'C', ć: 'c', Ĉ: 'C', ĉ: 'c', Ċ: 'C', ċ: 'c', Č: 'C', č: 'c', C̆: 'C', c̆: 'c', Ď: 'D', ď: 'd', Đ: 'D', đ: 'd', Ē: 'E', ē: 'e', Ĕ: 'E', ĕ: 'e', Ė: 'E', ė: 'e', Ę: 'E', ę: 'e', Ě: 'E', ě: 'e', Ĝ: 'G', Ǵ: 'G', ĝ: 'g', ǵ: 'g', Ğ: 'G', ğ: 'g', Ġ: 'G', ġ: 'g', Ģ: 'G', ģ: 'g', Ĥ: 'H', ĥ: 'h', Ħ: 'H', ħ: 'h', Ḫ: 'H', ḫ: 'h', Ĩ: 'I', ĩ: 'i', Ī: 'I', ī: 'i', Ĭ: 'I', ĭ: 'i', Į: 'I', į: 'i', İ: 'I', ı: 'i', IJ: 'IJ', ij: 'ij', Ĵ: 'J', ĵ: 'j', Ķ: 'K', ķ: 'k', Ḱ: 'K', ḱ: 'k', K̆: 'K', k̆: 'k', Ĺ: 'L', ĺ: 'l', Ļ: 'L', ļ: 'l', Ľ: 'L', ľ: 'l', Ŀ: 'L', ŀ: 'l', Ł: 'l', ł: 'l', Ḿ: 'M', ḿ: 'm', M̆: 'M', m̆: 'm', Ń: 'N', ń: 'n', Ņ: 'N', ņ: 'n', Ň: 'N', ň: 'n', ʼn: 'n', N̆: 'N', n̆: 'n', Ō: 'O', ō: 'o', Ŏ: 'O', ŏ: 'o', Ő: 'O', ő: 'o', Œ: 'OE', œ: 'oe', P̆: 'P', p̆: 'p', Ŕ: 'R', ŕ: 'r', Ŗ: 'R', ŗ: 'r', Ř: 'R', ř: 'r', R̆: 'R', r̆: 'r', Ȓ: 'R', ȓ: 'r', Ś: 'S', ś: 's', Ŝ: 'S', ŝ: 's', Ş: 'S', Ș: 'S', ș: 's', ş: 's', Š: 'S', š: 's', Ţ: 'T', ţ: 't', ț: 't', Ț: 'T', Ť: 'T', ť: 't', Ŧ: 'T', ŧ: 't', T̆: 'T', t̆: 't', Ũ: 'U', ũ: 'u', Ū: 'U', ū: 'u', Ŭ: 'U', ŭ: 'u', Ů: 'U', ů: 'u', Ű: 'U', ű: 'u', Ų: 'U', ų: 'u', Ȗ: 'U', ȗ: 'u', V̆: 'V', v̆: 'v', Ŵ: 'W', ŵ: 'w', Ẃ: 'W', ẃ: 'w', X̆: 'X', x̆: 'x', Ŷ: 'Y', ŷ: 'y', Ÿ: 'Y', Y̆: 'Y', y̆: 'y', Ź: 'Z', ź: 'z', Ż: 'Z', ż: 'z', Ž: 'Z', ž: 'z', ſ: 's', ƒ: 'f', Ơ: 'O', ơ: 'o', Ư: 'U', ư: 'u', Ǎ: 'A', ǎ: 'a', Ǐ: 'I', ǐ: 'i', Ǒ: 'O', ǒ: 'o', Ǔ: 'U', ǔ: 'u', Ǖ: 'U', ǖ: 'u', Ǘ: 'U', ǘ: 'u', Ǚ: 'U', ǚ: 'u', Ǜ: 'U', ǜ: 'u', Ứ: 'U', ứ: 'u', Ṹ: 'U', ṹ: 'u', Ǻ: 'A', ǻ: 'a', Ǽ: 'AE', ǽ: 'ae', Ǿ: 'O', ǿ: 'o', Þ: 'TH', þ: 'th', Ṕ: 'P', ṕ: 'p', Ṥ: 'S', ṥ: 's', X́: 'X', x́: 'x', Ѓ: 'Г', ѓ: 'г', Ќ: 'К', ќ: 'к', A̋: 'A', a̋: 'a', E̋: 'E', e̋: 'e', I̋: 'I', i̋: 'i', Ǹ: 'N', ǹ: 'n', Ồ: 'O', ồ: 'o', Ṑ: 'O', ṑ: 'o', Ừ: 'U', ừ: 'u', Ẁ: 'W', ẁ: 'w', Ỳ: 'Y', ỳ: 'y', Ȁ: 'A', ȁ: 'a', Ȅ: 'E', ȅ: 'e', Ȉ: 'I', ȉ: 'i', Ȍ: 'O', ȍ: 'o', Ȑ: 'R', ȑ: 'r', Ȕ: 'U', ȕ: 'u', B̌: 'B', b̌: 'b', Č̣: 'C', č̣: 'c', Ê̌: 'E', ê̌: 'e', F̌: 'F', f̌: 'f', Ǧ: 'G', ǧ: 'g', Ȟ: 'H', ȟ: 'h', J̌: 'J', ǰ: 'j', Ǩ: 'K', ǩ: 'k', M̌: 'M', m̌: 'm', P̌: 'P', p̌: 'p', Q̌: 'Q', q̌: 'q', Ř̩: 'R', ř̩: 'r', Ṧ: 'S', ṧ: 's', V̌: 'V', v̌: 'v', W̌: 'W', w̌: 'w', X̌: 'X', x̌: 'x', Y̌: 'Y', y̌: 'y', A̧: 'A', a̧: 'a', B̧: 'B', b̧: 'b', Ḑ: 'D', ḑ: 'd', Ȩ: 'E', ȩ: 'e', Ɛ̧: 'E', ɛ̧: 'e', Ḩ: 'H', ḩ: 'h', I̧: 'I', i̧: 'i', Ɨ̧: 'I', ɨ̧: 'i', M̧: 'M', m̧: 'm', O̧: 'O', o̧: 'o', Q̧: 'Q', q̧: 'q', U̧: 'U', u̧: 'u', X̧: 'X', x̧: 'x', Z̧: 'Z', z̧: 'z', } const chars = Object.keys(characterMap).join('|') const allAccents = new RegExp(chars, 'g') export function removeAccents(str: string) { return str.replace(allAccents, (match) => { return characterMap[match]! }) } ================================================ FILE: packages/match-sorter-utils/tests/match-sorter-utils.test.ts ================================================ import { describe, expect, it } from 'vitest' import { rankings, rankItem } from '../src' interface Person { firstName: string lastName: string email: string } const testPerson: Person = { firstName: 'John', lastName: 'Doe', email: 'j.doe@email.com', } describe('match-sorter-utils', () => { describe('rankItem', () => { describe('with accessorFn', () => { it('CASE_SENSITIVE_EQUAL', () => { const ranking = rankItem(testPerson, 'John', { accessors: [ (item) => item.firstName, (item) => item.lastName, (item) => item.email, ], }) expect(ranking.rank).toBe(rankings.CASE_SENSITIVE_EQUAL) expect(ranking.passed).toBe(true) expect(ranking.rankedValue).toBe(testPerson.firstName) expect(ranking.accessorIndex).toBe(0) expect(ranking.accessorThreshold).toBe(1) }) it('NO_MATCH', () => { const ranking = rankItem(testPerson, 'Tom', { accessors: [ (item) => item.firstName, (item) => item.lastName, (item) => item.email, ], }) expect(ranking.rank).toBe(rankings.NO_MATCH) expect(ranking.passed).toBe(false) expect(ranking.rankedValue).toBe(testPerson) expect(ranking.accessorIndex).toBe(-1) expect(ranking.accessorThreshold).toBe(1) }) }) describe('with accessorOptions and custom Threshold', () => { it('CASE_SENSITIVE_EQUAL', () => { const ranking = rankItem(testPerson, 'John', { accessors: [ { accessor: (item) => item.firstName, threshold: rankings.CONTAINS, }, { accessor: (item) => item.lastName, threshold: rankings.CONTAINS, }, { accessor: (item) => item.email, threshold: rankings.MATCHES, }, ], }) expect(ranking.rank).toBe(rankings.CASE_SENSITIVE_EQUAL) expect(ranking.passed).toBe(true) expect(ranking.rankedValue).toBe(testPerson.firstName) expect(ranking.accessorIndex).toBe(0) expect(ranking.accessorThreshold).toBe(rankings.CONTAINS) }) it('ACRONYM but threshold is CONTAINS', () => { const ranking = rankItem(testPerson, 'jd', { threshold: rankings.ACRONYM, accessors: [ { accessor: (item) => item.firstName, threshold: rankings.CONTAINS, }, { accessor: (item) => item.lastName, threshold: rankings.CONTAINS, }, { accessor: (item) => `${item.firstName} ${item.lastName}`, threshold: rankings.CONTAINS, }, { accessor: (item) => item.email, threshold: rankings.CONTAINS, }, ], }) expect(ranking.rank).toBe(rankings.NO_MATCH) expect(ranking.passed).toBe(false) expect(ranking.rankedValue).toBe(testPerson) expect(ranking.accessorIndex).toBe(-1) expect(ranking.accessorThreshold).toBe(rankings.ACRONYM) }) it('NO_MATCH', () => { const ranking = rankItem(testPerson, 'Tom', { accessors: [ { accessor: (item) => item.firstName, threshold: rankings.CONTAINS, }, { accessor: (item) => item.lastName, threshold: rankings.CONTAINS, }, { accessor: (item) => item.email, threshold: rankings.MATCHES, }, ], }) expect(ranking.rank).toBe(rankings.NO_MATCH) expect(ranking.passed).toBe(false) expect(ranking.rankedValue).toBe(testPerson) expect(ranking.accessorIndex).toBe(-1) expect(ranking.accessorThreshold).toBe(1) }) }) }) }) ================================================ FILE: packages/match-sorter-utils/tests/test-setup.ts ================================================ import '@testing-library/jest-dom/vitest' ================================================ FILE: packages/match-sorter-utils/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "include": ["src", "vite.config.ts", "tests"] } ================================================ FILE: packages/match-sorter-utils/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ test: { name: packageJson.name, dir: './tests', watch: false, environment: 'jsdom', setupFiles: ['./tests/test-setup.ts'], }, }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: './src/index.ts', srcDir: './src', }), ) ================================================ FILE: packages/preact-table/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [ ...rootConfig, { rules: {}, }, ] export default config ================================================ FILE: packages/preact-table/package.json ================================================ { "name": "@tanstack/preact-table", "version": "9.0.0-alpha.16", "description": "Headless UI for building powerful tables & datagrids for Preact.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/preact-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "preact", "table", "preact-table", "datagrid" ], "type": "module", "types": "dist/esm/index.d.ts", "main": "dist/esm/index.js", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:lib": "vitest --passWithNoTests", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "dependencies": { "@tanstack/preact-store": "^0.11.1", "@tanstack/table-core": "workspace:*" }, "devDependencies": { "@preact/preset-vite": "^2.10.3", "preact": "^10.28.2" }, "peerDependencies": { "preact": ">=10" } } ================================================ FILE: packages/preact-table/src/FlexRender.tsx ================================================ import type { Cell, CellData, Header, RowData, TableFeatures, } from '@tanstack/table-core' import type { ComponentChild, ComponentType } from 'preact' export type Renderable = ComponentChild | ComponentType function isPreactComponent( component: unknown, ): component is ComponentType { return ( isClassComponent(component) || typeof component === 'function' || isExoticComponent(component) ) } function isClassComponent(component: any) { return ( typeof component === 'function' && (() => { const proto = Object.getPrototypeOf(component) return proto.prototype && proto.prototype.isPreactComponent })() ) } function isExoticComponent(component: any) { return ( typeof component === 'object' && typeof component.$$typeof === 'symbol' && ['preact.memo', 'preact.forward_ref'].includes( component.$$typeof.description, ) ) } /** * If rendering headers, cells, or footers with custom markup, use flexRender instead of `cell.getValue()` or `cell.renderValue()`. * @example flexRender(cell.column.columnDef.cell, cell.getContext()) */ export function flexRender( Comp: Renderable | null, props: TProps, ): ComponentChild | Element | null { return !Comp ? null : isPreactComponent(Comp) ? ( ) : ( Comp ) } /** * Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. * Only one prop (`cell`, `header`, or `footer`) may be passed. * @example * @example * @example */ export type FlexRenderProps< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = | { cell: Cell; header?: never; footer?: never } | { header: Header cell?: never footer?: never } | { footer: Header cell?: never header?: never } /** * Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. * Only one prop (`cell`, `header`, or `footer`) may be passed. * @example * ```tsx * * * * ``` * * This replaces calling `flexRender` directly like this: * ```tsx * flexRender(cell.column.columnDef.cell, cell.getContext()) * flexRender(header.column.columnDef.header, header.getContext()) * flexRender(footer.column.columnDef.footer, footer.getContext()) * ``` */ export function FlexRender< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(props: FlexRenderProps) { if ('cell' in props && props.cell) { return flexRender(props.cell.column.columnDef.cell, props.cell.getContext()) } if ('header' in props && props.header) { return flexRender( props.header.column.columnDef.header, props.header.getContext(), ) } if ('footer' in props && props.footer) { return flexRender( props.footer.column.columnDef.footer, props.footer.getContext(), ) } return null } ================================================ FILE: packages/preact-table/src/Subscribe.ts ================================================ import { useStore } from '@tanstack/preact-store' import type { NoInfer, RowData, Table, TableFeatures, TableState, } from '@tanstack/table-core' import type { ComponentChildren } from 'preact' export type SubscribeProps< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = { /** * The table instance to subscribe to. Required when using as a standalone component. * Not needed when using as `table.Subscribe`. */ table: Table /** * A selector function that selects the part of the table state to subscribe to. * This allows for fine-grained reactivity by only re-rendering when the selected state changes. */ selector: (state: NoInfer>) => TSelected /** * The children to render. Can be a function that receives the selected state, or a Preact node. */ children: ((state: TSelected) => ComponentChildren) | ComponentChildren } /** * A Preact component that allows you to subscribe to the table state. * * This is useful for opting into state re-renders for specific parts of the table state. * * @example * ```tsx * // As a standalone component * ({ rowSelection: state.rowSelection })}> * {({ rowSelection }) => ( *
Selected rows: {Object.keys(rowSelection).length}
* )} *
* ``` * * @example * ```tsx * // As table.Subscribe (table instance method) * ({ rowSelection: state.rowSelection })}> * {({ rowSelection }) => ( *
Selected rows: {Object.keys(rowSelection).length}
* )} *
* ``` */ export function Subscribe< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >(props: SubscribeProps): ComponentChildren { const selected = useStore(props.table.store, props.selector) return typeof props.children === 'function' ? props.children(selected) : props.children } ================================================ FILE: packages/preact-table/src/createTableHook.tsx ================================================ 'use client' import { createContext } from 'preact' import { useContext, useMemo } from 'preact/hooks' import { createColumnHelper as coreCreateColumnHelper } from '@tanstack/table-core' import { useTable } from './useTable' import { FlexRender } from './FlexRender' import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, Cell, CellContext, CellData, Column, ColumnDef, DeepKeys, DeepValue, DisplayColumnDef, GroupColumnDef, Header, IdentifiedColumnDef, NoInfer, Row, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { ComponentChildren, ComponentType } from 'preact' import type { PreactTable } from './useTable' // ============================================================================= // Enhanced Context Types with Pre-bound Components // ============================================================================= /** * Enhanced CellContext with pre-bound cell components. * The `cell` property includes the registered cellComponents. */ export type AppCellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, > = { cell: Cell & TCellComponents & { FlexRender: () => ComponentChildren } column: Column getValue: CellContext['getValue'] renderValue: CellContext['renderValue'] row: Row table: Table } /** * Enhanced HeaderContext with pre-bound header components. * The `header` property includes the registered headerComponents. */ export type AppHeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, > = { column: Column header: Header & THeaderComponents & { FlexRender: () => ComponentChildren } table: Table } // ============================================================================= // Enhanced Column Definition Types // ============================================================================= /** * Template type for column definitions that can be a string or a function. */ type AppColumnDefTemplate = | string | ((props: TProps) => any) /** * Enhanced column definition base with pre-bound components in cell/header/footer contexts. */ type AppColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< IdentifiedColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced display column definition with pre-bound components. */ type AppDisplayColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< DisplayColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced group column definition with pre-bound components. */ type AppGroupColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< GroupColumnDef, 'cell' | 'header' | 'footer' | 'columns' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > columns?: Array> } // ============================================================================= // Enhanced Column Helper Type // ============================================================================= /** * Enhanced column helper with pre-bound components in cell/header/footer contexts. * This enables TypeScript to know about the registered components when defining columns. */ export type AppColumnHelper< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = { /** * Creates a data column definition with an accessor key or function. * The cell, header, and footer contexts include pre-bound components. */ accessor: < TAccessor extends AccessorFn | DeepKeys, TValue extends TAccessor extends AccessorFn ? TReturn : TAccessor extends DeepKeys ? DeepValue : never, >( accessor: TAccessor, column: TAccessor extends AccessorFn ? AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents > & { id: string } : AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents >, ) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef /** * Wraps an array of column definitions to preserve each column's individual TValue type. */ columns: >>( columns: [...TColumns], ) => Array> & [...TColumns] /** * Creates a display column definition for non-data columns. * The cell, header, and footer contexts include pre-bound components. */ display: ( column: AppDisplayColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => DisplayColumnDef /** * Creates a group column definition with nested child columns. * The cell, header, and footer contexts include pre-bound components. */ group: ( column: AppGroupColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => GroupColumnDef } // ============================================================================= // CreateTableHook Options and Props // ============================================================================= /** * Options for creating a table hook with pre-bound components and default table options. * Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. */ export type CreateTableHookOptions< TFeatures extends TableFeatures, TTableComponents extends Record>, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< TableOptions, 'columns' | 'data' | 'store' | 'state' | 'initialState' > & { /** * Table-level components that need access to the table instance. * These are available directly on the table object returned by useAppTable. * Use `useTableContext()` inside these components. * @example { PaginationControls, GlobalFilter, RowCount } */ tableComponents?: TTableComponents /** * Cell-level components that need access to the cell instance. * These are available on the cell object passed to AppCell's children. * Use `useCellContext()` inside these components. * @example { TextCell, NumberCell, DateCell, CurrencyCell } */ cellComponents?: TCellComponents /** * Header-level components that need access to the header instance. * These are available on the header object passed to AppHeader/AppFooter's children. * Use `useHeaderContext()` inside these components. * @example { SortIndicator, ColumnFilter, ResizeHandle } */ headerComponents?: THeaderComponents } /** * Props for AppTable component - without selector */ export interface AppTablePropsWithoutSelector { children: ComponentChildren selector?: never } /** * Props for AppTable component - with selector */ export interface AppTablePropsWithSelector< TFeatures extends TableFeatures, TSelected, > { children: (state: TSelected) => ComponentChildren selector: (state: TableState) => TSelected } /** * Props for AppCell component - without selector */ export interface AppCellPropsWithoutSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, > { cell: Cell children: ( cell: Cell & TCellComponents & { FlexRender: () => ComponentChildren }, ) => ComponentChildren selector?: never } /** * Props for AppCell component - with selector */ export interface AppCellPropsWithSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, TSelected, > { cell: Cell children: ( cell: Cell & TCellComponents & { FlexRender: () => ComponentChildren }, state: TSelected, ) => ComponentChildren selector: (state: TableState) => TSelected } /** * Props for AppHeader/AppFooter component - without selector */ export interface AppHeaderPropsWithoutSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, > { header: Header children: ( header: Header & THeaderComponents & { FlexRender: () => ComponentChildren }, ) => ComponentChildren selector?: never } /** * Props for AppHeader/AppFooter component - with selector */ export interface AppHeaderPropsWithSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, TSelected, > { header: Header children: ( header: Header & THeaderComponents & { FlexRender: () => ComponentChildren }, state: TSelected, ) => ComponentChildren selector: (state: TableState) => TSelected } /** * Component type for AppCell - wraps a cell and provides cell context with optional Subscribe */ export interface AppCellComponent< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, > { ( props: AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents >, ): ComponentChildren ( props: AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TSelected >, ): ComponentChildren } /** * Component type for AppHeader/AppFooter - wraps a header and provides header context with optional Subscribe */ export interface AppHeaderComponent< TFeatures extends TableFeatures, TData extends RowData, THeaderComponents extends Record>, > { ( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): ComponentChildren ( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TSelected >, ): ComponentChildren } /** * Component type for AppTable - root wrapper with optional Subscribe */ export interface AppTableComponent { (props: AppTablePropsWithoutSelector): ComponentChildren ( props: AppTablePropsWithSelector, ): ComponentChildren } /** * Extended table API returned by useAppTable with all App wrapper components */ export type AppPreactTable< TFeatures extends TableFeatures, TData extends RowData, TSelected, TTableComponents extends Record>, TCellComponents extends Record>, THeaderComponents extends Record>, > = PreactTable & NoInfer & { /** * Root wrapper component that provides table context with optional Subscribe. * @example * ```tsx * // Without selector - children is ComponentChildren * * ...
*
* * // With selector - children receives selected state * s.pagination}> * {(pagination) =>
Page {pagination.pageIndex}
} *
* ``` */ AppTable: AppTableComponent /** * Wraps a cell and provides cell context with pre-bound cellComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * // Without selector * * {(c) => } * * * // With selector - children receives cell and selected state * s.columnFilters}> * {(c, filters) => {filters.length}} * * ``` */ AppCell: AppCellComponent> /** * Wraps a header and provides header context with pre-bound headerComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * // Without selector * * {(h) => } * * * // With selector * s.sorting}> * {(h, sorting) => {sorting.length} sorted} * * ``` */ AppHeader: AppHeaderComponent> /** * Wraps a footer and provides header context with pre-bound headerComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * * {(f) => } * * ``` */ AppFooter: AppHeaderComponent> } /** * Creates a custom table hook with pre-bound components for composition. * * This is the table equivalent of TanStack Form's `createFormHook`. It allows you to: * - Define features, row models, and default options once, shared across all tables * - Register reusable table, cell, and header components * - Access table/cell/header instances via context in those components * - Get a `useAppTable` hook that returns an extended table with App wrapper components * - Get a `createAppColumnHelper` function pre-bound to your features * * @example * ```tsx * // hooks/table.ts * export const { * useAppTable, * createAppColumnHelper, * useTableContext, * useCellContext, * useHeaderContext, * } = createTableHook({ * _features: tableFeatures({ * rowPaginationFeature, * rowSortingFeature, * columnFilteringFeature, * }), * _rowModels: { * paginatedRowModel: createPaginatedRowModel(), * sortedRowModel: createSortedRowModel(sortFns), * filteredRowModel: createFilteredRowModel(filterFns), * }, * tableComponents: { PaginationControls, RowCount }, * cellComponents: { TextCell, NumberCell }, * headerComponents: { SortIndicator, ColumnFilter }, * }) * * // Create column helper with TFeatures already bound * const columnHelper = createAppColumnHelper() * * // components/table-components.tsx * function PaginationControls() { * const table = useTableContext() // TFeatures already known! * return s.pagination}>... * } * * // features/users.tsx * function UsersTable({ data }: { data: Person[] }) { * const table = useAppTable({ * columns, * data, // TData inferred from Person[] * }) * * return ( * * * * {table.getHeaderGroups().map(headerGroup => ( * * {headerGroup.headers.map(h => ( * * {(header) => ( * * )} * * ))} * * ))} * * * {table.getRowModel().rows.map(row => ( * * {row.getAllCells().map(c => ( * * {(cell) => } * * ))} * * ))} * *
* * *
* *
* ) * } * ``` */ export function createTableHook< TFeatures extends TableFeatures, const TTableComponents extends Record>, const TCellComponents extends Record>, const THeaderComponents extends Record>, >({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableHookOptions< TFeatures, TTableComponents, TCellComponents, THeaderComponents >) { // Create contexts internally with TFeatures baked in const TableContext = createContext>( null as never, ) const CellContext = createContext>(null as never) const HeaderContext = createContext>( null as never, ) /** * Create a column helper pre-bound to the features and components configured in this table hook. * The cell, header, and footer contexts include pre-bound components (e.g., `cell.TextCell`). * @example * ```tsx * const columnHelper = createAppColumnHelper() * * const columns = [ * columnHelper.accessor('firstName', { * header: 'First Name', * cell: ({ cell }) => , // cell has pre-bound components! * }), * columnHelper.accessor('age', { * header: 'Age', * cell: ({ cell }) => , * }), * ] * ``` */ function createAppColumnHelper(): AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > { // The runtime implementation is the same - components are attached at render time // This cast provides the enhanced types for column definitions return coreCreateColumnHelper() as AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > } /** * Access the table instance from within an `AppTable` wrapper. * Use this in custom `tableComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function PaginationControls() { * const table = useTableContext() * return ( * s.pagination}> * {(pagination) => ( *
* * Page {pagination.pageIndex + 1} * *
* )} *
* ) * } * ``` */ function useTableContext(): PreactTable< TFeatures, TData > { const table = useContext(TableContext) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!table) { throw new Error( '`useTableContext` must be used within an `AppTable` component. ' + 'Make sure your component is wrapped with `...`.', ) } return table as PreactTable } /** * Access the cell instance from within an `AppCell` wrapper. * Use this in custom `cellComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function TextCell() { * const cell = useCellContext() * return {cell.getValue()} * } * * function NumberCell({ format }: { format?: Intl.NumberFormatOptions }) { * const cell = useCellContext() * return {cell.getValue().toLocaleString(undefined, format)} * } * ``` */ function useCellContext() { const cell = useContext(CellContext) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!cell) { throw new Error( '`useCellContext` must be used within an `AppCell` component. ' + 'Make sure your component is wrapped with `...`.', ) } return cell as Cell } /** * Access the header instance from within an `AppHeader` or `AppFooter` wrapper. * Use this in custom `headerComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function SortIndicator() { * const header = useHeaderContext() * const sorted = header.column.getIsSorted() * return sorted === 'asc' ? '🔼' : sorted === 'desc' ? '🔽' : null * } * * function ColumnFilter() { * const header = useHeaderContext() * if (!header.column.getCanFilter()) return null * return ( * header.column.setFilterValue(e.target.value)} * placeholder="Filter..." * /> * ) * } * ``` */ function useHeaderContext() { const header = useContext(HeaderContext) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!header) { throw new Error( '`useHeaderContext` must be used within an `AppHeader` or `AppFooter` component.', ) } return header as Header } /** * Context-aware FlexRender component for cells. * Uses the cell from context, so no need to pass cell prop. */ function CellFlexRender() { const cell = useCellContext() return } /** * Context-aware FlexRender component for headers. * Uses the header from context, so no need to pass header prop. */ function HeaderFlexRender() { const header = useHeaderContext() return } /** * Context-aware FlexRender component for footers. * Uses the header from context, so no need to pass footer prop. */ function FooterFlexRender() { const header = useHeaderContext() return } /** * Enhanced useTable hook that returns a table with App wrapper components * and pre-bound tableComponents attached directly to the table object. * * Default options from createTableHook are automatically merged with * the options passed here. Options passed here take precedence. * * TFeatures is already known from the createTableHook call; TData is inferred from the data prop. */ function useAppTable( tableOptions: Omit< TableOptions, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ): AppPreactTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > { // Merge default options with provided options (provided takes precedence) const table = useTable( { ...defaultTableOptions, ...tableOptions } as TableOptions< TFeatures, TData >, selector, ) // AppTable - Root wrapper that provides table context with optional Subscribe const AppTable = useMemo(() => { function AppTableImpl( props: AppTablePropsWithoutSelector, ): ComponentChildren function AppTableImpl( props: AppTablePropsWithSelector, ): ComponentChildren function AppTableImpl( props: | AppTablePropsWithoutSelector | AppTablePropsWithSelector, ): ComponentChildren { const { children, selector: appTableSelector } = props as any return ( {appTableSelector ? ( {(state: TAppTableSelected) => (children as (state: TAppTableSelected) => ComponentChildren)( state, ) } ) : ( children )} ) } return AppTableImpl as AppTableComponent }, [table]) // AppCell - Wraps cell with context, pre-bound cellComponents, and optional Subscribe const AppCell = useMemo(() => { function AppCellImpl( props: AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents >, ): ComponentChildren function AppCellImpl< TValue extends CellData = CellData, TAppCellSelected = unknown, >( props: AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TAppCellSelected >, ): ComponentChildren function AppCellImpl< TValue extends CellData = CellData, TAppCellSelected = unknown, >( props: | AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents > | AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TAppCellSelected >, ): ComponentChildren { const { cell, children, selector: appCellSelector } = props as any const extendedCell = Object.assign(cell, { FlexRender: CellFlexRender, ...cellComponents, }) return ( {appCellSelector ? ( {(state: TAppCellSelected) => ( children as ( cell: Cell & TCellComponents & { FlexRender: () => ComponentChildren }, state: TAppCellSelected, ) => ComponentChildren )(extendedCell, state) } ) : ( ( children as ( cell: Cell & TCellComponents & { FlexRender: () => ComponentChildren }, ) => ComponentChildren )(extendedCell) )} ) } return AppCellImpl as AppCellComponent }, [table]) // AppHeader - Wraps header with context, pre-bound headerComponents, and optional Subscribe const AppHeader = useMemo(() => { function AppHeaderImpl( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): ComponentChildren function AppHeaderImpl< TValue extends CellData = CellData, TAppHeaderSelected = unknown, >( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppHeaderSelected >, ): ComponentChildren function AppHeaderImpl< TValue extends CellData = CellData, TAppHeaderSelected = unknown, >( props: | AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents > | AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppHeaderSelected >, ): ComponentChildren { const { header, children, selector: appHeaderSelector } = props as any const extendedHeader = Object.assign(header, { FlexRender: HeaderFlexRender, ...headerComponents, }) return ( {appHeaderSelector ? ( {(state: TAppHeaderSelected) => ( children as ( header: Header & THeaderComponents, state: TAppHeaderSelected, ) => ComponentChildren )(extendedHeader, state) } ) : ( ( children as ( header: Header & THeaderComponents & { FlexRender: () => ComponentChildren }, ) => ComponentChildren )(extendedHeader) )} ) } return AppHeaderImpl as AppHeaderComponent< TFeatures, TData, THeaderComponents > }, [table]) // AppFooter - Same as AppHeader (footers use Header type) const AppFooter = useMemo(() => { function AppFooterImpl( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): ComponentChildren function AppFooterImpl< TValue extends CellData = CellData, TAppFooterSelected = unknown, >( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppFooterSelected >, ): ComponentChildren function AppFooterImpl< TValue extends CellData = CellData, TAppFooterSelected = unknown, >( props: | AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents > | AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppFooterSelected >, ): ComponentChildren { const { header, children, selector: appFooterSelector } = props as any const extendedHeader = Object.assign(header, { FlexRender: FooterFlexRender, ...headerComponents, }) return ( {appFooterSelector ? ( {(state: TAppFooterSelected) => ( children as ( header: Header & THeaderComponents, state: TAppFooterSelected, ) => ComponentChildren )(extendedHeader, state) } ) : ( ( children as ( header: Header & THeaderComponents & { FlexRender: () => ComponentChildren }, ) => ComponentChildren )(extendedHeader) )} ) } return AppFooterImpl as AppHeaderComponent< TFeatures, TData, THeaderComponents > }, [table]) // Combine everything into the extended table API const extendedTable = useMemo(() => { return Object.assign(table, { AppTable, AppCell, AppHeader, AppFooter, ...tableComponents, }) as AppPreactTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > }, [table, AppTable, AppCell, AppHeader, AppFooter]) return extendedTable } return { appFeatures: defaultTableOptions._features as TFeatures, createAppColumnHelper, useAppTable, useTableContext, useCellContext, useHeaderContext, } } ================================================ FILE: packages/preact-table/src/index.ts ================================================ export * from '@tanstack/table-core' export * from './FlexRender' export * from './Subscribe' export * from './createTableHook' export * from './useTable' ================================================ FILE: packages/preact-table/src/useTable.ts ================================================ import { useEffect, useLayoutEffect, useMemo, useState } from 'preact/hooks' import { constructTable } from '@tanstack/table-core' import { useStore } from '@tanstack/preact-store' import { FlexRender } from './FlexRender' import { Subscribe } from './Subscribe' import type { CellData, NoInfer, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { ComponentChildren } from 'preact' import type { FlexRenderProps } from './FlexRender' import type { SubscribeProps } from './Subscribe' const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect export type PreactTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = Table & { /** * A Preact HOC (Higher Order Component) that allows you to subscribe to the table state. * * This is useful for opting into state re-renders for specific parts of the table state. * * @example * ({ rowSelection: state.rowSelection })}> * {({ rowSelection }) => ( // important to include `{() => {()}}` syntax * * // render the row * * )} * */ Subscribe: (props: { selector: (state: NoInfer>) => TSelected children: ((state: TSelected) => ComponentChildren) | ComponentChildren }) => ComponentChildren /** * A Preact component that renders headers, cells, or footers with custom markup. * Use this utility component instead of manually calling flexRender. * * @example * ```tsx * * * * ``` * * This replaces calling `flexRender` directly like this: * ```tsx * flexRender(cell.column.columnDef.cell, cell.getContext()) * flexRender(header.column.columnDef.header, header.getContext()) * flexRender(footer.column.columnDef.footer, footer.getContext()) * ``` */ FlexRender: ( props: FlexRenderProps, ) => ComponentChildren /** * The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `useTable`. * * @example * const table = useTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state * * console.log(table.state.globalFilter) */ readonly state: Readonly } export function useTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( tableOptions: TableOptions, selector: (state: TableState) => TSelected = () => ({}) as TSelected, ): PreactTable { const [table] = useState(() => { const tableInstance = constructTable(tableOptions) as PreactTable< TFeatures, TData, TSelected > tableInstance.Subscribe = function SubscribeBound( props: Omit, 'table'>, ) { return Subscribe({ ...props, table: tableInstance }) } tableInstance.FlexRender = FlexRender return tableInstance }) // sync table options on every render table.setOptions((prev) => ({ ...prev, ...tableOptions, })) useIsomorphicLayoutEffect(() => { // prevent race condition between table.setOptions and table.baseStore.setState queueMicrotask(() => { table.baseStore.setState((prev) => ({ ...prev, })) }) }, [ table.options.columns, // re-render when columns change table.options.data, // re-render when data changes table.options.state, // sync preact state to the table store ]) const state = useStore(table.store, selector) return useMemo( () => ({ ...table, state, }), [state, table], ) } ================================================ FILE: packages/preact-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact", "skipLibCheck": true, "paths": { "react": ["./node_modules/preact/compat/"], "react-dom": ["./node_modules/preact/compat/"] } }, "include": [ "src", "eslint.config.js", "vite.config.ts", "tests", "node_modules/vite/client.d.ts" ] } ================================================ FILE: packages/preact-table/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import preact from '@preact/preset-vite' import packageJson from './package.json' const config = defineConfig({ plugins: [preact()], test: { name: packageJson.name, dir: './tests', watch: false, environment: 'jsdom', // setupFiles: ['./tests/test-setup.ts'], globals: true, }, }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: './src/index.ts', srcDir: './src', }), ) ================================================ FILE: packages/react-table/eslint.config.js ================================================ // @ts-check import pluginReact from '@eslint-react/eslint-plugin' import pluginReactCompiler from 'eslint-plugin-react-compiler' import pluginReactHooks from 'eslint-plugin-react-hooks' import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [ ...rootConfig, { files: ['**/*.{ts,tsx}'], ...pluginReact.configs.recommended, }, { plugins: { 'react-hooks': pluginReactHooks, 'react-compiler': pluginReactCompiler, }, rules: { '@eslint-react/dom/no-missing-button-type': 'off', 'react-compiler/react-compiler': 'error', 'react-hooks/exhaustive-deps': 'error', 'react-hooks/rules-of-hooks': 'error', }, }, { files: ['**/__tests__/**'], rules: { // 'react-compiler/react-compiler': 'off', }, }, ] export default config ================================================ FILE: packages/react-table/package.json ================================================ { "name": "@tanstack/react-table", "version": "9.0.0-alpha.19", "description": "Headless UI for building powerful tables & datagrids for React.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/react-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "react", "table", "react-table", "datagrid" ], "type": "module", "types": "dist/esm/index.d.ts", "main": "dist/esm/index.js", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./package.json": "./package.json", "./legacy": { "import": { "types": "./dist/esm/legacy.d.ts", "default": "./dist/esm/legacy.js" } } }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:lib": "vitest --passWithNoTests", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "dependencies": { "@tanstack/react-store": "^0.9.2", "@tanstack/table-core": "workspace:*" }, "devDependencies": { "@eslint-react/eslint-plugin": "^2.13.0", "@types/react": "^19.2.10", "@vitejs/plugin-react": "^5.1.2", "eslint-plugin-react-compiler": "19.1.0-rc.2", "eslint-plugin-react-hooks": "^7.0.1", "react": "^19.2.4" }, "peerDependencies": { "react": ">=18" } } ================================================ FILE: packages/react-table/src/FlexRender.tsx ================================================ import React from 'react' import type { Cell, CellData, Header, RowData, TableFeatures, } from '@tanstack/table-core' import type { ComponentType, JSX, ReactNode } from 'react' export type Renderable = ReactNode | ComponentType function isReactComponent( component: unknown, ): component is ComponentType { return ( isClassComponent(component) || typeof component === 'function' || isExoticComponent(component) ) } function isClassComponent(component: any) { return ( typeof component === 'function' && (() => { const proto = Object.getPrototypeOf(component) return proto.prototype && proto.prototype.isReactComponent })() ) } function isExoticComponent(component: any) { return ( typeof component === 'object' && typeof component.$$typeof === 'symbol' && ['react.memo', 'react.forward_ref'].includes(component.$$typeof.description) ) } /** * If rendering headers, cells, or footers with custom markup, use flexRender instead of `cell.getValue()` or `cell.renderValue()`. * @example flexRender(cell.column.columnDef.cell, cell.getContext()) */ export function flexRender( Comp: Renderable, props: TProps, ): ReactNode | JSX.Element { return !Comp ? null : isReactComponent(Comp) ? ( ) : ( Comp ) } /** * Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. * Only one prop (`cell`, `header`, or `footer`) may be passed. * @example * @example * @example */ export type FlexRenderProps< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = | { cell: Cell; header?: never; footer?: never } | { header: Header cell?: never footer?: never } | { footer: Header cell?: never header?: never } /** * Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. * Only one prop (`cell`, `header`, or `footer`) may be passed. * @example * ```tsx * * * * ``` * * This replaces calling `flexRender` directly like this: * ```tsx * flexRender(cell.column.columnDef.cell, cell.getContext()) * flexRender(header.column.columnDef.header, header.getContext()) * flexRender(footer.column.columnDef.footer, footer.getContext()) * ``` */ export function FlexRender< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(props: FlexRenderProps) { if ('cell' in props && props.cell) { return flexRender(props.cell.column.columnDef.cell, props.cell.getContext()) } if ('header' in props && props.header) { return flexRender( props.header.column.columnDef.header, props.header.getContext(), ) } if ('footer' in props && props.footer) { return flexRender( props.footer.column.columnDef.footer, props.footer.getContext(), ) } return null } ================================================ FILE: packages/react-table/src/Subscribe.ts ================================================ 'use client' import { shallow, useStore } from '@tanstack/react-store' import type { NoInfer, RowData, Table, TableFeatures, TableState, } from '@tanstack/table-core' import type { FunctionComponent, ReactNode } from 'react' export type SubscribeProps< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = { /** * The table instance to subscribe to. Required when using as a standalone component. * Not needed when using as `table.Subscribe`. */ table: Table /** * A selector function that selects the part of the table state to subscribe to. * This allows for fine-grained reactivity by only re-rendering when the selected state changes. */ selector: (state: NoInfer>) => TSelected /** * The children to render. Can be a function that receives the selected state, or a React node. */ children: ((state: TSelected) => ReactNode) | ReactNode } /** * A React component that allows you to subscribe to the table state. * * This is useful for opting into state re-renders for specific parts of the table state. * * @example * ```tsx * // As a standalone component * ({ rowSelection: state.rowSelection })}> * {({ rowSelection }) => ( *
Selected rows: {Object.keys(rowSelection).length}
* )} *
* ``` * * @example * ```tsx * // As table.Subscribe (table instance method) * ({ rowSelection: state.rowSelection })}> * {({ rowSelection }) => ( *
Selected rows: {Object.keys(rowSelection).length}
* )} *
* ``` */ export function Subscribe< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( props: SubscribeProps, ): ReturnType { const selected = useStore(props.table.store, props.selector, shallow) return typeof props.children === 'function' ? props.children(selected) : props.children } ================================================ FILE: packages/react-table/src/createTableHook.tsx ================================================ 'use client' /* eslint-disable @eslint-react/no-context-provider */ // eslint-disable-next-line @eslint-react/no-use-context -- intentional useContext for older React support import React, { createContext, useContext, useMemo } from 'react' import { createColumnHelper as coreCreateColumnHelper } from '@tanstack/table-core' import { useTable } from './useTable' import { FlexRender } from './FlexRender' import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, Cell, CellContext, CellData, Column, ColumnDef, DeepKeys, DeepValue, DisplayColumnDef, GroupColumnDef, Header, IdentifiedColumnDef, NoInfer, Row, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { ComponentType, ReactNode } from 'react' import type { ReactTable } from './useTable' // ============================================================================= // Enhanced Context Types with Pre-bound Components // ============================================================================= /** * Enhanced CellContext with pre-bound cell components. * The `cell` property includes the registered cellComponents. */ export type AppCellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, > = { cell: Cell & TCellComponents & { FlexRender: () => ReactNode } column: Column getValue: CellContext['getValue'] renderValue: CellContext['renderValue'] row: Row table: Table } /** * Enhanced HeaderContext with pre-bound header components. * The `header` property includes the registered headerComponents. */ export type AppHeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, > = { column: Column header: Header & THeaderComponents & { FlexRender: () => ReactNode } table: Table } // ============================================================================= // Enhanced Column Definition Types // ============================================================================= /** * Template type for column definitions that can be a string or a function. */ type AppColumnDefTemplate = | string | ((props: TProps) => any) /** * Enhanced column definition base with pre-bound components in cell/header/footer contexts. */ type AppColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< IdentifiedColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced display column definition with pre-bound components. */ type AppDisplayColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< DisplayColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced group column definition with pre-bound components. */ type AppGroupColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< GroupColumnDef, 'cell' | 'header' | 'footer' | 'columns' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > columns?: Array> } // ============================================================================= // Enhanced Column Helper Type // ============================================================================= /** * Enhanced column helper with pre-bound components in cell/header/footer contexts. * This enables TypeScript to know about the registered components when defining columns. */ export type AppColumnHelper< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = { /** * Creates a data column definition with an accessor key or function. * The cell, header, and footer contexts include pre-bound components. */ accessor: < TAccessor extends AccessorFn | DeepKeys, TValue extends TAccessor extends AccessorFn ? TReturn : TAccessor extends DeepKeys ? DeepValue : never, >( accessor: TAccessor, column: TAccessor extends AccessorFn ? AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents > & { id: string } : AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents >, ) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef /** * Wraps an array of column definitions to preserve each column's individual TValue type. */ columns: >>( columns: [...TColumns], ) => Array> & [...TColumns] /** * Creates a display column definition for non-data columns. * The cell, header, and footer contexts include pre-bound components. */ display: ( column: AppDisplayColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => DisplayColumnDef /** * Creates a group column definition with nested child columns. * The cell, header, and footer contexts include pre-bound components. */ group: ( column: AppGroupColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => GroupColumnDef } // ============================================================================= // CreateTableHook Options and Props // ============================================================================= /** * Options for creating a table hook with pre-bound components and default table options. * Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. */ export type CreateTableHookOptions< TFeatures extends TableFeatures, TTableComponents extends Record>, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< TableOptions, 'columns' | 'data' | 'store' | 'state' | 'initialState' > & { /** * Table-level components that need access to the table instance. * These are available directly on the table object returned by useAppTable. * Use `useTableContext()` inside these components. * @example { PaginationControls, GlobalFilter, RowCount } */ tableComponents?: TTableComponents /** * Cell-level components that need access to the cell instance. * These are available on the cell object passed to AppCell's children. * Use `useCellContext()` inside these components. * @example { TextCell, NumberCell, DateCell, CurrencyCell } */ cellComponents?: TCellComponents /** * Header-level components that need access to the header instance. * These are available on the header object passed to AppHeader/AppFooter's children. * Use `useHeaderContext()` inside these components. * @example { SortIndicator, ColumnFilter, ResizeHandle } */ headerComponents?: THeaderComponents } /** * Props for AppTable component - without selector */ export interface AppTablePropsWithoutSelector { children: ReactNode selector?: never } /** * Props for AppTable component - with selector */ export interface AppTablePropsWithSelector< TFeatures extends TableFeatures, TSelected, > { children: (state: TSelected) => ReactNode selector: (state: TableState) => TSelected } /** * Props for AppCell component - without selector */ export interface AppCellPropsWithoutSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, > { cell: Cell children: ( cell: Cell & TCellComponents & { FlexRender: () => ReactNode }, ) => ReactNode selector?: never } /** * Props for AppCell component - with selector */ export interface AppCellPropsWithSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, TSelected, > { cell: Cell children: ( cell: Cell & TCellComponents & { FlexRender: () => ReactNode }, state: TSelected, ) => ReactNode selector: (state: TableState) => TSelected } /** * Props for AppHeader/AppFooter component - without selector */ export interface AppHeaderPropsWithoutSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, > { header: Header children: ( header: Header & THeaderComponents & { FlexRender: () => ReactNode }, ) => ReactNode selector?: never } /** * Props for AppHeader/AppFooter component - with selector */ export interface AppHeaderPropsWithSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, TSelected, > { header: Header children: ( header: Header & THeaderComponents & { FlexRender: () => ReactNode }, state: TSelected, ) => ReactNode selector: (state: TableState) => TSelected } /** * Component type for AppCell - wraps a cell and provides cell context with optional Subscribe */ export interface AppCellComponent< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, > { ( props: AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents >, ): ReactNode ( props: AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TSelected >, ): ReactNode } /** * Component type for AppHeader/AppFooter - wraps a header and provides header context with optional Subscribe */ export interface AppHeaderComponent< TFeatures extends TableFeatures, TData extends RowData, THeaderComponents extends Record>, > { ( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): ReactNode ( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TSelected >, ): ReactNode } /** * Component type for AppTable - root wrapper with optional Subscribe */ export interface AppTableComponent { (props: AppTablePropsWithoutSelector): ReactNode (props: AppTablePropsWithSelector): ReactNode } /** * Extended table API returned by useAppTable with all App wrapper components */ export type AppReactTable< TFeatures extends TableFeatures, TData extends RowData, TSelected, TTableComponents extends Record>, TCellComponents extends Record>, THeaderComponents extends Record>, > = ReactTable & NoInfer & { /** * Root wrapper component that provides table context with optional Subscribe. * @example * ```tsx * // Without selector - children is ReactNode * * ...
*
* * // With selector - children receives selected state * s.pagination}> * {(pagination) =>
Page {pagination.pageIndex}
} *
* ``` */ AppTable: AppTableComponent /** * Wraps a cell and provides cell context with pre-bound cellComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * // Without selector * * {(c) => } * * * // With selector - children receives cell and selected state * s.columnFilters}> * {(c, filters) => {filters.length}} * * ``` */ AppCell: AppCellComponent> /** * Wraps a header and provides header context with pre-bound headerComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * // Without selector * * {(h) => } * * * // With selector * s.sorting}> * {(h, sorting) => {sorting.length} sorted} * * ``` */ AppHeader: AppHeaderComponent> /** * Wraps a footer and provides header context with pre-bound headerComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * * {(f) => } * * ``` */ AppFooter: AppHeaderComponent> } /** * Creates a custom table hook with pre-bound components for composition. * * This is the table equivalent of TanStack Form's `createFormHook`. It allows you to: * - Define features, row models, and default options once, shared across all tables * - Register reusable table, cell, and header components * - Access table/cell/header instances via context in those components * - Get a `useAppTable` hook that returns an extended table with App wrapper components * - Get a `createAppColumnHelper` function pre-bound to your features * * @example * ```tsx * // hooks/table.ts * export const { * useAppTable, * createAppColumnHelper, * useTableContext, * useCellContext, * useHeaderContext, * } = createTableHook({ * _features: tableFeatures({ * rowPaginationFeature, * rowSortingFeature, * columnFilteringFeature, * }), * _rowModels: { * paginatedRowModel: createPaginatedRowModel(), * sortedRowModel: createSortedRowModel(sortFns), * filteredRowModel: createFilteredRowModel(filterFns), * }, * tableComponents: { PaginationControls, RowCount }, * cellComponents: { TextCell, NumberCell }, * headerComponents: { SortIndicator, ColumnFilter }, * }) * * // Create column helper with TFeatures already bound * const columnHelper = createAppColumnHelper() * * // components/table-components.tsx * function PaginationControls() { * const table = useTableContext() // TFeatures already known! * return s.pagination}>... * } * * // features/users.tsx * function UsersTable({ data }: { data: Person[] }) { * const table = useAppTable({ * columns, * data, // TData inferred from Person[] * }) * * return ( * * * * {table.getHeaderGroups().map(headerGroup => ( * * {headerGroup.headers.map(h => ( * * {(header) => ( * * )} * * ))} * * ))} * * * {table.getRowModel().rows.map(row => ( * * {row.getAllCells().map(c => ( * * {(cell) => } * * ))} * * ))} * *
* * *
* *
* ) * } * ``` */ export function createTableHook< TFeatures extends TableFeatures, const TTableComponents extends Record>, const TCellComponents extends Record>, const THeaderComponents extends Record>, >({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableHookOptions< TFeatures, TTableComponents, TCellComponents, THeaderComponents >) { // Create contexts internally with TFeatures baked in const TableContext = createContext>( null as never, ) const CellContext = createContext>(null as never) const HeaderContext = createContext>( null as never, ) /** * Create a column helper pre-bound to the features and components configured in this table hook. * The cell, header, and footer contexts include pre-bound components (e.g., `cell.TextCell`). * @example * ```tsx * const columnHelper = createAppColumnHelper() * * const columns = [ * columnHelper.accessor('firstName', { * header: 'First Name', * cell: ({ cell }) => , // cell has pre-bound components! * }), * columnHelper.accessor('age', { * header: 'Age', * cell: ({ cell }) => , * }), * ] * ``` */ function createAppColumnHelper(): AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > { // The runtime implementation is the same - components are attached at render time // This cast provides the enhanced types for column definitions return coreCreateColumnHelper() as AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > } /** * Access the table instance from within an `AppTable` wrapper. * Use this in custom `tableComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function PaginationControls() { * const table = useTableContext() * return ( * s.pagination}> * {(pagination) => ( *
* * Page {pagination.pageIndex + 1} * *
* )} *
* ) * } * ``` */ function useTableContext(): ReactTable< TFeatures, TData > { // useContext used for React 18 compatibility - use() requires React 19+ // eslint-disable-next-line @eslint-react/no-use-context -- intentional useContext for older React support const table = useContext(TableContext) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!table) { throw new Error( '`useTableContext` must be used within an `AppTable` component. ' + 'Make sure your component is wrapped with `...`.', ) } return table as ReactTable } /** * Access the cell instance from within an `AppCell` wrapper. * Use this in custom `cellComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function TextCell() { * const cell = useCellContext() * return {cell.getValue()} * } * * function NumberCell({ format }: { format?: Intl.NumberFormatOptions }) { * const cell = useCellContext() * return {cell.getValue().toLocaleString(undefined, format)} * } * ``` */ function useCellContext() { // useContext used for React 18 compatibility - use() requires React 19+ // eslint-disable-next-line @eslint-react/no-use-context -- intentional useContext for older React support const cell = useContext(CellContext) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!cell) { throw new Error( '`useCellContext` must be used within an `AppCell` component. ' + 'Make sure your component is wrapped with `...`.', ) } return cell as Cell } /** * Access the header instance from within an `AppHeader` or `AppFooter` wrapper. * Use this in custom `headerComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function SortIndicator() { * const header = useHeaderContext() * const sorted = header.column.getIsSorted() * return sorted === 'asc' ? '🔼' : sorted === 'desc' ? '🔽' : null * } * * function ColumnFilter() { * const header = useHeaderContext() * if (!header.column.getCanFilter()) return null * return ( * header.column.setFilterValue(e.target.value)} * placeholder="Filter..." * /> * ) * } * ``` */ function useHeaderContext() { // useContext used for React 18 compatibility - use() requires React 19+ // eslint-disable-next-line @eslint-react/no-use-context -- intentional useContext for older React support const header = useContext(HeaderContext) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!header) { throw new Error( '`useHeaderContext` must be used within an `AppHeader` or `AppFooter` component.', ) } return header as Header } /** * Context-aware FlexRender component for cells. * Uses the cell from context, so no need to pass cell prop. */ function CellFlexRender() { const cell = useCellContext() return } /** * Context-aware FlexRender component for headers. * Uses the header from context, so no need to pass header prop. */ function HeaderFlexRender() { const header = useHeaderContext() return } /** * Context-aware FlexRender component for footers. * Uses the header from context, so no need to pass footer prop. */ function FooterFlexRender() { const header = useHeaderContext() return } /** * Enhanced useTable hook that returns a table with App wrapper components * and pre-bound tableComponents attached directly to the table object. * * Default options from createTableHook are automatically merged with * the options passed here. Options passed here take precedence. * * TFeatures is already known from the createTableHook call; TData is inferred from the data prop. */ function useAppTable( tableOptions: Omit< TableOptions, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ): AppReactTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > { // Merge default options with provided options (provided takes precedence) const table = useTable( { ...defaultTableOptions, ...tableOptions } as TableOptions< TFeatures, TData >, selector, ) // AppTable - Root wrapper that provides table context with optional Subscribe const AppTable = useMemo(() => { function AppTableImpl(props: AppTablePropsWithoutSelector): ReactNode function AppTableImpl( props: AppTablePropsWithSelector, ): ReactNode function AppTableImpl( props: | AppTablePropsWithoutSelector | AppTablePropsWithSelector, ): ReactNode { const { children, selector: appTableSelector } = props as any return ( {appTableSelector ? ( {(state: TAppTableSelected) => (children as (state: TAppTableSelected) => ReactNode)(state) } ) : ( children )} ) } return AppTableImpl as AppTableComponent }, [table]) // AppCell - Wraps cell with context, pre-bound cellComponents, and optional Subscribe const AppCell = useMemo(() => { function AppCellImpl( props: AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents >, ): ReactNode function AppCellImpl< TValue extends CellData = CellData, TAppCellSelected = unknown, >( props: AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TAppCellSelected >, ): ReactNode function AppCellImpl< TValue extends CellData = CellData, TAppCellSelected = unknown, >( props: | AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents > | AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TAppCellSelected >, ): ReactNode { const { cell, children, selector: appCellSelector } = props as any const extendedCell = Object.assign(cell, { FlexRender: CellFlexRender, ...cellComponents, }) return ( {appCellSelector ? ( {(state: TAppCellSelected) => ( children as ( cell: Cell & TCellComponents & { FlexRender: () => ReactNode }, state: TAppCellSelected, ) => ReactNode )(extendedCell, state) } ) : ( ( children as ( cell: Cell & TCellComponents & { FlexRender: () => ReactNode }, ) => ReactNode )(extendedCell) )} ) } return AppCellImpl as AppCellComponent }, [table]) // AppHeader - Wraps header with context, pre-bound headerComponents, and optional Subscribe const AppHeader = useMemo(() => { function AppHeaderImpl( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): ReactNode function AppHeaderImpl< TValue extends CellData = CellData, TAppHeaderSelected = unknown, >( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppHeaderSelected >, ): ReactNode function AppHeaderImpl< TValue extends CellData = CellData, TAppHeaderSelected = unknown, >( props: | AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents > | AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppHeaderSelected >, ): ReactNode { const { header, children, selector: appHeaderSelector } = props as any const extendedHeader = Object.assign(header, { FlexRender: HeaderFlexRender, ...headerComponents, }) return ( {appHeaderSelector ? ( {(state: TAppHeaderSelected) => ( children as ( header: Header & THeaderComponents & { FlexRender: () => ReactNode }, state: TAppHeaderSelected, ) => ReactNode )(extendedHeader, state) } ) : ( ( children as ( header: Header & THeaderComponents & { FlexRender: () => ReactNode }, ) => ReactNode )(extendedHeader) )} ) } return AppHeaderImpl as AppHeaderComponent< TFeatures, TData, THeaderComponents > }, [table]) // AppFooter - Same as AppHeader (footers use Header type) const AppFooter = useMemo(() => { function AppFooterImpl( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): ReactNode function AppFooterImpl< TValue extends CellData = CellData, TAppFooterSelected = unknown, >( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppFooterSelected >, ): ReactNode function AppFooterImpl< TValue extends CellData = CellData, TAppFooterSelected = unknown, >( props: | AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents > | AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppFooterSelected >, ): ReactNode { const { header, children, selector: appFooterSelector } = props as any const extendedHeader = Object.assign(header, { FlexRender: FooterFlexRender, ...headerComponents, }) return ( {appFooterSelector ? ( {(state: TAppFooterSelected) => ( children as ( header: Header & THeaderComponents & { FlexRender: () => ReactNode }, state: TAppFooterSelected, ) => ReactNode )(extendedHeader, state) } ) : ( ( children as ( header: Header & THeaderComponents & { FlexRender: () => ReactNode }, ) => ReactNode )(extendedHeader) )} ) } return AppFooterImpl as AppHeaderComponent< TFeatures, TData, THeaderComponents > }, [table]) // Combine everything into the extended table API const extendedTable = useMemo(() => { return Object.assign(table, { AppTable, AppCell, AppHeader, AppFooter, ...tableComponents, }) as AppReactTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > }, [table, AppTable, AppCell, AppHeader, AppFooter]) return extendedTable } return { appFeatures: defaultTableOptions._features as TFeatures, createAppColumnHelper, useAppTable, useTableContext, useCellContext, useHeaderContext, } } ================================================ FILE: packages/react-table/src/index.ts ================================================ export * from '@tanstack/table-core' export * from './FlexRender' export * from './Subscribe' export * from './createTableHook' export * from './useTable' ================================================ FILE: packages/react-table/src/legacy.ts ================================================ // Legacy entry - v8-style API for incremental migration // Import flexRender, types (ColumnFiltersState, etc.) from '@tanstack/react-table' export * from './useLegacyTable' ================================================ FILE: packages/react-table/src/useLegacyTable.ts ================================================ 'use client' import { aggregationFns, createColumnHelper, createExpandedRowModel, createFacetedMinMaxValues, createFacetedRowModel, createFacetedUniqueValues, createFilteredRowModel, createGroupedRowModel, createPaginatedRowModel, createSortedRowModel, filterFns, sortFns, stockFeatures, } from '@tanstack/table-core' import { useCallback, useMemo } from 'react' import { shallow, useStore } from '@tanstack/react-store' import { useTable } from './useTable' import type { Cell, Column, ColumnDef, CreateRowModels_All, Header, HeaderGroup, Row, RowData, RowModel, StockFeatures, Table, TableOptions, TableState, } from '@tanstack/table-core' import type { ReactTable } from './useTable' // ============================================================================= // V8-style row model factory functions // These are stub functions that act as markers for useLegacyTable to know // which row models to enable. They don't actually do anything - the real // implementation is handled by useLegacyTable internally. // ============================================================================= /** * @deprecated Use `createFilteredRowModel(filterFns)` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the filtered row model. */ export function getFilteredRowModel< TData extends RowData, >(): RowModelFactory { return (() => () => {}) as unknown as RowModelFactory } /** * @deprecated Use `createSortedRowModel(sortFns)` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the sorted row model. */ export function getSortedRowModel< TData extends RowData, >(): RowModelFactory { return (() => () => {}) as unknown as RowModelFactory } /** * @deprecated Use `createPaginatedRowModel()` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the paginated row model. */ export function getPaginationRowModel< TData extends RowData, >(): RowModelFactory { return (() => () => {}) as unknown as RowModelFactory } /** * @deprecated Use `createExpandedRowModel()` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the expanded row model. */ export function getExpandedRowModel< TData extends RowData, >(): RowModelFactory { return (() => () => {}) as unknown as RowModelFactory } /** * @deprecated Use `createGroupedRowModel(aggregationFns)` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the grouped row model. */ export function getGroupedRowModel< TData extends RowData, >(): RowModelFactory { return (() => () => {}) as unknown as RowModelFactory } /** * @deprecated Use `createFacetedRowModel()` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the faceted row model. */ export function getFacetedRowModel< TData extends RowData, >(): FacetedRowModelFactory { return (() => () => {}) as unknown as FacetedRowModelFactory } /** * @deprecated Use `createFacetedMinMaxValues()` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the faceted min/max values. */ export function getFacetedMinMaxValues< TData extends RowData, >(): FacetedMinMaxValuesFactory { return (() => () => undefined) as unknown as FacetedMinMaxValuesFactory } /** * @deprecated Use `createFacetedUniqueValues()` with the new `useTable` hook instead. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It acts as a marker to enable the faceted unique values. */ export function getFacetedUniqueValues< TData extends RowData, >(): FacetedUniqueValuesFactory { return (() => () => new Map()) as unknown as FacetedUniqueValuesFactory } /** * @deprecated The core row model is always created automatically in v9. * * This is a stub function for v8 API compatibility with `useLegacyTable`. * It does nothing - the core row model is always available. */ export function getCoreRowModel< TData extends RowData, >(): RowModelFactory { return (() => () => {}) as unknown as RowModelFactory } // ============================================================================= // Type definitions // ============================================================================= /** * Row model factory function type from v8 API */ type RowModelFactory = ( table: Table, ) => () => RowModel /** * Faceted row model factory function type from v8 API */ type FacetedRowModelFactory = ( table: Table, columnId: string, ) => () => RowModel /** * Faceted min/max values factory function type from v8 API */ type FacetedMinMaxValuesFactory = ( table: Table, columnId: string, ) => () => undefined | [number, number] /** * Faceted unique values factory function type from v8 API */ type FacetedUniqueValuesFactory = ( table: Table, columnId: string, ) => () => Map /** * Legacy v8-style row model options */ export interface LegacyRowModelOptions { /** * Returns the core row model for the table. * @deprecated This option is no longer needed in v9. The core row model is always created automatically. */ getCoreRowModel?: RowModelFactory /** * Returns the filtered row model for the table. * @deprecated Use `_rowModels.filteredRowModel` with `createFilteredRowModel(filterFns)` instead. */ getFilteredRowModel?: RowModelFactory /** * Returns the sorted row model for the table. * @deprecated Use `_rowModels.sortedRowModel` with `createSortedRowModel(sortFns)` instead. */ getSortedRowModel?: RowModelFactory /** * Returns the paginated row model for the table. * @deprecated Use `_rowModels.paginatedRowModel` with `createPaginatedRowModel()` instead. */ getPaginationRowModel?: RowModelFactory /** * Returns the expanded row model for the table. * @deprecated Use `_rowModels.expandedRowModel` with `createExpandedRowModel()` instead. */ getExpandedRowModel?: RowModelFactory /** * Returns the grouped row model for the table. * @deprecated Use `_rowModels.groupedRowModel` with `createGroupedRowModel(aggregationFns)` instead. */ getGroupedRowModel?: RowModelFactory /** * Returns the faceted row model for a column. * @deprecated Use `_rowModels.facetedRowModel` with `createFacetedRowModel()` instead. */ getFacetedRowModel?: FacetedRowModelFactory /** * Returns the faceted min/max values for a column. * @deprecated Use `_rowModels.facetedMinMaxValues` with `createFacetedMinMaxValues()` instead. */ getFacetedMinMaxValues?: FacetedMinMaxValuesFactory /** * Returns the faceted unique values for a column. * @deprecated Use `_rowModels.facetedUniqueValues` with `createFacetedUniqueValues()` instead. */ getFacetedUniqueValues?: FacetedUniqueValuesFactory } /** * Legacy v8-style table options that work with useLegacyTable. * * This type omits `_features` and `_rowModels` and instead accepts the v8-style * `get*RowModel` function options. * * @deprecated This is a compatibility layer for migrating from v8. Use `useTable` with explicit `_features` and `_rowModels` instead. */ export type LegacyTableOptions = Omit< TableOptions, '_features' | '_rowModels' > & LegacyRowModelOptions /** * Legacy table instance type that includes the v8-style `getState()` method. * * @deprecated Use `useTable` with explicit state selection instead. */ export type LegacyReactTable = ReactTable< StockFeatures, TData, TableState > & { /** * Returns the current table state. * @deprecated In v9, access state directly via `table.state` or use `table.store.state` for the full state. */ getState: () => TableState } // ============================================================================= // Legacy type aliases - StockFeatures hardcoded for simpler prop typing with useLegacyTable // ============================================================================= /** @deprecated Use Column with useTable instead. */ export type LegacyColumn = Column< StockFeatures, TData, TValue > /** @deprecated Use Row with useTable instead. */ export type LegacyRow = Row /** @deprecated Use Cell with useTable instead. */ export type LegacyCell = Cell< StockFeatures, TData, TValue > /** @deprecated Use Header with useTable instead. */ export type LegacyHeader = Header< StockFeatures, TData, TValue > /** @deprecated Use HeaderGroup with useTable instead. */ export type LegacyHeaderGroup = HeaderGroup< StockFeatures, TData > /** @deprecated Use ColumnDef with useTable instead. */ export type LegacyColumnDef< TData extends RowData, TValue = unknown, > = ColumnDef /** @deprecated Use Table with useTable instead. */ export type LegacyTable = Table // ============================================================================= // Legacy column helper - StockFeatures hardcoded // ============================================================================= /** * @deprecated Use `createColumnHelper()` with useTable instead. * * A column helper with StockFeatures pre-bound for use with useLegacyTable. * Only requires TData—no need to specify TFeatures. */ export function legacyCreateColumnHelper() { return createColumnHelper() } // ============================================================================= // useLegacyTable hook // ============================================================================= /** * @deprecated This hook is provided as a compatibility layer for migrating from TanStack Table v8. * * Use the new `useTable` hook instead with explicit `_features` and `_rowModels`: * * ```tsx * // New v9 API * const _features = tableFeatures({ * columnFilteringFeature, * rowSortingFeature, * rowPaginationFeature, * }) * * const table = useTable({ * _features, * _rowModels: { * filteredRowModel: createFilteredRowModel(filterFns), * sortedRowModel: createSortedRowModel(sortFns), * paginatedRowModel: createPaginatedRowModel(), * }, * columns, * data, * }) * ``` * * Key differences from v8: * - Features are tree-shakeable - only import what you use * - Row models are explicitly passed via `_rowModels` * - Use `table.Subscribe` for fine-grained re-renders * - State is accessed via `table.state` after selecting with the 2nd argument * * @param options - Legacy v8-style table options * @returns A table instance with the full state subscribed and a `getState()` method */ export function useLegacyTable( options: LegacyTableOptions, ): LegacyReactTable { const { // Extract legacy row model options getCoreRowModel: _getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, getExpandedRowModel, getGroupedRowModel, getFacetedRowModel, getFacetedMinMaxValues, getFacetedUniqueValues, // Rest of the options ...restOptions } = options // Build the _rowModels object based on which legacy options were provided const _rowModels: CreateRowModels_All = {} // Map v8 row model factories to v9 _rowModels // Note: getCoreRowModel is handled automatically in v9, so we ignore it if (getFilteredRowModel) { _rowModels.filteredRowModel = createFilteredRowModel(filterFns) } if (getSortedRowModel) { _rowModels.sortedRowModel = createSortedRowModel(sortFns) } if (getPaginationRowModel) { _rowModels.paginatedRowModel = createPaginatedRowModel() } if (getExpandedRowModel) { _rowModels.expandedRowModel = createExpandedRowModel() } if (getGroupedRowModel) { _rowModels.groupedRowModel = createGroupedRowModel(aggregationFns) } if (getFacetedRowModel) { _rowModels.facetedRowModel = createFacetedRowModel() } if (getFacetedMinMaxValues) { _rowModels.facetedMinMaxValues = createFacetedMinMaxValues() } if (getFacetedUniqueValues) { _rowModels.facetedUniqueValues = createFacetedUniqueValues() } // Call useTable with the v9 API, subscribing to all state changes const table = useTable>( { ...restOptions, _features: stockFeatures, _rowModels, } as TableOptions, (state) => state, ) return useMemo( () => ({ ...table, getState: () => table.state, }) as LegacyReactTable, [table], ) } ================================================ FILE: packages/react-table/src/useTable.ts ================================================ 'use client' import { useEffect, useLayoutEffect, useMemo, useState } from 'react' import { constructTable } from '@tanstack/table-core' import { shallow, useStore } from '@tanstack/react-store' import { FlexRender } from './FlexRender' import { Subscribe } from './Subscribe' import type { CellData, NoInfer, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { FunctionComponent, ReactNode } from 'react' import type { FlexRenderProps } from './FlexRender' import type { SubscribeProps } from './Subscribe' const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect export type ReactTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = Table & { /** * A React HOC (Higher Order Component) that allows you to subscribe to the table state. * * This is useful for opting into state re-renders for specific parts of the table state. * * @example * ({ rowSelection: state.rowSelection })}> * {({ rowSelection }) => ( // important to include `{() => {()}}` syntax * // render the row * * ))} * */ Subscribe: (props: { selector: (state: NoInfer>) => TSelected children: ((state: TSelected) => ReactNode) | ReactNode }) => ReturnType /** * A React component that renders headers, cells, or footers with custom markup. * Use this utility component instead of manually calling flexRender. * * @example * ```tsx * * * * ``` * * This replaces calling `flexRender` directly like this: * ```tsx * flexRender(cell.column.columnDef.cell, cell.getContext()) * flexRender(header.column.columnDef.header, header.getContext()) * flexRender(footer.column.columnDef.footer, footer.getContext()) * ``` */ FlexRender: ( props: FlexRenderProps, ) => ReactNode /** * The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `useTable`. * * @example * const table = useTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state * * console.log(table.state.globalFilter) */ readonly state: Readonly } export function useTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( tableOptions: TableOptions, selector: (state: TableState) => TSelected = () => ({}) as TSelected, ): ReactTable { const [table] = useState(() => { const tableInstance = constructTable(tableOptions) as ReactTable< TFeatures, TData, TSelected > tableInstance.Subscribe = function SubscribeBound( props: Omit, 'table'>, ) { return Subscribe({ ...props, table: tableInstance }) } tableInstance.FlexRender = FlexRender return tableInstance }) useEffect(() => { // sync table options on every render table.setOptions((prev) => ({ ...prev, ...tableOptions, })) }, [table, tableOptions]) const state = useStore(table.store, selector, shallow) return useMemo( () => ({ ...table, state, }), [state, table], ) } ================================================ FILE: packages/react-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "react" }, "include": ["src", "eslint.config.js", "vite.config.ts", "tests"] } ================================================ FILE: packages/react-table/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import react from '@vitejs/plugin-react' import packageJson from './package.json' const config = defineConfig({ plugins: [react()], test: { name: packageJson.name, dir: './tests', watch: false, environment: 'jsdom', // setupFiles: ['./tests/test-setup.ts'], globals: true, }, }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: ['./src/index.ts', './src/legacy.ts'], srcDir: './src', }), ) ================================================ FILE: packages/react-table-devtools/eslint.config.js ================================================ // @ts-check import pluginReact from '@eslint-react/eslint-plugin' import pluginReactCompiler from 'eslint-plugin-react-compiler' import pluginReactHooks from 'eslint-plugin-react-hooks' import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [ ...rootConfig, { files: ['**/*.{ts,tsx}'], ...pluginReact.configs.recommended, }, { plugins: { 'react-hooks': pluginReactHooks, 'react-compiler': pluginReactCompiler, }, rules: { '@eslint-react/dom/no-missing-button-type': 'off', 'react-compiler/react-compiler': 'error', 'react-hooks/exhaustive-deps': 'error', 'react-hooks/rules-of-hooks': 'error', }, }, ] export default config ================================================ FILE: packages/react-table-devtools/package.json ================================================ { "name": "@tanstack/react-table-devtools", "version": "9.0.0-alpha.11", "description": "React devtools for TanStack Table.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/react-table-devtools" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "react", "tanstack", "table", "devtools" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:lib": "vitest --passWithNoTests", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "type": "module", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./production": { "import": { "types": "./dist/esm/production.d.ts", "default": "./dist/esm/production.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "dependencies": { "@tanstack/devtools-utils": "^0.3.2", "@tanstack/table-core": "workspace:*", "@tanstack/table-devtools": "workspace:*" }, "devDependencies": { "@eslint-react/eslint-plugin": "^2.13.0", "@types/react": "^19.2.10", "@vitejs/plugin-react": "^5.1.2", "eslint-plugin-react-compiler": "19.1.0-rc.2", "eslint-plugin-react-hooks": "^7.0.1", "react": "^19.2.4" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } } ================================================ FILE: packages/react-table-devtools/src/ReactTableDevtools.tsx ================================================ import React from 'react' import { createReactPanel } from '@tanstack/devtools-utils/react' import { TableDevtoolsCore, setTableDevtoolsTarget, } from '@tanstack/table-devtools' import type { RowData, Table, TableFeatures } from '@tanstack/table-core' import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/react' export interface TableDevtoolsReactInit< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, > extends DevtoolsPanelProps { table?: Table } const [TableDevtoolsPanelBase, TableDevtoolsPanelNoOp] = createReactPanel(TableDevtoolsCore) function TableDevtoolsPanel(props: TableDevtoolsReactInit) { setTableDevtoolsTarget(props.table) return } export { TableDevtoolsPanel, TableDevtoolsPanelNoOp } ================================================ FILE: packages/react-table-devtools/src/index.ts ================================================ 'use client' import * as Devtools from './ReactTableDevtools' import * as plugin from './plugin' export const TableDevtoolsPanel = process.env.NODE_ENV !== 'development' ? Devtools.TableDevtoolsPanelNoOp : Devtools.TableDevtoolsPanel export const tableDevtoolsPlugin = process.env.NODE_ENV !== 'development' ? plugin.tableDevtoolsNoOpPlugin : plugin.tableDevtoolsPlugin export type { TableDevtoolsReactInit } from './ReactTableDevtools' export type { TableDevtoolsPluginOptions } from './plugin' ================================================ FILE: packages/react-table-devtools/src/plugin.tsx ================================================ import React from 'react' import { TableDevtoolsPanel } from './ReactTableDevtools' import type { RowData, Table, TableFeatures } from '@tanstack/table-core' export interface TableDevtoolsPluginOptions< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, > { table: Table } function tableDevtoolsPlugin< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, >(options: TableDevtoolsPluginOptions) { return { name: 'TanStack Table', render: (_el: HTMLElement, theme: 'light' | 'dark') => ( ), } } function tableDevtoolsNoOpPlugin< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, >(_options: TableDevtoolsPluginOptions) { return { name: 'TanStack Table', render: (_el: HTMLElement, _theme: 'light' | 'dark') => <>, } } export { tableDevtoolsPlugin, tableDevtoolsNoOpPlugin } ================================================ FILE: packages/react-table-devtools/src/production.ts ================================================ 'use client' export { TableDevtoolsPanel } from './ReactTableDevtools' export type { TableDevtoolsReactInit } from './ReactTableDevtools' export { tableDevtoolsPlugin } from './plugin' export type { TableDevtoolsPluginOptions } from './plugin' ================================================ FILE: packages/react-table-devtools/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "react" }, "include": ["src", "eslint.config.js", "vite.config.ts", "tests"] } ================================================ FILE: packages/react-table-devtools/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import react from '@vitejs/plugin-react' import packageJson from './package.json' const config = defineConfig({ plugins: [react()], test: { name: packageJson.name, dir: './tests', watch: false, environment: 'jsdom', globals: true, }, }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: ['./src/index.ts', './src/production.ts'], srcDir: './src', }), ) ================================================ FILE: packages/solid-table/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' export default [ ...rootConfig, { rules: {}, }, ] ================================================ FILE: packages/solid-table/package.json ================================================ { "name": "@tanstack/solid-table", "version": "9.0.0-alpha.10", "description": "Headless UI for building powerful tables & datagrids for Solid.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/solid-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "solid", "table", "solid-table", "datagrid" ], "type": "module", "types": "dist/index.d.ts", "module": "dist/index.jsx", "exports": { ".": { "solid": { "types": "./dist/index.d.ts", "default": "./dist/index.jsx" }, "import": { "types": "./dist/index.d.ts", "default": "./dist/index.jsx" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:types": "tsc", "test:build": "publint --strict", "build": "tsc -p tsconfig.build.json" }, "dependencies": { "@tanstack/solid-store": "^0.9.2", "@tanstack/table-core": "workspace:*" }, "devDependencies": { "solid-js": "^1.9.11", "vite-plugin-solid": "^2.11.10" }, "peerDependencies": { "solid-js": ">=1.3" } } ================================================ FILE: packages/solid-table/src/FlexRender.tsx ================================================ import { Match, Switch, createComponent } from 'solid-js' import type { JSX } from 'solid-js' import type { Cell, CellData, Header, RowData, TableFeatures, } from '@tanstack/table-core' export function flexRender( Comp: ((_props: TProps) => JSX.Element) | JSX.Element | undefined, props: TProps, ): JSX.Element { if (!Comp) return null if (typeof Comp === 'function') { return createComponent(Comp, props as any) } return Comp } /** * Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. * Only one prop (`cell`, `header`, or `footer`) may be passed. * @example * @example * @example */ export type FlexRenderProps< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = | { cell: Cell; header?: never; footer?: never } | { header: Header cell?: never footer?: never } | { footer: Header cell?: never header?: never } /** * Simplified component wrapper of `flexRender`. Use this utility component to render headers, cells, or footers with custom markup. * Only one prop (`cell`, `header`, or `footer`) may be passed. * @example * ```tsx * * * * ``` * * This replaces calling `flexRender` directly like this: * ```tsx * flexRender(cell.column.columnDef.cell, cell.getContext()) * flexRender(header.column.columnDef.header, header.getContext()) * flexRender(footer.column.columnDef.footer, footer.getContext()) * ``` */ export function FlexRender< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(props: FlexRenderProps) { return ( {(cell) => flexRender(cell().column.columnDef.cell, cell().getContext()) } {(header) => flexRender(header().column.columnDef.header, header().getContext()) } {(footer) => flexRender(footer().column.columnDef.footer, footer().getContext()) } ) } ================================================ FILE: packages/solid-table/src/createTable.ts ================================================ import { constructReactivityFeature, constructTable, } from '@tanstack/table-core' import { useStore } from '@tanstack/solid-store' import { createComputed, createSignal, mergeProps } from 'solid-js' import type { Accessor, JSX } from 'solid-js' import type { NoInfer, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' export type SolidTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = Table & { /** * A Solid component that allows you to subscribe to the table state. * * This is useful for opting into state subscriptions for specific parts of the table state. * * @example * ({ rowSelection: state.rowSelection })}> * {(state) => ( * * // render the row * * )} * */ Subscribe: (props: { selector: (state: NoInfer>) => TSelected children: ((state: Accessor) => JSX.Element) | JSX.Element }) => JSX.Element /** * The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `createTable`. * * @example * const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state * * console.log(table.state().globalFilter) */ readonly state: Accessor> } export function createTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( tableOptions: TableOptions, selector: (state: TableState) => TSelected = () => ({}) as TSelected, ): SolidTable { const [notifier, setNotifier] = createSignal(void 0, { equals: false }) const solidReactivityFeature = constructReactivityFeature({ stateNotifier: () => notifier(), optionsNotifier: () => notifier(), }) const mergedOptions = mergeProps(tableOptions, { _features: mergeProps(tableOptions._features, { solidReactivityFeature, }), }) as any const resolvedOptions = mergeProps( { mergeOptions: ( defaultOptions: TableOptions, options: TableOptions, ) => { return mergeProps(defaultOptions, options) }, }, mergedOptions, ) as TableOptions const table = constructTable(resolvedOptions) as SolidTable< TFeatures, TData, TSelected > const allState = useStore(table.store, (state) => state) const allOptions = useStore(table.optionsStore, (options) => options) createComputed(() => { table.setOptions((prev) => { return mergeProps(prev, mergedOptions) as TableOptions }) }) createComputed(() => { allState() allOptions() setNotifier(void 0) }) table.Subscribe = function Subscribe(props: { selector: (state: TableState) => TSelected children: ((state: Accessor) => JSX.Element) | JSX.Element }) { const selected = useStore(table.store, props.selector) return typeof props.children === 'function' ? props.children(selected) : props.children } const state = useStore(table.store, selector) return { ...table, state, } as SolidTable } ================================================ FILE: packages/solid-table/src/createTableHook.tsx ================================================ import { createColumnHelper as coreCreateColumnHelper } from '@tanstack/table-core' import { Show, createContext, mergeProps, useContext } from 'solid-js' import { createTable } from './createTable' import { FlexRender } from './FlexRender' import type { SolidTable } from './createTable' import type { Accessor, Component, JSXElement } from 'solid-js' import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, Cell, CellContext, CellData, Column, ColumnDef, DeepKeys, DeepValue, DisplayColumnDef, GroupColumnDef, Header, IdentifiedColumnDef, NoInfer, Row, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' type ComponentType> = Component // ============================================================================= // Enhanced Context Types with Pre-bound Components // ============================================================================= /** * Enhanced CellContext with pre-bound cell components. * The `cell` property includes the registered cellComponents. */ export type AppCellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, > = { cell: Cell & TCellComponents & { FlexRender: () => JSXElement } column: Column getValue: CellContext['getValue'] renderValue: CellContext['renderValue'] row: Row table: Table } /** * Enhanced HeaderContext with pre-bound header components. * The `header` property includes the registered headerComponents. */ export type AppHeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, > = { column: Column header: Header & THeaderComponents & { FlexRender: () => JSXElement } table: Table } // ============================================================================= // Enhanced Column Definition Types // ============================================================================= /** * Template type for column definitions that can be a string or a function. */ type AppColumnDefTemplate = | string | ((props: TProps) => any) /** * Enhanced column definition base with pre-bound components in cell/header/footer contexts. */ type AppColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< IdentifiedColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced display column definition with pre-bound components. */ type AppDisplayColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< DisplayColumnDef, 'cell' | 'header' | 'footer' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > } /** * Enhanced group column definition with pre-bound components. */ type AppGroupColumnDef< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< GroupColumnDef, 'cell' | 'header' | 'footer' | 'columns' > & { cell?: AppColumnDefTemplate< AppCellContext > header?: AppColumnDefTemplate< AppHeaderContext > footer?: AppColumnDefTemplate< AppHeaderContext > columns?: Array> } // ============================================================================= // Enhanced Column Helper Type // ============================================================================= /** * Enhanced column helper with pre-bound components in cell/header/footer contexts. * This enables TypeScript to know about the registered components when defining columns. */ export type AppColumnHelper< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, THeaderComponents extends Record>, > = { /** * Creates a data column definition with an accessor key or function. * The cell, header, and footer contexts include pre-bound components. */ accessor: < TAccessor extends AccessorFn | DeepKeys, TValue extends TAccessor extends AccessorFn ? TReturn : TAccessor extends DeepKeys ? DeepValue : never, >( accessor: TAccessor, column: TAccessor extends AccessorFn ? AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents > & { id: string } : AppColumnDefBase< TFeatures, TData, TValue, TCellComponents, THeaderComponents >, ) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef /** * Wraps an array of column definitions to preserve each column's individual TValue type. */ columns: >>( columns: [...TColumns], ) => Array> & [...TColumns] /** * Creates a display column definition for non-data columns. * The cell, header, and footer contexts include pre-bound components. */ display: ( column: AppDisplayColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => DisplayColumnDef /** * Creates a group column definition with nested child columns. * The cell, header, and footer contexts include pre-bound components. */ group: ( column: AppGroupColumnDef< TFeatures, TData, TCellComponents, THeaderComponents >, ) => GroupColumnDef } // ============================================================================= // CreateTableHook Options and Props // ============================================================================= /** * Options for creating a table hook with pre-bound components and default table options. * Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'. */ export type CreateTableHookOptions< TFeatures extends TableFeatures, TTableComponents extends Record>, TCellComponents extends Record>, THeaderComponents extends Record>, > = Omit< TableOptions, 'columns' | 'data' | 'store' | 'state' | 'initialState' > & { /** * Table-level components that need access to the table instance. * These are available directly on the table object returned by createAppTable. * Use `useTableContext()` inside these components. * @example { PaginationControls, GlobalFilter, RowCount } */ tableComponents?: TTableComponents /** * Cell-level components that need access to the cell instance. * These are available on the cell object passed to AppCell's children. * Use `useCellContext()` inside these components. * @example { TextCell, NumberCell, DateCell, CurrencyCell } */ cellComponents?: TCellComponents /** * Header-level components that need access to the header instance. * These are available on the header object passed to AppHeader/AppFooter's children. * Use `useHeaderContext()` inside these components. * @example { SortIndicator, ColumnFilter, ResizeHandle } */ headerComponents?: THeaderComponents } /** * Props for AppTable component - without selector */ export interface AppTablePropsWithoutSelector { children: JSXElement selector?: never } /** * Props for AppTable component - with selector */ export interface AppTablePropsWithSelector< TFeatures extends TableFeatures, TSelected, > { children: (state: Accessor) => JSXElement selector: (state: TableState) => TSelected } /** * Props for AppCell component - without selector */ export interface AppCellPropsWithoutSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, > { cell: Cell children: ( cell: Cell & TCellComponents & { FlexRender: () => JSXElement }, ) => JSXElement selector?: never } /** * Props for AppCell component - with selector */ export interface AppCellPropsWithSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record>, TSelected, > { cell: Cell children: ( cell: Cell & TCellComponents & { FlexRender: () => JSXElement }, state: Accessor, ) => JSXElement selector: (state: TableState) => TSelected } /** * Props for AppHeader/AppFooter component - without selector */ export interface AppHeaderPropsWithoutSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, > { header: Header children: ( header: Header & THeaderComponents & { FlexRender: () => JSXElement }, ) => JSXElement selector?: never } /** * Props for AppHeader/AppFooter component - with selector */ export interface AppHeaderPropsWithSelector< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record>, TSelected, > { header: Header children: ( header: Header & THeaderComponents & { FlexRender: () => JSXElement }, state: Accessor, ) => JSXElement selector: (state: TableState) => TSelected } /** * Component type for AppCell - wraps a cell and provides cell context with optional Subscribe */ export interface AppCellComponent< TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record>, > { ( props: AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents >, ): JSXElement ( props: AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TSelected >, ): JSXElement } /** * Component type for AppHeader/AppFooter - wraps a header and provides header context with optional Subscribe */ export interface AppHeaderComponent< TFeatures extends TableFeatures, TData extends RowData, THeaderComponents extends Record>, > { ( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): JSXElement ( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TSelected >, ): JSXElement } /** * Component type for AppTable - root wrapper with optional Subscribe */ export interface AppTableComponent { (props: AppTablePropsWithoutSelector): JSXElement ( props: AppTablePropsWithSelector, ): JSXElement } /** * Extended table API returned by createAppTable with all App wrapper components */ export type AppSolidTable< TFeatures extends TableFeatures, TData extends RowData, TSelected, TTableComponents extends Record>, TCellComponents extends Record>, THeaderComponents extends Record>, > = SolidTable & NoInfer & { /** * Root wrapper component that provides table context with optional Subscribe. * @example * ```tsx * // Without selector - children is JSXElement * * ...
*
* * // With selector - children receives selected state * s.pagination}> * {(pagination) =>
Page {pagination.pageIndex}
} *
* ``` */ AppTable: AppTableComponent /** * Wraps a cell and provides cell context with pre-bound cellComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * // Without selector * * {(c) => } * * * // With selector - children receives cell and selected state * s.columnFilters}> * {(c, filters) => {filters.length}} * * ``` */ AppCell: AppCellComponent> /** * Wraps a header and provides header context with pre-bound headerComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * // Without selector * * {(h) => } * * * // With selector * s.sorting}> * {(h, sorting) => {sorting.length} sorted} * * ``` */ AppHeader: AppHeaderComponent> /** * Wraps a footer and provides header context with pre-bound headerComponents. * Optionally accepts a selector for Subscribe functionality. * @example * ```tsx * * {(f) => } * * ``` */ AppFooter: AppHeaderComponent> /** * Convenience FlexRender component attached to the table instance. * Renders cell, header, or footer content from column definitions. * @example * ```tsx * * * * ``` */ FlexRender: typeof FlexRender } /** * Creates a custom table hook with pre-bound components for composition. * * This is the table equivalent of TanStack Form's `createFormHook`. It allows you to: * - Define features, row models, and default options once, shared across all tables * - Register reusable table, cell, and header components * - Access table/cell/header instances via context in those components * - Get a `createAppTable` hook that returns an extended table with App wrapper components * - Get a `createAppColumnHelper` function pre-bound to your features * * @example * ```tsx * // hooks/table.ts * export const { * createAppTable, * createAppColumnHelper, * useTableContext, * useCellContext, * useHeaderContext, * } = createTableHook({ * _features: tableFeatures({ * rowPaginationFeature, * rowSortingFeature, * columnFilteringFeature, * }), * _rowModels: { * paginatedRowModel: createPaginatedRowModel(), * sortedRowModel: createSortedRowModel(sortFns), * filteredRowModel: createFilteredRowModel(filterFns), * }, * tableComponents: { PaginationControls, RowCount }, * cellComponents: { TextCell, NumberCell }, * headerComponents: { SortIndicator, ColumnFilter }, * }) * * // Create column helper with TFeatures already bound * const columnHelper = createAppColumnHelper() * * // components/table-components.tsx * function PaginationControls() { * const table = useTableContext() // TFeatures already known! * return s.pagination}>... * } * * // features/users.tsx * function UsersTable({ data }: { data: Person[] }) { * const table = createAppTable({ * columns, * data, // TData inferred from Person[] * }) * * return ( * * * * * {(headerGroup) => ( * * * {(h) => ( * * {(header) => ( * * )} * * )} * * * )} * * * * * {(row) => ( * * * {(c) => ( * * {(cell) => } * * )} * * * )} * * *
* * *
* *
* ) * } * ``` */ export function createTableHook< TFeatures extends TableFeatures, const TTableComponents extends Record>, const TCellComponents extends Record>, const THeaderComponents extends Record>, >({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableHookOptions< TFeatures, TTableComponents, TCellComponents, THeaderComponents >) { // Create contexts internally with TFeatures baked in const TableContext = createContext>( null as never, ) const CellContext = createContext>(null as never) const HeaderContext = createContext>( null as never, ) /** * Create a column helper pre-bound to the features and components configured in this table hook. * The cell, header, and footer contexts include pre-bound components (e.g., `cell.TextCell`). * @example * ```tsx * const columnHelper = createAppColumnHelper() * * const columns = [ * columnHelper.accessor('firstName', { * header: 'First Name', * cell: ({ cell }) => , // cell has pre-bound components! * }), * columnHelper.accessor('age', { * header: 'Age', * cell: ({ cell }) => , * }), * ] * ``` */ function createAppColumnHelper(): AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > { // The runtime implementation is the same - components are attached at render time // This cast provides the enhanced types for column definitions return coreCreateColumnHelper() as AppColumnHelper< TFeatures, TData, TCellComponents, THeaderComponents > } /** * Access the table instance from within an `AppTable` wrapper. * Use this in custom `tableComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function PaginationControls() { * const table = useTableContext() * return ( * s.pagination}> * {(pagination) => ( *
* * Page {pagination.pageIndex + 1} * *
* )} *
* ) * } * ``` */ function useTableContext(): SolidTable< TFeatures, TData > { const table = useContext(TableContext) if (!table) { throw new Error( '`useTableContext` must be used within an `AppTable` component. ' + 'Make sure your component is wrapped with `...`.', ) } return table } /** * Access the cell instance from within an `AppCell` wrapper. * Use this in custom `cellComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function TextCell() { * const cell = useCellContext() * return {cell.getValue()} * } * * function NumberCell({ format }: { format?: Intl.NumberFormatOptions }) { * const cell = useCellContext() * return {cell.getValue().toLocaleString(undefined, format)} * } * ``` */ function useCellContext(): Cell< TFeatures, any, TValue > { const cell = useContext(CellContext) if (!cell) { throw new Error( '`useCellContext` must be used within an `AppCell` component. ' + 'Make sure your component is wrapped with `...`.', ) } return cell } /** * Access the header instance from within an `AppHeader` or `AppFooter` wrapper. * Use this in custom `headerComponents` passed to `createTableHook`. * TFeatures is already known from the createTableHook call. * * @example * ```tsx * function SortIndicator() { * const header = useHeaderContext() * const sorted = header.column.getIsSorted() * return sorted === 'asc' ? '🔼' : sorted === 'desc' ? '🔽' : null * } * * function ColumnFilter() { * const header = useHeaderContext() * if (!header.column.getCanFilter()) return null * return ( * header.column.setFilterValue(e.target.value)} * placeholder="Filter..." * /> * ) * } * ``` */ function useHeaderContext(): Header< TFeatures, any, TValue > { const header = useContext(HeaderContext) if (!header) { throw new Error( '`useHeaderContext` must be used within an `AppHeader` or `AppFooter` component.', ) } return header } /** * Context-aware FlexRender component for cells. * Uses the cell from context, so no need to pass cell prop. */ function CellFlexRender() { const cell = useCellContext() return } /** * Context-aware FlexRender component for headers. * Uses the header from context, so no need to pass header prop. */ function HeaderFlexRender() { const header = useHeaderContext() return } /** * Context-aware FlexRender component for footers. * Uses the header from context, so no need to pass footer prop. */ function FooterFlexRender() { const header = useHeaderContext() return } /** * Enhanced useTable hook that returns a table with App wrapper components * and pre-bound tableComponents attached directly to the table object. * * Default options from createTableHook are automatically merged with * the options passed here. Options passed here take precedence. * * TFeatures is already known from the createTableHook call; TData is inferred from the data prop. */ function createAppTable( tableOptions: Omit< TableOptions, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ): AppSolidTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > { // Merge default options with provided options (provided takes precedence) const mergedProps = mergeProps(defaultTableOptions, tableOptions) const table = createTable( mergedProps as TableOptions, selector, ) // AppTable - Root wrapper that provides table context with optional state selector function AppTable(props: AppTablePropsWithoutSelector): JSXElement function AppTable( props: AppTablePropsWithSelector, ): JSXElement function AppTable( props: | AppTablePropsWithoutSelector | AppTablePropsWithSelector, ): JSXElement { return ( {(selector) => ( {(state: Accessor) => ( props.children as ( state: Accessor, ) => JSXElement )(state) } )} ) } // AppCell - Wraps cell with context, pre-bound cellComponents, and optional state selector function AppCell( props: AppCellPropsWithoutSelector< TFeatures, TData, TValue, TCellComponents >, ): JSXElement function AppCell< TValue extends CellData = CellData, TAppCellSelected = unknown, >( props: AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TAppCellSelected >, ): JSXElement function AppCell< TValue extends CellData = CellData, TAppCellSelected = unknown, >( props: | AppCellPropsWithoutSelector | AppCellPropsWithSelector< TFeatures, TData, TValue, TCellComponents, TAppCellSelected >, ): JSXElement { const extendedCell = Object.assign(props.cell, { FlexRender: CellFlexRender, ...cellComponents, }) as Cell & TCellComponents & { FlexRender: () => JSXElement } return ( JSXElement)( extendedCell as any, )} > {(selector) => ( {(state: Accessor) => props.children(extendedCell as any, state) } )} ) } // AppHeader - Wraps header with context, pre-bound headerComponents, and optional state selector function AppHeader( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): JSXElement function AppHeader< TValue extends CellData = CellData, TAppHeaderSelected = unknown, >( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppHeaderSelected >, ): JSXElement function AppHeader< TValue extends CellData = CellData, TAppHeaderSelected = unknown, >( props: | AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents > | AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppHeaderSelected >, ): JSXElement { const extendedHeader = Object.assign(props.header, { FlexRender: HeaderFlexRender, ...headerComponents, }) as Header & THeaderComponents & { FlexRender: () => JSXElement } return ( JSXElement)( extendedHeader as any, )} > {(selector) => ( {(state: Accessor) => props.children(extendedHeader as any, state) } )} ) } // AppFooter - Same as AppHeader but uses FooterFlexRender (footers use Header type) function AppFooter( props: AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents >, ): JSXElement function AppFooter< TValue extends CellData = CellData, TAppFooterSelected = unknown, >( props: AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppFooterSelected >, ): JSXElement function AppFooter< TValue extends CellData = CellData, TAppFooterSelected = unknown, >( props: | AppHeaderPropsWithoutSelector< TFeatures, TData, TValue, THeaderComponents > | AppHeaderPropsWithSelector< TFeatures, TData, TValue, THeaderComponents, TAppFooterSelected >, ): JSXElement { const extendedHeader = Object.assign(props.header, { FlexRender: FooterFlexRender, ...headerComponents, }) as Header & THeaderComponents & { FlexRender: () => JSXElement } return ( JSXElement)( extendedHeader as any, )} > {(selector) => ( {(state: Accessor) => props.children(extendedHeader as any, state) } )} ) } // Combine everything into the extended table API return Object.assign(table, { AppTable, AppCell, AppHeader, AppFooter, FlexRender, ...tableComponents, }) as AppSolidTable< TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents > } return { appFeatures: defaultTableOptions._features as TFeatures, createAppColumnHelper, createAppTable: createAppTable, useTableContext, useCellContext, useHeaderContext, } } ================================================ FILE: packages/solid-table/src/index.tsx ================================================ export * from '@tanstack/table-core' export * from './createTable' export * from './FlexRender' export * from './createTableHook' ================================================ FILE: packages/solid-table/tsconfig.build.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "preserve", "jsxImportSource": "solid-js", "rootDir": "src", "outDir": "dist", "noEmit": false, "declaration": true, "sourceMap": true }, "include": ["src"] } ================================================ FILE: packages/solid-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "preserve", "jsxImportSource": "solid-js" }, "include": ["src", "eslint.config.js", "vite.config.ts"] } ================================================ FILE: packages/solid-table/vite.config.ts ================================================ import { defineConfig } from 'vitest/config' import solid from 'vite-plugin-solid' export default defineConfig({ plugins: [solid()], }) ================================================ FILE: packages/solid-table-devtools/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [...rootConfig] export default config ================================================ FILE: packages/solid-table-devtools/package.json ================================================ { "name": "@tanstack/solid-table-devtools", "version": "9.0.0-alpha.11", "description": "Solid devtools for TanStack Table.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/react-table-devtools" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "solid", "tanstack", "table", "devtools" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:lib": "vitest --passWithNoTests", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "type": "module", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./production": { "import": { "types": "./dist/esm/production.d.ts", "default": "./dist/esm/production.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "dependencies": { "@tanstack/devtools-utils": "^0.3.2", "@tanstack/table-core": "workspace:*", "@tanstack/table-devtools": "workspace:*" }, "peerDependencies": { "solid-js": "^1.9.11" }, "devDependencies": { "vite-plugin-solid": "^2.11.10" } } ================================================ FILE: packages/solid-table-devtools/src/TableDevtools.tsx ================================================ import { createSolidPanel } from '@tanstack/devtools-utils/solid' import { TableDevtoolsCore, setTableDevtoolsTarget, } from '@tanstack/table-devtools' import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/solid' import type { RowData, Table, TableFeatures } from '@tanstack/table-core' export interface TableDevtoolsSolidInit< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, > extends DevtoolsPanelProps { table?: Table } const [TableDevtoolsPanelBase, TableDevtoolsPanelNoOp] = createSolidPanel(TableDevtoolsCore) function TableDevtoolsPanel(props: TableDevtoolsSolidInit) { setTableDevtoolsTarget(props.table) return } export { TableDevtoolsPanel, TableDevtoolsPanelNoOp } ================================================ FILE: packages/solid-table-devtools/src/index.ts ================================================ import { isDev } from 'solid-js/web' import * as plugin from './plugin' import * as Devtools from './TableDevtools' export const TableDevtoolsPanel = !isDev ? Devtools.TableDevtoolsPanelNoOp : Devtools.TableDevtoolsPanel export const tableDevtoolsPlugin = !isDev ? plugin.tableDevtoolsNoOpPlugin : plugin.tableDevtoolsPlugin export type { TableDevtoolsSolidInit } from './TableDevtools' export type { TableDevtoolsPluginOptions } from './plugin' ================================================ FILE: packages/solid-table-devtools/src/plugin.tsx ================================================ import { createSolidPlugin } from '@tanstack/devtools-utils/solid' import { TableDevtoolsPanel } from './TableDevtools' import type { RowData, Table, TableFeatures } from '@tanstack/table-core' export interface TableDevtoolsPluginOptions< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, > { table: Table } function tableDevtoolsPlugin< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, >(options: TableDevtoolsPluginOptions) { return { name: 'TanStack Table', render: (_el: HTMLElement, theme: 'light' | 'dark') => ( ), } } function tableDevtoolsNoOpPlugin< TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData, >(_options: TableDevtoolsPluginOptions) { return { name: 'TanStack Table', render: (_el: HTMLElement, _theme: 'light' | 'dark') => <>, } } export { tableDevtoolsPlugin, tableDevtoolsNoOpPlugin } ================================================ FILE: packages/solid-table-devtools/src/production/TableDevtools.tsx ================================================ import { createSolidPanel } from '@tanstack/devtools-utils/solid' import { TableDevtoolsCore } from '@tanstack/table-devtools/production' import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/solid' const [TableDevtoolsPanel] = createSolidPanel(TableDevtoolsCore) export interface TableDevtoolsSolidInit extends DevtoolsPanelProps {} export { TableDevtoolsPanel } ================================================ FILE: packages/solid-table-devtools/src/production/plugin.tsx ================================================ import { createSolidPlugin } from '@tanstack/devtools-utils/solid' import { TableDevtoolsPanel } from './TableDevtools' const [tableDevtoolsPlugin] = createSolidPlugin({ name: 'TanStack Table', Component: TableDevtoolsPanel, }) export { tableDevtoolsPlugin } ================================================ FILE: packages/solid-table-devtools/src/production.ts ================================================ export { TableDevtoolsPanel } from './TableDevtools' export type { TableDevtoolsSolidInit } from './production/TableDevtools' export { tableDevtoolsPlugin } from './production/plugin' ================================================ FILE: packages/solid-table-devtools/tsconfig.build.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "preserve", "jsxImportSource": "solid-js", "rootDir": "src", "outDir": "dist", "noEmit": false, "declaration": true, "sourceMap": true }, "include": ["src"] } ================================================ FILE: packages/solid-table-devtools/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "preserve", "jsxImportSource": "solid-js" }, "include": ["src", "eslint.config.js", "vite.config.ts", "tests"] } ================================================ FILE: packages/solid-table-devtools/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import solid from 'vite-plugin-solid' import packageJson from './package.json' const config = defineConfig({ plugins: [solid()], test: { name: packageJson.name, dir: './', watch: false, environment: 'jsdom', globals: true, }, }) export default mergeConfig( config, tanstackViteConfig({ entry: ['./src/index.ts', './src/production.ts'], srcDir: './src', cjs: false, }), ) ================================================ FILE: packages/svelte-table/eslint.config.js ================================================ // @ts-check import pluginSvelte from 'eslint-plugin-svelte' import rootConfig from '../../eslint.config.js' export default [ ...rootConfig, ...pluginSvelte.configs['flat/recommended'], { rules: { 'svelte/block-lang': ['error', { script: ['ts'] }], 'svelte/no-svelte-internal': 'error', 'svelte/valid-compile': 'off', }, }, ] ================================================ FILE: packages/svelte-table/package.json ================================================ { "name": "@tanstack/svelte-table", "version": "9.0.0-alpha.10", "description": "Headless UI for building powerful tables & datagrids for Svelte.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/svelte-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "svelte", "table", "svelte-table", "datagrid" ], "type": "module", "types": "dist/index.d.ts", "module": "dist/index.js", "svelte": "./dist/index.js", "exports": { ".": { "types": "./dist/index.d.ts", "svelte": "./dist/index.js", "import": "./dist/index.js" }, "./package.json": "./package.json" }, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:types": "svelte-check --tsconfig ./tsconfig.json", "test:build": "publint --strict", "build": "svelte-package --input ./src --output ./dist" }, "dependencies": { "@tanstack/svelte-store": "^0.10.1", "@tanstack/table-core": "workspace:*" }, "devDependencies": { "@sveltejs/package": "^2.5.7", "@sveltejs/vite-plugin-svelte": "^6.2.4", "eslint-plugin-svelte": "^3.14.0", "svelte": "^5.48.5", "svelte-check": "^4.3.5" }, "peerDependencies": { "svelte": "^5.0.0" } } ================================================ FILE: packages/svelte-table/src/FlexRender.svelte ================================================ {#if typeof content === 'string'} {content} {:else if isFunction(content)} {@const result = content(context as any)} {#if result instanceof RenderComponentConfig} {@const { component: Component, props } = result} {:else if result instanceof RenderSnippetConfig} {@const { snippet, params } = result} {@render snippet(params)} {:else} {result} {/if} {/if} ================================================ FILE: packages/svelte-table/src/Subscribe.svelte ================================================ {@render props.children(selectedState.current)} ================================================ FILE: packages/svelte-table/src/createTable.svelte.ts ================================================ import { constructTable } from '@tanstack/table-core' import { useStore } from '@tanstack/svelte-store' import type { NoInfer, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { Snippet } from 'svelte' export type SvelteTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = Table & { /** * A Svelte component that allows you to subscribe to the table state. * * This is useful for opting into state subscriptions for specific parts of the table state. * * @example * ({ rowSelection: state.rowSelection })}> * {(state) => ( * * // render the row * * )} * */ Subscribe: (props: { selector: (state: NoInfer>) => TSelected children: ((state: Readonly) => Snippet) | Snippet }) => any /** * The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `createTable`. * * @example * const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state * * console.log(table.state.globalFilter) */ readonly state: Readonly } export function createTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( tableOptions: TableOptions, selector: (state: TableState) => TSelected = () => ({}) as TSelected, ): SvelteTable { const statefulOptions: TableOptions = mergeObjects( tableOptions, { // Remove state and onStateChange - store handles it internally mergeOptions: ( defaultOptions: TableOptions, newOptions: Partial>, ) => { return mergeObjects(defaultOptions, newOptions) }, }, ) const table = constructTable(statefulOptions) as SvelteTable< TFeatures, TData, TSelected > function updateOptions() { table.setOptions((prev) => { return mergeObjects(prev, tableOptions) }) } updateOptions() /** * Temp force reactivity to all state changes on every table.get* method */ const allState = useStore(table.store, (state) => state) // Wrap all "get*" methods to make them reactive // Access allState.current directly to create reactive dependency Object.keys(table).forEach((key) => { const value = (table as any)[key] if (typeof value === 'function' && key.startsWith('get')) { const originalMethod = value.bind(table) ;(table as any)[key] = (...args: Array) => { // Access state to create reactive dependency allState.current return originalMethod(...args) } } }) table.Subscribe = function Subscribe(props: { selector: (state: TableState) => TSelected children: ((state: Readonly) => Snippet) | Snippet }): any { const selected = useStore(table.store, props.selector) if (typeof props.children === 'function') { return props.children(selected.current) } return props.children } const stateStore = useStore(table.store, selector) return { ...table, get state() { return stateStore.current }, } as SvelteTable } /** * Merges objects together while keeping their getters alive. * Taken from SolidJS: {https://github.com/solidjs/solid/blob/24abc825c0996fd2bc8c1de1491efe9a7e743aff/packages/solid/src/server/rendering.ts#L82-L115} * */ function mergeObjects(source: T): T function mergeObjects(source: T, source1: U): T & U function mergeObjects(source: T, source1: U, source2: V): T & U & V function mergeObjects( source: T, source1: U, source2: V, source3: W, ): T & U & V & W function mergeObjects(...sources: any): any { const target = {} for (let source of sources) { if (typeof source === 'function') source = source() if (source) { const descriptors = Object.getOwnPropertyDescriptors(source) for (const key in descriptors) { if (key in target) continue Object.defineProperty(target, key, { enumerable: true, get() { for (let i = sources.length - 1; i >= 0; i--) { let v, s = sources[i] if (typeof s === 'function') s = s() // eslint-disable-next-line prefer-const v = (s || {})[key] if (v !== undefined) return v } }, }) } } } return target } ================================================ FILE: packages/svelte-table/src/createTableHelper.ts ================================================ import { constructTableHelper } from '@tanstack/table-core' import { createTable } from './createTable.svelte' import type { RowData, Table, TableFeatures, TableHelperOptions, TableHelper_Core, TableOptions, } from '@tanstack/table-core' export type TableHelper< TFeatures extends TableFeatures, TData extends RowData = any, > = Omit, 'tableCreator'> & { createTable: ( tableOptions: Omit< TableOptions, '_features' | '_rowModels' >, ) => Table } export function createTableHelper< TFeatures extends TableFeatures, TData extends RowData = any, >( tableHelperOptions: TableHelperOptions, ): TableHelper { const tableHelper = constructTableHelper(createTable, tableHelperOptions) return { ...tableHelper, createTable: tableHelper.tableCreator, } as any } // test // type Person = { // firstName: string // lastName: string // age: number // } // const tableHelper = createTableHelper({ // _features: { rowSelectionFeature: {} }, // TData: {} as Person, // }) // const columns = [ // tableHelper.columnHelper.accessor('firstName', { header: 'First Name' }), // tableHelper.columnHelper.accessor('lastName', { header: 'Last Name' }), // tableHelper.columnHelper.accessor('age', { header: 'Age' }), // tableHelper.columnHelper.display({ header: 'Actions', id: 'actions' }), // ] as Array> // const data: Array = [] // tableHelper.createTable({ // columns, // data, // }) ================================================ FILE: packages/svelte-table/src/createTableState.svelte.ts ================================================ import type { Updater } from '@tanstack/table-core' export function createTableState( initialValue: TState, ): [() => TState, (updater: Updater) => void] { let value = $state(initialValue) return [ () => value, (updater: Updater) => { if (updater instanceof Function) value = updater(value) else value = updater }, ] } ================================================ FILE: packages/svelte-table/src/global.d.ts ================================================ /// ================================================ FILE: packages/svelte-table/src/index.ts ================================================ export * from '@tanstack/table-core' export { createTable } from './createTable.svelte' export { createTableHelper, type TableHelper } from './createTableHelper' export { createTableState } from './createTableState.svelte' export { default as FlexRender } from './FlexRender.svelte' export { default as Subscribe } from './Subscribe.svelte' export { renderComponent, renderSnippet } from './render-component' ================================================ FILE: packages/svelte-table/src/render-component.ts ================================================ import type { Component, ComponentProps, Snippet } from 'svelte' /** * A helper class to make it easy to identify Svelte components in * `columnDef.cell` and `columnDef.header` properties. * * > NOTE: This class should only be used internally by the adapter. If you're * reading this and you don't know what this is for, you probably don't need it. * * @example * ```svelte * {@const result = content(context as any)} * {#if result instanceof RenderComponentConfig} * {@const { component: Component, props } = result} * * {/if} * ``` * */ export class RenderComponentConfig { constructor( public component: TComponent, public props: ComponentProps | Record = {}, ) {} } /** * A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties. * * > NOTE: This class should only be used internally by the adapter. If you're * reading this and you don't know what this is for, you probably don't need it. * * @example * ```svelte * {@const result = content(context as any)} * {#if result instanceof RenderSnippetConfig} * {@const { snippet, params } = result} * {@render snippet(params)} * {/if} * ``` * */ export class RenderSnippetConfig { constructor( public snippet: Snippet<[TProps]>, public params: TProps, ) {} } /** * A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties. * * This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets. * * @param component A Svelte component * @param props The props to pass to `component` * @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component. * @example * ```ts * // +page.svelte * const defaultColumns = [ * columnHelper.accessor('name', { * header: header => renderComponent(SortHeader, { label: 'Name', header }), * }), * columnHelper.accessor('state', { * header: header => renderComponent(SortHeader, { label: 'State', header }), * }), * ] * ``` * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} */ export const renderComponent = < TComponent extends Component, TProps extends ComponentProps, >( component: TComponent, props: TProps, ) => new RenderComponentConfig(component, props) /** * A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties. * * *The snippet must only take one parameter.* * * This is only to be used with Snippets - use `renderComponent` for Svelte Components. * * @param snippet * @param params * @returns * @example * ```ts * // +page.svelte * const defaultColumns = [ * columnHelper.accessor('name', { * cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }), * }), * columnHelper.accessor('state', { * cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }), * }), * ] * ``` * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} */ export const renderSnippet = ( snippet: Snippet<[TProps]>, params: TProps, ) => new RenderSnippetConfig(snippet, params) ================================================ FILE: packages/svelte-table/svelte.config.js ================================================ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' const config = { preprocess: vitePreprocess(), } export default config ================================================ FILE: packages/svelte-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "rootDir": "./src", "outDir": "./build/lib" }, "include": ["src"] } ================================================ FILE: packages/svelte-table/vite.config.ts ================================================ import { svelte } from '@sveltejs/vite-plugin-svelte' import { defineConfig } from 'vitest/config' export default defineConfig({ plugins: [svelte()], }) ================================================ FILE: packages/table-core/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [ ...rootConfig, { rules: {}, }, ] export default config ================================================ FILE: packages/table-core/package.json ================================================ { "name": "@tanstack/table-core", "version": "9.0.0-alpha.16", "description": "Headless UI for building powerful tables & datagrids for TS/JS.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/table-core" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "react", "vue", "solid", "svelte", "lit", "angular", "table", "table-core", "datagrid" ], "type": "module", "types": "dist/esm/index.d.ts", "main": "dist/esm/index.js", "module": "dist/esm/index.js", "exports": { ".": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist/", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "lint:fix": "eslint ./src --fix", "test:eslint": "eslint ./src", "test:lib": "vitest", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "dependencies": { "@tanstack/store": "^0.9.2" } } ================================================ FILE: packages/table-core/src/core/cells/constructCell.ts ================================================ import type { Table_Internal } from '../../types/Table' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' import type { Cell } from '../../types/Cell' import type { Column } from '../../types/Column' import type { Cell_CoreProperties } from './coreCellsFeature.types' /** * Creates or retrieves the cell prototype for a table. * The prototype is cached on the table and shared by all cell instances. */ function getCellPrototype< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): object { if (!table._cellPrototype) { table._cellPrototype = { table } for (const feature of Object.values(table._features)) { feature.assignCellPrototype?.(table._cellPrototype, table) } } return table._cellPrototype } export function constructCell< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column, row: Row, table: Table_Internal, ): Cell { // Create cell with shared prototype for memory efficiency const cellPrototype = getCellPrototype(table) const cell = Object.create(cellPrototype) as Cell_CoreProperties< TFeatures, TData, TValue > // Only assign instance-specific properties cell.column = column cell.id = `${row.id}_${column.id}` cell.row = row return cell as Cell } ================================================ FILE: packages/table-core/src/core/cells/coreCellsFeature.ts ================================================ import { assignPrototypeAPIs } from '../../utils' import { cell_getContext, cell_getValue, cell_renderValue, } from './coreCellsFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { Cell_Cell, TableOptions_Cell } from './coreCellsFeature.types' interface CoreCellsFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Cell: Cell_Cell // TableOptions: TableOptions_Cell } export function constructCoreCellsFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { assignCellPrototype: (prototype, table) => { assignPrototypeAPIs('coreCellsFeature', prototype, table, { cell_getValue: { fn: (cell) => cell_getValue(cell), }, cell_renderValue: { fn: (cell) => cell_renderValue(cell), }, cell_getContext: { fn: (cell) => cell_getContext(cell), memoDeps: (cell) => [cell], }, }) }, } } /** * The Core Cells feature provides the core cell functionality. */ export const coreCellsFeature = constructCoreCellsFeature() ================================================ FILE: packages/table-core/src/core/cells/coreCellsFeature.types.ts ================================================ import type { CellData, Getter, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table, Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { Cell } from '../../types/Cell' import type { Column } from '../../types/Column' export interface CellContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { cell: Cell column: Column getValue: Getter renderValue: Getter row: Row table: Table } export interface Cell_CoreProperties< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { /** * The associated Column object for the cell. */ column: Column /** * The unique ID for the cell across the entire table. */ id: string /** * The associated Row object for the cell. */ row: Row /** * Reference to the parent table instance. */ table: Table_Internal } export interface Cell_Cell< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > extends Cell_CoreProperties { /** * Returns the rendering context (or props) for cell-based components like cells and aggregated cells. Use these props with your framework's `flexRender` utility to render these using the template of your choice: */ getContext: () => CellContext /** * Returns the value for the cell, accessed via the associated column's accessor key or accessor function. */ getValue: CellContext['getValue'] /** * Renders the value for a cell the same as `getValue`, but will return the `renderFallbackValue` if no value is found. */ renderValue: CellContext['renderValue'] } export interface TableOptions_Cell { /** * Value used when the desired value is not found in the data. */ renderFallbackValue?: any } ================================================ FILE: packages/table-core/src/core/cells/coreCellsFeature.utils.ts ================================================ import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Cell } from '../../types/Cell' export function cell_getValue< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(cell: Cell): TValue { return cell.row.getValue(cell.column.id) } export function cell_renderValue< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(cell: Cell) { return cell.getValue() ?? cell.table.options.renderFallbackValue } export function cell_getContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(cell: Cell) { return { table: cell.table, column: cell.column, row: cell.row, cell: cell, // Wrap in arrow functions to preserve `this` binding (methods are on prototype) getValue: () => cell.getValue(), renderValue: () => cell.renderValue(), } } ================================================ FILE: packages/table-core/src/core/columns/constructColumn.ts ================================================ import {} from '../../utils' import type { Table_Internal } from '../../types/Table' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { AccessorFn, ColumnDef, ColumnDefResolved, } from '../../types/ColumnDef' import type { Column } from '../../types/Column' import type { Column_CoreProperties } from './coreColumnsFeature.types' /** * Creates or retrieves the column prototype for a table. * The prototype is cached on the table and shared by all column instances. */ function getColumnPrototype< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): object { if (!table._columnPrototype) { table._columnPrototype = { table } for (const feature of Object.values(table._features)) { feature.assignColumnPrototype?.(table._columnPrototype, table) } } return table._columnPrototype } export function constructColumn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( table: Table_Internal, columnDef: ColumnDef, depth: number, parent?: Column, ): Column { const defaultColumn = table.getDefaultColumnDef() const resolvedColumnDef = { ...defaultColumn, ...columnDef, } as ColumnDefResolved<{}, TData, TValue> const accessorKey = resolvedColumnDef.accessorKey const id = resolvedColumnDef.id ?? (accessorKey ? accessorKey.replaceAll('.', '_') : undefined) ?? (typeof resolvedColumnDef.header === 'string' ? resolvedColumnDef.header : undefined) let accessorFn: AccessorFn | undefined if (resolvedColumnDef.accessorFn) { accessorFn = resolvedColumnDef.accessorFn } else if (accessorKey) { // Support deep accessor keys if (accessorKey.includes('.')) { accessorFn = (originalRow: TData) => { let result = originalRow as Record | undefined for (const key of accessorKey.split('.')) { result = result?.[key] if (process.env.NODE_ENV === 'development' && result === undefined) { console.warn( `"${key}" in deeply nested key "${accessorKey}" returned undefined.`, ) } } return result as TValue } } else { accessorFn = (originalRow: TData) => (originalRow as any)[resolvedColumnDef.accessorKey] } } if (!id) { if (process.env.NODE_ENV === 'development') { throw new Error( resolvedColumnDef.accessorFn ? `coreColumnsFeature require an id when using an accessorFn` : `coreColumnsFeature require an id when using a non-string header`, ) } throw new Error() } // Create column with shared prototype for memory efficiency const columnPrototype = getColumnPrototype(table) const column = Object.create(columnPrototype) as Column_CoreProperties< TFeatures, TData, TValue > // Only assign instance-specific properties column.accessorFn = accessorFn column.columnDef = resolvedColumnDef as ColumnDef column.columns = [] column.depth = depth column.id = `${String(id)}` column.parent = parent return column as Column } ================================================ FILE: packages/table-core/src/core/columns/coreColumnsFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs } from '../../utils' import { column_getFlatColumns, column_getLeafColumns, table_getAllColumns, table_getAllFlatColumns, table_getAllFlatColumnsById, table_getAllLeafColumns, table_getColumn, table_getDefaultColumnDef, } from './coreColumnsFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // Column_Column, // TableOptions_Columns, // Table_Columns, // } from './coreColumnsFeature.types' interface CoreColumnsFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Column: Column_Column // Table: Table_Columns // TableOptions: TableOptions_Columns } export function constructCoreColumnsFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('coreColumnsFeature', prototype, table, { column_getFlatColumns: { fn: (column) => column_getFlatColumns(column), memoDeps: (column) => [column.table.options.columns], }, column_getLeafColumns: { fn: (column) => column_getLeafColumns(column), memoDeps: (column) => [ column.table.store.state.columnOrder, column.table.store.state.grouping, column.table.options.columns, column.table.options.groupedColumnMode, ], }, }) }, constructTableAPIs: (table) => { assignTableAPIs('coreColumnsFeature', table, { table_getDefaultColumnDef: { fn: () => table_getDefaultColumnDef(table), memoDeps: () => [table.options.defaultColumn], }, table_getAllColumns: { fn: () => table_getAllColumns(table), memoDeps: () => [table.options.columns], }, table_getAllFlatColumns: { fn: () => table_getAllFlatColumns(table), memoDeps: () => [table.options.columns], }, table_getAllFlatColumnsById: { fn: () => table_getAllFlatColumnsById(table), memoDeps: () => [table.options.columns], }, table_getAllLeafColumns: { fn: () => table_getAllLeafColumns(table), memoDeps: () => [ table.store.state.columnOrder, table.store.state.grouping, table.options.columns, table.options.groupedColumnMode, ], }, table_getColumn: { fn: (columnId) => table_getColumn(table, columnId), }, }) }, } } /** * The Core Columns feature provides the core column functionality. */ export const coreColumnsFeature = constructCoreColumnsFeature() ================================================ FILE: packages/table-core/src/core/columns/coreColumnsFeature.types.ts ================================================ import type { Table_Internal } from '../../types/Table' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { AccessorFn, ColumnDef } from '../../types/ColumnDef' import type { Column } from '../../types/Column' export interface Column_CoreProperties< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { /** * The resolved accessor function to use when extracting the value for the column from each row. Will only be defined if the column def has a valid accessor key or function defined. */ accessorFn?: AccessorFn /** * The original column def used to create the column. */ columnDef: ColumnDef /** * The child column (if the column is a group column). Will be an empty array if the column is not a group column. */ columns: Array> /** * The depth of the column (if grouped) relative to the root column def array. */ depth: number /** * The resolved unique identifier for the column resolved in this priority: - A manual `id` property from the column def - The accessor key from the column def - The header string from the column def */ id: string /** * The parent column for this column. Will be undefined if this is a root column. */ parent?: Column /** * Reference to the parent table instance. */ table: Table_Internal } export interface Column_Column< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > extends Column_CoreProperties { /** * Returns the flattened array of this column and all child/grand-child columns for this column. */ getFlatColumns: () => Array> /** * Returns an array of all leaf-node columns for this column. If a column has no children, it is considered the only leaf-node column. */ getLeafColumns: () => Array> } export interface TableOptions_Columns< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { /** * The array of column defs to use for the table. */ columns: ReadonlyArray> /** * Default column options to use for all column defs supplied to the table. */ defaultColumn?: Partial> } export interface Table_Columns< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns a map of all flat columns by their ID. */ getAllFlatColumnsById: () => Record> /** * Returns the default column options to use for all column defs supplied to the table. */ getDefaultColumnDef: () => Partial> /** * Returns all columns in the table in their normalized and nested hierarchy. */ getAllColumns: () => Array> /** * Returns all columns in the table flattened to a single level. */ getAllFlatColumns: () => Array> /** * Returns all leaf-node columns in the table flattened to a single level. This does not include parent columns. */ getAllLeafColumns: () => Array> /** * Returns a single column by its ID. */ getColumn: (columnId: string) => Column | undefined } ================================================ FILE: packages/table-core/src/core/columns/coreColumnsFeature.utils.ts ================================================ import { callMemoOrStaticFn } from '../../utils' import { table_getOrderColumnsFn } from '../../features/column-ordering/columnOrderingFeature.utils' import { constructColumn } from './constructColumn' import type { Table_Internal } from '../../types/Table' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { ColumnDef, ColumnDefResolved, GroupColumnDef, } from '../../types/ColumnDef' import type { Column } from '../../types/Column' export function column_getFlatColumns< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column, ): Array> { return [column, ...column.columns.flatMap((col) => col.getFlatColumns())] } export function column_getLeafColumns< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column, ): Array> { if (column.columns.length) { const leafColumns = column.columns.flatMap( (col) => col.getLeafColumns(), // recursive ) return callMemoOrStaticFn( column.table, 'getOrderColumns', table_getOrderColumnsFn, )(leafColumns as any) as any } return [column] } export function table_getDefaultColumnDef< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): Partial> { return { header: (props) => { const resolvedColumnDef = props.header.column .columnDef as ColumnDefResolved<{}, TData> if (resolvedColumnDef.accessorKey) { return resolvedColumnDef.accessorKey } if (resolvedColumnDef.accessorFn) { return resolvedColumnDef.id } return null }, cell: (props) => props.renderValue()?.toString?.() ?? null, ...Object.values(table._features).reduce((obj, feature) => { return Object.assign(obj, feature.getDefaultColumnDef?.()) }, {}), ...table.options.defaultColumn, } as Partial> } export function table_getAllColumns< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): Array> { const recurseColumns = ( colDefs: ReadonlyArray>, parent?: Column, depth = 0, ): Array> => { return colDefs.map((columnDef) => { const column = constructColumn(table, columnDef, depth, parent) const groupingColumnDef = columnDef as GroupColumnDef< TFeatures, TData, unknown > column.columns = groupingColumnDef.columns ? recurseColumns(groupingColumnDef.columns, column, depth + 1) : [] return column }) } return recurseColumns(table.options.columns as any) } export function table_getAllFlatColumns< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): Array> { return table.getAllColumns().flatMap((column) => column.getFlatColumns()) } export function table_getAllFlatColumnsById< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): Record> { return table.getAllFlatColumns().reduce( (acc, column) => { acc[column.id] = column return acc }, {} as Record>, ) } export function table_getAllLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): Array> { const leafColumns = table.getAllColumns().flatMap( (c) => c.getLeafColumns(), // recursive ) return callMemoOrStaticFn( table, 'getOrderColumns', table_getOrderColumnsFn, )(leafColumns as any) as any } export function table_getColumn< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, columnId: string, ): Column | undefined { const column = table.getAllFlatColumnsById()[columnId] if (process.env.NODE_ENV === 'development' && !column) { console.warn(`[Table] Column with id '${columnId}' does not exist.`) } return column } ================================================ FILE: packages/table-core/src/core/coreFeatures.ts ================================================ import { coreCellsFeature } from './cells/coreCellsFeature' import { coreColumnsFeature } from './columns/coreColumnsFeature' import { coreHeadersFeature } from './headers/coreHeadersFeature' import { coreRowModelsFeature } from './row-models/coreRowModelsFeature' import { coreRowsFeature } from './rows/coreRowsFeature' import { coreTablesFeature } from './table/coreTablesFeature' export interface CoreFeatures { coreCellsFeature: typeof coreCellsFeature coreColumnsFeature: typeof coreColumnsFeature coreHeadersFeature: typeof coreHeadersFeature coreRowModelsFeature: typeof coreRowModelsFeature coreRowsFeature: typeof coreRowsFeature coreTablesFeature: typeof coreTablesFeature } export const coreFeatures: CoreFeatures = { coreCellsFeature, coreColumnsFeature, coreHeadersFeature, coreRowModelsFeature, coreRowsFeature, coreTablesFeature, } ================================================ FILE: packages/table-core/src/core/headers/buildHeaderGroups.ts ================================================ import { callMemoOrStaticFn } from '../../utils' import { column_getIsVisible } from '../../features/column-visibility/columnVisibilityFeature.utils' import { constructHeader } from './constructHeader' import type { Table_Internal } from '../../types/Table' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Header } from '../../types/Header' import type { HeaderGroup } from '../../types/HeaderGroup' import type { Column } from '../../types/Column' export function buildHeaderGroups< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( allColumns: Array>, columnsToGroup: Array>, table: Table_Internal, headerFamily?: 'center' | 'left' | 'right', ) { // Find the max depth of the columns: // build the leaf column row // build each buffer row going up // placeholder for non-existent level // real column for existing level let maxDepth = 0 const findMaxDepth = ( columns: Array>, depth = 1, ) => { maxDepth = Math.max(maxDepth, depth) columns .filter((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) .forEach((column) => { if (column.columns.length) { findMaxDepth(column.columns, depth + 1) } }, 0) } findMaxDepth(allColumns) const headerGroups: Array> = [] const constructHeaderGroup = ( headersToGroup: Array>, depth: number, ) => { // The header group we are creating const headerGroup: HeaderGroup = { depth, id: [headerFamily, `${depth}`].filter(Boolean).join('_'), headers: [], } as any // The parent columns we're going to scan next const pendingParentHeaders: Array> = [] // Scan each column for parents headersToGroup.forEach((headerToGroup) => { // What is the latest (last) parent column? const latestPendingParentHeader = [...pendingParentHeaders].reverse()[0] const isLeafHeader = headerToGroup.column.depth === headerGroup.depth let column: Column let isPlaceholder = false if (isLeafHeader && headerToGroup.column.parent) { // The parent header is new column = headerToGroup.column.parent } else { // The parent header is repeated column = headerToGroup.column isPlaceholder = true } if ( latestPendingParentHeader && latestPendingParentHeader.column === column ) { // This column is repeated. Add it as a sub header to the next batch latestPendingParentHeader.subHeaders.push(headerToGroup) } else { // This is a new header. Let's create it const header = constructHeader(table, column, { id: [headerFamily, depth, column.id, headerToGroup.id] .filter(Boolean) .join('_'), isPlaceholder, placeholderId: isPlaceholder ? `${pendingParentHeaders.filter((d) => d.column === column).length}` : undefined, depth, index: pendingParentHeaders.length, }) // Add the headerToGroup as a subHeader of the new header header.subHeaders.push(headerToGroup) // Add the new header to the pendingParentHeaders to get grouped // in the next batch pendingParentHeaders.push(header) } headerGroup.headers.push(headerToGroup) headerToGroup.headerGroup = headerGroup }) headerGroups.push(headerGroup) if (depth > 0) { constructHeaderGroup(pendingParentHeaders, depth - 1) } } const bottomHeaders = columnsToGroup.map((column, index) => constructHeader(table, column, { depth: maxDepth, index, }), ) constructHeaderGroup(bottomHeaders, maxDepth - 1) headerGroups.reverse() // headerGroups = headerGroups.filter(headerGroup => { // return !headerGroup.headers.every(header => header.isPlaceholder) // }) const recurseHeadersForSpans = ( headers: Array>, ): Array<{ colSpan: number; rowSpan: number }> => { const filteredHeaders = headers.filter((header) => callMemoOrStaticFn(header.column, 'getIsVisible', column_getIsVisible), ) return filteredHeaders.map((header) => { let colSpan = 0 let rowSpan = 0 let childRowSpans = [0] if (header.subHeaders.length) { childRowSpans = [] recurseHeadersForSpans(header.subHeaders).forEach( ({ colSpan: childColSpan, rowSpan: childRowSpan }) => { colSpan += childColSpan childRowSpans.push(childRowSpan) }, ) } else { colSpan = 1 } const minChildRowSpan = Math.min(...childRowSpans) rowSpan = rowSpan + minChildRowSpan header.colSpan = colSpan header.rowSpan = rowSpan return { colSpan, rowSpan } }) } recurseHeadersForSpans( (headerGroups[0]?.headers ?? []) as Array>, ) return headerGroups } ================================================ FILE: packages/table-core/src/core/headers/constructHeader.ts ================================================ import type { Table_Internal } from '../../types/Table' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Header } from '../../types/Header' import type { Column } from '../../types/Column' import type { Header_CoreProperties } from './coreHeadersFeature.types' /** * Creates or retrieves the header prototype for a table. * The prototype is cached on the table and shared by all header instances. */ function getHeaderPrototype< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): object { if (!table._headerPrototype) { table._headerPrototype = { table } for (const feature of Object.values(table._features)) { feature.assignHeaderPrototype?.(table._headerPrototype, table) } } return table._headerPrototype } export function constructHeader< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( table: Table_Internal, column: Column, options: { id?: string isPlaceholder?: boolean placeholderId?: string index: number depth: number }, ): Header { // Create header with shared prototype for memory efficiency const headerPrototype = getHeaderPrototype(table) const header = Object.create(headerPrototype) as Header_CoreProperties< TFeatures, TData, TValue > // Only assign instance-specific properties header.colSpan = 0 header.column = column header.depth = options.depth header.headerGroup = null header.id = options.id ?? column.id header.index = options.index header.isPlaceholder = !!options.isPlaceholder header.placeholderId = options.placeholderId header.rowSpan = 0 header.subHeaders = [] return header as Header } ================================================ FILE: packages/table-core/src/core/headers/coreHeadersFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, } from '../../utils' import { table_getCenterHeaderGroups, table_getLeftHeaderGroups, table_getRightHeaderGroups, } from '../../features/column-pinning/columnPinningFeature.utils' import { header_getContext, header_getLeafHeaders, table_getFlatHeaders, table_getFooterGroups, table_getHeaderGroups, table_getLeafHeaders, } from './coreHeadersFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { Header_Header, Table_Headers } from './coreHeadersFeature.types' interface CoreHeadersFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Header: Header_Header // Table: Table_Headers } export function constructCoreHeadersFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { assignHeaderPrototype: (prototype, table) => { assignPrototypeAPIs('coreHeadersFeature', prototype, table, { header_getLeafHeaders: { fn: (header) => header_getLeafHeaders(header), memoDeps: (header) => [header.column.table.options.columns], }, header_getContext: { fn: (header) => header_getContext(header), memoDeps: (header) => [header.column.table.options.columns], }, }) }, constructTableAPIs: (table) => { assignTableAPIs('coreHeadersFeature', table, { table_getHeaderGroups: { fn: () => table_getHeaderGroups(table), memoDeps: () => [ table.options.columns, table.store.state.columnOrder, table.store.state.grouping, table.store.state.columnPinning, table.store.state.columnVisibility, table.options.groupedColumnMode, ], }, table_getFooterGroups: { fn: () => table_getFooterGroups(table), memoDeps: () => [table.getHeaderGroups()], }, table_getFlatHeaders: { fn: () => table_getFlatHeaders(table), memoDeps: () => [table.getHeaderGroups()], }, table_getLeafHeaders: { fn: () => table_getLeafHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ), callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ), callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ), ], }, }) }, } } /** * The Core Headers feature provides the core header functionality. */ export const coreHeadersFeature = constructCoreHeadersFeature() ================================================ FILE: packages/table-core/src/core/headers/coreHeadersFeature.types.ts ================================================ import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table } from '../../types/Table' import type { Header } from '../../types/Header' import type { HeaderGroup } from '../../types/HeaderGroup' import type { Column } from '../../types/Column' export interface Table_Headers< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns all header groups for the table. */ getHeaderGroups: () => Array> /** * Returns the footer groups for the table. */ getFooterGroups: () => Array> /** * Returns headers for all columns in the table, including parent headers. */ getFlatHeaders: () => Array> /** * Returns headers for all leaf columns in the table, (not including parent headers). */ getLeafHeaders: () => Array> } export interface HeaderContext< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { /** * An instance of a column. */ column: Column /** * An instance of a header. */ header: Header /** * The table instance. */ table: Table } export interface Header_CoreProperties< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { /** * The col-span for the header. */ colSpan: number /** * The header's associated column object. */ column: Column /** * The depth of the header, zero-indexed based. */ depth: number /** * The header's associated header group object. */ headerGroup: HeaderGroup | null /** * The unique identifier for the header. */ id: string /** * The index for the header within the header group. */ index: number /** * A boolean denoting if the header is a placeholder header. */ isPlaceholder: boolean /** * If the header is a placeholder header, this will be a unique header ID that does not conflict with any other headers across the table. */ placeholderId?: string /** * The row-span for the header. */ rowSpan: number /** * The header's hierarchical sub/child headers. Will be empty if the header's associated column is a leaf-column. */ subHeaders: Array> /** * Reference to the parent table instance. */ table: Table } export interface Header_Header< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > extends Header_CoreProperties { /** * Returns the rendering context (or props) for column-based components like headers, footers and filters. */ getContext: () => HeaderContext /** * Returns the leaf headers hierarchically nested under this header. */ getLeafHeaders: () => Array> } export interface HeaderGroup_Header< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { depth: number headers: Array> id: string } ================================================ FILE: packages/table-core/src/core/headers/coreHeadersFeature.utils.ts ================================================ import { getDefaultColumnPinningState, table_getCenterHeaderGroups, table_getLeftHeaderGroups, table_getRightHeaderGroups, } from '../../features/column-pinning/columnPinningFeature.utils' import { table_getVisibleLeafColumns } from '../../features/column-visibility/columnVisibilityFeature.utils' import { callMemoOrStaticFn } from '../../utils' import { buildHeaderGroups } from './buildHeaderGroups' import type { Table_Internal } from '../../types/Table' import type { Header } from '../../types/Header' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Header_Header } from './coreHeadersFeature.types' import type { Column } from '../../types/Column' export function header_getLeafHeaders< TFeatures extends TableFeatures, TData extends RowData, TValue, >(header: Header) { const leafHeaders: Array> = [] const recurseHeader = (h: Header_Header) => { if (h.subHeaders.length) { h.subHeaders.map(recurseHeader) } leafHeaders.push(h as Header) } recurseHeader(header) return leafHeaders } export function header_getContext< TFeatures extends TableFeatures, TData extends RowData, TValue, >(header: Header) { return { column: header.column, header, table: header.column.table, } } export function table_getHeaderGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const { left, right } = table.store.state.columnPinning ?? getDefaultColumnPinningState() const allColumns = table.getAllColumns() const leafColumns = callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ) as unknown as Array> const leftColumns = left .map((columnId) => leafColumns.find((d) => d.id === columnId)!) .filter(Boolean) const rightColumns = right .map((columnId) => leafColumns.find((d) => d.id === columnId)!) .filter(Boolean) const centerColumns = leafColumns.filter( (column) => !left.includes(column.id) && !right.includes(column.id), ) const headerGroups = buildHeaderGroups( allColumns, [...leftColumns, ...centerColumns, ...rightColumns], table, ) return headerGroups } export function table_getFooterGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const headerGroups = table.getHeaderGroups() return [...headerGroups].reverse() } export function table_getFlatHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const headerGroups = table.getHeaderGroups() return headerGroups .map((headerGroup) => { return headerGroup.headers }) .flat() } export function table_getLeafHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const left = callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ) const center = callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ) const right = callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ) return [ ...(left[0]?.headers ?? []), ...(center[0]?.headers ?? []), ...(right[0]?.headers ?? []), ] .map((header) => { return header.getLeafHeaders() }) .flat() } ================================================ FILE: packages/table-core/src/core/row-models/coreRowModelsFeature.ts ================================================ import { assignTableAPIs } from '../../utils' import { table_getCoreRowModel, table_getExpandedRowModel, table_getFilteredRowModel, table_getGroupedRowModel, table_getPaginatedRowModel, table_getPreExpandedRowModel, table_getPreFilteredRowModel, table_getPreGroupedRowModel, table_getPrePaginatedRowModel, table_getPreSortedRowModel, table_getRowModel, table_getSortedRowModel, } from './coreRowModelsFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { Table_RowModels } from './coreRowModelsFeature.types' interface CoreRowModelsFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Table: Table_RowModels } export function constructCoreRowModelsFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { constructTableAPIs: (table) => { assignTableAPIs('coreRowModelsFeature', table, { table_getCoreRowModel: { fn: () => table_getCoreRowModel(table), }, table_getPreFilteredRowModel: { fn: () => table_getPreFilteredRowModel(table), }, table_getFilteredRowModel: { fn: () => table_getFilteredRowModel(table), }, table_getPreGroupedRowModel: { fn: () => table_getPreGroupedRowModel(table), }, table_getGroupedRowModel: { fn: () => table_getGroupedRowModel(table), }, table_getPreSortedRowModel: { fn: () => table_getPreSortedRowModel(table), }, table_getSortedRowModel: { fn: () => table_getSortedRowModel(table), }, table_getPreExpandedRowModel: { fn: () => table_getPreExpandedRowModel(table), }, table_getExpandedRowModel: { fn: () => table_getExpandedRowModel(table), }, table_getPrePaginatedRowModel: { fn: () => table_getPrePaginatedRowModel(table), }, table_getPaginatedRowModel: { fn: () => table_getPaginatedRowModel(table), }, table_getRowModel: { fn: () => table_getRowModel(table), }, }) }, } } /** * The Core Row Models feature provides the core row model functionality. */ export const coreRowModelsFeature = constructCoreRowModelsFeature() ================================================ FILE: packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts ================================================ import type { Table } from '../../types/Table' import type { Table_RowModels_Faceted } from '../../features/column-faceting/columnFacetingFeature.types' import type { Table_RowModels_Filtered } from '../../features/column-filtering/columnFilteringFeature.types' import type { Table_RowModels_Grouped } from '../../features/column-grouping/columnGroupingFeature.types' import type { Table_RowModels_Expanded } from '../../features/row-expanding/rowExpandingFeature.types' import type { Table_RowModels_Paginated } from '../../features/row-pagination/rowPaginationFeature.types' import type { Table_RowModels_Sorted } from '../../features/row-sorting/rowSortingFeature.types' import type { Row } from '../../types/Row' import type { TableFeatures } from '../../types/TableFeatures' import type { RowData } from '../../types/type-utils' export interface RowModel< TFeatures extends TableFeatures, TData extends RowData, > { rows: Array> flatRows: Array> rowsById: Record> } export interface CreateRowModel_Plugins {} export interface CreateRowModel_Core< TFeatures extends TableFeatures, TData extends RowData, > extends CreateRowModel_Plugins { /** * This required option is a factory for a function that computes and returns the core row model for the table. */ coreRowModel?: ( table: Table, ) => () => RowModel } export interface CachedRowModel_Plugins {} export interface CachedRowModel_Core< TFeatures extends TableFeatures, TData extends RowData, > extends CachedRowModel_Plugins { coreRowModel: () => RowModel } export interface Table_RowModels_Core< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the core row model before any processing has been applied. */ getCoreRowModel: () => RowModel /** * Returns the final model after all processing from other used features has been applied. This is the row model that is most commonly used for rendering. */ getRowModel: () => RowModel } export type Table_RowModels< TFeatures extends TableFeatures, TData extends RowData, > = Table_RowModels_Core & Table_RowModels_Faceted & Table_RowModels_Filtered & Table_RowModels_Grouped & Table_RowModels_Expanded & Table_RowModels_Paginated & Table_RowModels_Sorted ================================================ FILE: packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts ================================================ import { createCoreRowModel } from './createCoreRowModel' import type { Table_Internal } from '../../types/Table' import type { TableFeatures } from '../../types/TableFeatures' import type { RowData } from '../../types/type-utils' import type { RowModel } from './coreRowModelsFeature.types' export function table_getCoreRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { if (!table._rowModels.coreRowModel) { table._rowModels.coreRowModel = table.options._rowModels?.coreRowModel?.(table) ?? createCoreRowModel()(table) } return table._rowModels.coreRowModel() } export function table_getPreFilteredRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getCoreRowModel() } export function table_getFilteredRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { if (!table._rowModels.filteredRowModel) { table._rowModels.filteredRowModel = table.options._rowModels?.filteredRowModel?.(table) } if (table.options.manualFiltering || !table._rowModels.filteredRowModel) { return table.getPreFilteredRowModel() } return table._rowModels.filteredRowModel() } export function table_getPreGroupedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getFilteredRowModel() } export function table_getGroupedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { if (!table._rowModels.groupedRowModel) { table._rowModels.groupedRowModel = table.options._rowModels?.groupedRowModel?.(table) } if (table.options.manualGrouping || !table._rowModels.groupedRowModel) { return table.getPreGroupedRowModel() } return table._rowModels.groupedRowModel() } export function table_getPreSortedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getGroupedRowModel() } export function table_getSortedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { if (!table._rowModels.sortedRowModel) { table._rowModels.sortedRowModel = table.options._rowModels?.sortedRowModel?.(table) } if (table.options.manualSorting || !table._rowModels.sortedRowModel) { return table.getPreSortedRowModel() } return table._rowModels.sortedRowModel() } export function table_getPreExpandedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getSortedRowModel() } export function table_getExpandedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { if (!table._rowModels.expandedRowModel) { table._rowModels.expandedRowModel = table.options._rowModels?.expandedRowModel?.(table) } if (table.options.manualExpanding || !table._rowModels.expandedRowModel) { return table.getPreExpandedRowModel() } return table._rowModels.expandedRowModel() } export function table_getPrePaginatedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getExpandedRowModel() } export function table_getPaginatedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { if (!table._rowModels.paginatedRowModel) { table._rowModels.paginatedRowModel = table.options._rowModels?.paginatedRowModel?.(table) } if (table.options.manualPagination || !table._rowModels.paginatedRowModel) { return table.getPrePaginatedRowModel() } return table._rowModels.paginatedRowModel() } export function table_getRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getPaginatedRowModel() } ================================================ FILE: packages/table-core/src/core/row-models/createCoreRowModel.ts ================================================ import { constructRow } from '../rows/constructRow' import { tableMemo } from '../../utils' import { table_autoResetPageIndex } from '../../features/row-pagination/rowPaginationFeature.utils' import type { Table, Table_Internal } from '../../types/Table' import type { RowModel } from './coreRowModelsFeature.types' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' import type { RowData } from '../../types/type-utils' export function createCoreRowModel< TFeatures extends TableFeatures, TData extends RowData, >(): (table: Table) => () => RowModel { return (_table) => { const table = _table as Table_Internal return tableMemo({ feature: 'coreRowModelsFeature', table, fnName: 'table.getCoreRowModel', memoDeps: () => [table.options.data], fn: () => _createCoreRowModel(table, table.options.data), onAfterUpdate: () => table_autoResetPageIndex(table), }) } } function _createCoreRowModel< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, data: ReadonlyArray, ): { rows: Array> flatRows: Array> rowsById: Record> } { const rowModel: RowModel = { rows: [], flatRows: [], rowsById: {}, } const accessRows = ( originalRows: ReadonlyArray, depth = 0, parentRow?: Row, ): Array> => { const rows = [] as Array> for (let i = 0; i < originalRows.length; i++) { const originalRow = originalRows[i]! // Make the row const row = constructRow( table, table.getRowId(originalRow, i, parentRow), originalRow, i, depth, undefined, parentRow?.id, ) // Keep track of every row in a flat array rowModel.flatRows.push(row) // Also keep track of every row by its ID rowModel.rowsById[row.id] = row // Push table row into parent rows.push(row) // Get the original subrows if (table.options.getSubRows) { row.originalSubRows = table.options.getSubRows(originalRow, i) // Then recursively access them if (row.originalSubRows?.length) { row.subRows = accessRows(row.originalSubRows, depth + 1, row) } } } return rows } rowModel.rows = accessRows(data) return rowModel } ================================================ FILE: packages/table-core/src/core/rows/constructRow.ts ================================================ import type { Table_Internal } from '../../types/Table' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' import type { Row_CoreProperties } from './coreRowsFeature.types' /** * Creates or retrieves the row prototype for a table. * The prototype is cached on the table and shared by all row instances. */ function getRowPrototype< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): object { if (!table._rowPrototype) { table._rowPrototype = { table } for (const feature of Object.values(table._features)) { feature.assignRowPrototype?.(table._rowPrototype, table) } } return table._rowPrototype } export const constructRow = < TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, id: string, original: TData, rowIndex: number, depth: number, subRows?: Array>, parentId?: string, ): Row => { // Create row with shared prototype for memory efficiency const rowPrototype = getRowPrototype(table) const row = Object.create(rowPrototype) as Row_CoreProperties< TFeatures, TData > // Only assign instance-specific properties row._uniqueValuesCache = {} row._valuesCache = {} row.depth = depth row.id = id row.index = rowIndex row.original = original row.parentId = parentId row.subRows = subRows ?? [] // Initialize instance-specific data (e.g., caches) for features that need it for (const feature of Object.values(table._features)) { feature.initRowInstanceData?.(row as Row) } return row as Row } ================================================ FILE: packages/table-core/src/core/rows/coreRowsFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs } from '../../utils' import { row_getAllCells, row_getAllCellsByColumnId, row_getLeafRows, row_getParentRow, row_getParentRows, row_getUniqueValues, row_getValue, row_renderValue, table_getRow, table_getRowId, } from './coreRowsFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // Row_Row, // TableOptions_Rows, // Table_Rows, // } from './coreRowsFeature.types' interface CoreRowsFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Row: Row_Row // TableOptions: TableOptions_Rows // Table: Table_Rows } export function constructCoreRowsFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('coreRowsFeature', prototype, table, { row_getAllCellsByColumnId: { fn: (row) => row_getAllCellsByColumnId(row), memoDeps: (row) => [row.getAllCells()], }, row_getAllCells: { fn: (row) => row_getAllCells(row), memoDeps: (row) => [row.table.getAllLeafColumns()], }, row_getLeafRows: { fn: (row) => row_getLeafRows(row), }, row_getParentRow: { fn: (row) => row_getParentRow(row), }, row_getParentRows: { fn: (row) => row_getParentRows(row), }, row_getUniqueValues: { fn: (row, columnId) => row_getUniqueValues(row, columnId), }, row_getValue: { fn: (row, columnId) => row_getValue(row, columnId), }, row_renderValue: { fn: (row, columnId) => row_renderValue(row, columnId), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('coreRowsFeature', table, { table_getRowId: { fn: (originalRow, index, parent) => table_getRowId(originalRow, table, index, parent), }, table_getRow: { fn: (id: string, searchAll?: boolean) => table_getRow(table, id, searchAll), }, }) }, } } /** * The Core Rows feature provides the core row functionality. */ export const coreRowsFeature = constructCoreRowsFeature() ================================================ FILE: packages/table-core/src/core/rows/coreRowsFeature.types.ts ================================================ import type { Table_Internal } from '../../types/Table' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' import type { Cell } from '../../types/Cell' export interface Row_CoreProperties< TFeatures extends TableFeatures, TData extends RowData, > { _uniqueValuesCache: Record _valuesCache: Record /** * The depth of the row (if nested or grouped) relative to the root row array. */ depth: number /** * The resolved unique identifier for the row resolved via the `options.getRowId` option. Defaults to the row's index (or relative index if it is a subRow). */ id: string /** * The index of the row within its parent array (or the root data array). */ index: number /** * The original row object provided to the table. If the row is a grouped row, the original row object will be the first original in the group. */ original: TData /** * An array of the original subRows as returned by the `options.getSubRows` option. */ originalSubRows?: ReadonlyArray /** * If nested, this row's parent row id. */ parentId?: string /** * An array of subRows for the row as returned and created by the `options.getSubRows` option. */ subRows: Array> /** * Reference to the parent table instance. */ table: Table_Internal } export interface Row_Row< TFeatures extends TableFeatures, TData extends RowData, > extends Row_CoreProperties { getAllCellsByColumnId: () => Record> /** * Returns all of the cells for the row. */ getAllCells: () => Array> /** * Returns the leaf rows for the row, not including any parent rows. */ getLeafRows: () => Array> /** * Returns the parent row for the row, if it exists. */ getParentRow: () => Row | undefined /** * Returns the parent rows for the row, all the way up to a root row. */ getParentRows: () => Array> /** * Returns a unique array of values from the row for a given columnId. */ getUniqueValues: (columnId: string) => Array /** * Returns the value from the row for a given columnId. */ getValue: (columnId: string) => TValue /** * Renders the value for the row in a given columnId the same as `getValue`, but will return the `renderFallbackValue` if no value is found. */ renderValue: (columnId: string) => TValue } export interface TableOptions_Rows< TFeatures extends TableFeatures, TData extends RowData, > { /** * This optional function is used to derive a unique ID for any given row. If not provided the rows index is used (nested rows join together with `.` using their grandparents' index eg. `index.index.index`). If you need to identify individual rows that are originating from any server-side operations, it's suggested you use this function to return an ID that makes sense regardless of network IO/ambiguity eg. a userId, taskId, database ID field, etc. * @example getRowId: row => row.userId */ getRowId?: ( originalRow: TData, index: number, parent?: Row, ) => string /** * This optional function is used to access the sub rows for any given row. If you are using nested rows, you will need to use this function to return the sub rows object (or undefined) from the row. * @example getSubRows: row => row.subRows */ getSubRows?: ( originalRow: TData, index: number, ) => undefined | ReadonlyArray } export interface Table_Rows< TFeatures extends TableFeatures, TData extends RowData, > { getRowId: (_: TData, index: number, parent?: Row) => string /** * Returns the row with the given ID. */ getRow: (id: string, searchAll?: boolean) => Row } ================================================ FILE: packages/table-core/src/core/rows/coreRowsFeature.utils.ts ================================================ import { flattenBy } from '../../utils' import { constructCell } from '../cells/constructCell' import type { Table_Internal } from '../../types/Table' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' import type { Cell } from '../../types/Cell' export function row_getValue< TFeatures extends TableFeatures, TData extends RowData, >(row: Row, columnId: string) { if (row._valuesCache.hasOwnProperty(columnId)) { return row._valuesCache[columnId] } const column = row.table.getColumn(columnId) if (!column?.accessorFn) { return undefined } row._valuesCache[columnId] = column.accessorFn(row.original, row.index) return row._valuesCache[columnId] } export function row_getUniqueValues< TFeatures extends TableFeatures, TData extends RowData, >(row: Row, columnId: string) { if (row._uniqueValuesCache.hasOwnProperty(columnId)) { return row._uniqueValuesCache[columnId] } const column = row.table.getColumn(columnId) if (!column?.accessorFn) { return undefined } if (!column.columnDef.getUniqueValues) { row._uniqueValuesCache[columnId] = [row.getValue(columnId)] return row._uniqueValuesCache[columnId] } row._uniqueValuesCache[columnId] = column.columnDef.getUniqueValues( row.original, row.index, ) return row._uniqueValuesCache[columnId] } export function row_renderValue< TFeatures extends TableFeatures, TData extends RowData, >(row: Row, columnId: string) { return row.getValue(columnId) ?? row.table.options.renderFallbackValue } export function row_getLeafRows< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): Array> { return flattenBy(row.subRows, (d) => d.subRows) } export function row_getParentRow< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return row.parentId ? row.table.getRow(row.parentId, true) : undefined } export function row_getParentRows< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const parentRows: Array> = [] let currentRow = row // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition while (true) { const parentRow = currentRow.getParentRow() if (!parentRow) break parentRows.push(parentRow) currentRow = parentRow } return parentRows.reverse() } export function row_getAllCells< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): Array> { return row.table.getAllLeafColumns().map((column) => { return constructCell(column, row, row.table) }) } export function row_getAllCellsByColumnId< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return row.getAllCells().reduce( (acc, cell) => { acc[cell.column.id] = cell return acc }, {} as Record>, ) } export function table_getRowId< TFeatures extends TableFeatures, TData extends RowData, >( originalRow: TData, table: Table_Internal, index: number, parent?: Row, ) { return ( table.options.getRowId?.(originalRow, index, parent) ?? `${parent ? [parent.id, index].join('.') : index}` ) } export function table_getRow< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, rowId: string, searchAll?: boolean, ): Row { // TODO - simplify this across different row models let row = (searchAll ? table.getPrePaginatedRowModel() : table.getRowModel()) .rowsById[rowId] if (!row) { row = table.getCoreRowModel().rowsById[rowId] if (!row) { if (process.env.NODE_ENV === 'development') { throw new Error(`getRow could not find row with ID: ${rowId}`) } throw new Error() } } return row } ================================================ FILE: packages/table-core/src/core/table/constructTable.ts ================================================ import { createStore } from '@tanstack/store' import { coreFeatures } from '../coreFeatures' import type { Store } from '@tanstack/store' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' import type { Table, Table_Internal } from '../../types/Table' import type { TableOptions } from '../../types/TableOptions' import type { TableState } from '../../types/TableState' export function getInitialTableState( features: TFeatures, initialState: Partial> | undefined = {}, ): TableState { Object.values(features).forEach((feature) => { initialState = feature.getInitialState?.(initialState as TableState) ?? initialState }) return structuredClone(initialState) as TableState } export function createTableStore( features: TFeatures, initialState: Partial> | undefined = {}, ): Store> { return createStore(getInitialTableState(features, initialState)) } export function constructTable< TFeatures extends TableFeatures, TData extends RowData, >(tableOptions: TableOptions): Table { const table = { _features: { ...coreFeatures, ...tableOptions._features }, _rowModels: {}, _rowModelFns: {}, get options() { return this.optionsStore.state }, set options(value) { this.optionsStore.setState(() => value) }, } as Table_Internal const featuresList: Array> = Object.values(table._features) const defaultOptions = featuresList.reduce((obj, feature) => { return Object.assign(obj, feature.getDefaultTableOptions?.(table)) }, {}) as TableOptions table.optionsStore = createStore({ ...defaultOptions, ...tableOptions, }) table.initialState = getInitialTableState( table._features, table.options.initialState, ) table.baseStore = table.options.store ?? createStore(table.initialState) table.store = createStore(() => { const state = table.baseStore.state return { ...state, ...(table.optionsStore.state.state ?? {}), } }) if ( process.env.NODE_ENV === 'development' && (tableOptions.debugAll || tableOptions.debugTable) ) { const features = Object.keys(table._features) const rowModels = Object.keys(table.options._rowModels || {}) const states = Object.keys(table.initialState) console.log( `Constructing Table Instance Features: ${features.join('\n ')} Row Models: ${rowModels.length ? rowModels.join('\n ') : '(none)'} States: ${states.join('\n ')}`, ) } for (const feature of featuresList) { feature.constructTableAPIs?.(table) } return table } ================================================ FILE: packages/table-core/src/core/table/coreTablesFeature.ts ================================================ import { assignTableAPIs } from '../../utils' import { table_reset, table_setOptions } from './coreTablesFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { TableOptions_Table, Table_Table } from './coreTablesFeature.types' interface CoreTablesFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Table: Table_Table // TableOptions: TableOptions_Table } export function constructCoreTablesFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { constructTableAPIs: (table) => { assignTableAPIs('coreTablesFeature', table, { table_reset: { fn: () => table_reset(table), }, table_setOptions: { fn: (updater) => table_setOptions(table, updater), }, }) }, } } /** * The Core Tables feature provides the core table functionality for handling state and options. */ export const coreTablesFeature = constructCoreTablesFeature() ================================================ FILE: packages/table-core/src/core/table/coreTablesFeature.types.ts ================================================ import type { ReadonlyStore, Store } from '@tanstack/store' import type { CoreFeatures } from '../coreFeatures' import type { RowModelFns } from '../../types/RowModelFns' import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { CachedRowModels, CreateRowModels_All } from '../../types/RowModel' import type { TableOptions } from '../../types/TableOptions' import type { TableState } from '../../types/TableState' export interface TableMeta< TFeatures extends TableFeatures, TData extends RowData, > {} export interface TableOptions_Table< TFeatures extends TableFeatures, TData extends RowData, > { /** * The features that you want to enable for the table. */ _features: TFeatures /** * The row model options that you want to enable for the table. */ _rowModels?: CreateRowModels_All /** * Set this option to override any of the `autoReset...` feature options. */ autoResetAll?: boolean /** * The data for the table to display. When the `data` option changes reference, the table will reprocess the data. */ data: ReadonlyArray /** * Use this option to optionally pass initial state to the table. This state will be used when resetting various table states either automatically by the table (eg. `options.autoResetPageIndex`) or via functions like `table.resetRowSelection()`. Most reset function allow you optionally pass a flag to reset to a blank/default state instead of the initial state. * Table state will not be reset when this object changes, which also means that the initial state object does not need to be stable. */ initialState?: Partial> /** * This option is used to optionally implement the merging of table options. */ mergeOptions?: ( defaultOptions: TableOptions, options: Partial>, ) => TableOptions /** * You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`. */ meta?: TableMeta /** * Pass in individual self-managed state to the table. */ state?: Partial> /** * Optionally, provide your own external TanStack Store instance if you want to manage the table state externally. */ store?: Store> } export interface Table_CoreProperties< TFeatures extends TableFeatures, TData extends RowData, > { /** * The features that are enabled for the table. */ _features: Partial & TFeatures /** * Prototype cache for Cell objects - shared by all cells in this table */ _cellPrototype?: object /** * Prototype cache for Column objects - shared by all columns in this table */ _columnPrototype?: object /** * Prototype cache for Header objects - shared by all headers in this table */ _headerPrototype?: object /** * The row model processing functions that are used to process the data by features. */ _rowModelFns: RowModelFns /** * The row models that are enabled for the table. */ _rowModels: CachedRowModels /** * Prototype cache for Row objects - shared by all rows in this table */ _rowPrototype?: object /** * The base store for the table. This can be used to write to the table state. */ baseStore: Store> /** * The base store for the table options. */ optionsStore: Store> /** * This is the resolved initial state of the table. */ initialState: TableState /** * A read-only reference to the table's current options. */ readonly options: TableOptions /** * Where the table state is stored. */ store: ReadonlyStore> } export interface Table_Table< TFeatures extends TableFeatures, TData extends RowData, > extends Table_CoreProperties { /** * Call this function to reset the table state to the initial state. */ reset: () => void /** * This function can be used to update the table options. */ setOptions: (newOptions: Updater>) => void } ================================================ FILE: packages/table-core/src/core/table/coreTablesFeature.utils.ts ================================================ import { functionalUpdate } from '../../utils' import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { TableOptions } from '../../types/TableOptions' export function table_reset< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): void { table.baseStore.setState(() => structuredClone(table.initialState)) } export function table_mergeOptions< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, newOptions: TableOptions, ) { if (table.options.mergeOptions) { return table.options.mergeOptions(table.options, newOptions) } return { ...table.options, ...newOptions, } } export function table_setOptions< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater>, ): void { const newOptions = functionalUpdate(updater, table.options) const mergedOptions = table_mergeOptions(table, newOptions) table.optionsStore.setState(() => mergedOptions) } ================================================ FILE: packages/table-core/src/features/column-faceting/columnFacetingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, } from '../../utils' import { column_getFacetedMinMaxValues, column_getFacetedRowModel, column_getFacetedUniqueValues, table_getGlobalFacetedMinMaxValues, table_getGlobalFacetedRowModel, table_getGlobalFacetedUniqueValues, } from './columnFacetingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' import type { Column_Internal } from '../../types/Column' // import type { // CachedRowModel_Faceted, // Column_ColumnFaceting, // CreateRowModel_Faceted, // } from './columnFacetingFeature.types' interface ColumnFacetingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // CachedRowModel: CachedRowModel_Faceted // Column: Column_ColumnFaceting // CreateRowModels: CreateRowModel_Faceted } export function constructColumnFacetingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnFacetingFeature', prototype, table, { column_getFacetedRowModel: { memoDeps: () => [ table.getPreFilteredRowModel().rows, table.store.state.columnFilters, table.store.state.globalFilter, table.getFilteredRowModel().rows, ], fn: (column) => column_getFacetedRowModel(column, column.table), }, column_getFacetedMinMaxValues: { memoDeps: (column: Column_Internal) => [ callMemoOrStaticFn( column, 'getFacetedRowModel', column_getFacetedRowModel, column.table, ).flatRows, ], fn: (column) => column_getFacetedMinMaxValues(column, column.table), }, column_getFacetedUniqueValues: { memoDeps: (column: Column_Internal) => [ callMemoOrStaticFn( column, 'getFacetedRowModel', column_getFacetedRowModel, column.table, ).flatRows, ], fn: (column) => column_getFacetedUniqueValues(column, column.table), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('columnFacetingFeature', table, { table_getGlobalFacetedRowModel: { memoDeps: () => [ table.getPreFilteredRowModel().rows, table.store.state.columnFilters, table.store.state.globalFilter, table.getFilteredRowModel().rows, ], fn: () => table_getGlobalFacetedRowModel(table), }, table_getGlobalFacetedMinMaxValues: { memoDeps: () => [ callMemoOrStaticFn( table, 'getGlobalFacetedRowModel', table_getGlobalFacetedRowModel, ).flatRows, ], fn: () => table_getGlobalFacetedMinMaxValues(table), }, table_getGlobalFacetedUniqueValues: { memoDeps: () => [ callMemoOrStaticFn( table, 'getGlobalFacetedRowModel', table_getGlobalFacetedRowModel, ).flatRows, ], fn: () => table_getGlobalFacetedUniqueValues(table), }, }) }, } } /** * The Column Faceting feature adds column faceting APIs to the column objects. */ export const columnFacetingFeature = constructColumnFacetingFeature() ================================================ FILE: packages/table-core/src/features/column-faceting/columnFacetingFeature.types.ts ================================================ import type { Table } from '../../types/Table' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' export interface Column_ColumnFaceting< TFeatures extends TableFeatures, TData extends RowData, > { /** * A function that **computes and returns** a min/max tuple derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. */ getFacetedMinMaxValues: () => undefined | [number, number] /** * A function that **computes and returns** a row model with all other column filters applied, excluding its own filter. Useful for displaying faceted result counts. */ getFacetedRowModel: () => RowModel /** * Returns a `Map` of unique values and their occurrences derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. */ getFacetedUniqueValues: () => Map } export interface Table_RowModels_Faceted< TFeatures extends TableFeatures, TData extends RowData, > { /** * A function that **computes and returns** a min/max tuple derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. * > ⚠️ Requires that you pass a valid `getFacetedMinMaxValues` function to `options.getFacetedMinMaxValues`. A default implementation is provided via the exported `getFacetedMinMaxValues` function. */ getFacetedMinMaxValues: () => undefined | [number, number] /** * Returns the row model with all other column filters applied, excluding its own filter. Useful for displaying faceted result counts. * > ⚠️ Requires that you pass a valid `getFacetedRowModel` function to `options.facetedRowModel`. A default implementation is provided via the exported `getFacetedRowModel` function. */ getFacetedRowModel: () => RowModel /** * A function that **computes and returns** a `Map` of unique values and their occurrences derived from `column.getFacetedRowModel`. Useful for displaying faceted result values. * > ⚠️ Requires that you pass a valid `getFacetedUniqueValues` function to `options.getFacetedUniqueValues`. A default implementation is provided via the exported `getFacetedUniqueValues` function. */ getFacetedUniqueValues: () => Map } export interface CreateRowModel_Faceted< TFeatures extends TableFeatures, TData extends RowData, > { /** * This function is used to retrieve the faceted min/max values. If using server-side faceting, this function is not required. To use client-side faceting, pass the exported `getFacetedMinMaxValues()` from your adapter to your table or implement your own. */ facetedMinMaxValues?: ( table: Table, columnId: string, ) => () => [number, number] | undefined /** * This function is used to retrieve the faceted row model. If using server-side faceting, this function is not required. To use client-side faceting, pass the exported `getFacetedRowModel()` from your adapter to your table or implement your own. */ facetedRowModel?: ( table: Table, columnId: string, ) => () => RowModel /** * This function is used to retrieve the faceted unique values. If using server-side faceting, this function is not required. To use client-side faceting, pass the exported `getFacetedUniqueValues()` from your adapter to your table or implement your own. */ facetedUniqueValues?: ( table: Table, columnId: string, ) => () => Map } export interface CachedRowModel_Faceted< TFeatures extends TableFeatures, TData extends RowData, > { facetedRowModel?: (columnId: string) => () => RowModel facetedMinMaxValues?: (columnId: string) => [number, number] facetedUniqueValues?: (columnId: string) => Map } export interface Table_ColumnFaceting< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the min and max values for the global filter. */ getGlobalFacetedMinMaxValues: () => undefined | [number, number] /** * Returns the row model for the table after **global** filtering has been applied. */ getGlobalFacetedRowModel: () => RowModel /** * Returns the faceted unique values for the global filter. */ getGlobalFacetedUniqueValues: () => Map } ================================================ FILE: packages/table-core/src/features/column-faceting/columnFacetingFeature.utils.ts ================================================ import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table_Internal } from '../../types/Table' import type { Column_Internal } from '../../types/Column' export function column_getFacetedMinMaxValues< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, table: Table_Internal, ): [number, number] | undefined { const facetedMinMaxValuesFn = table.options._rowModels?.facetedMinMaxValues?.(table, column.id) ?? (() => undefined) return facetedMinMaxValuesFn() } export function column_getFacetedRowModel< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal | undefined, table: Table_Internal, ): RowModel { const facetedRowModelFn = table.options._rowModels?.facetedRowModel?.(table, column?.id ?? '') ?? (() => table.getPreFilteredRowModel()) return facetedRowModelFn() } export function column_getFacetedUniqueValues< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, table: Table_Internal, ): Map { const facetedUniqueValuesFn = table.options._rowModels?.facetedUniqueValues?.(table, column.id) ?? (() => new Map()) return facetedUniqueValuesFn() } export function table_getGlobalFacetedMinMaxValues< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): undefined | [number, number] { const facetedMinMaxValuesFn = table.options._rowModels?.facetedMinMaxValues?.(table, '__global__') ?? (() => undefined) return facetedMinMaxValuesFn() } export function table_getGlobalFacetedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { const facetedRowModelFn = table.options._rowModels?.facetedRowModel?.(table, '__global__') ?? (() => table.getPreFilteredRowModel()) return facetedRowModelFn() } export function table_getGlobalFacetedUniqueValues< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): Map { const facetedUniqueValuesFn = table.options._rowModels?.facetedUniqueValues?.(table, '__global__') ?? (() => new Map()) return facetedUniqueValuesFn() } ================================================ FILE: packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts ================================================ import { callMemoOrStaticFn, tableMemo } from '../../utils' import { column_getFacetedRowModel } from './columnFacetingFeature.utils' import type { Row } from '../../types/Row' import type { Table, Table_Internal } from '../../types/Table' import type { TableFeatures } from '../../types/TableFeatures' import type { RowData } from '../../types/type-utils' export function createFacetedMinMaxValues< TFeatures extends TableFeatures, TData extends RowData = any, >(): ( table: Table, columnId: string, ) => () => undefined | [number, number] { return (_table, columnId) => { const table = _table as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', fn: (flatRows) => _createFacetedMinMaxValues(columnId, flatRows), fnName: 'table.getFacetedMinMaxValues', memoDeps: () => { const column = table.getColumn(columnId) if (!column) return [table.getPreFilteredRowModel().flatRows] return [ callMemoOrStaticFn( column, 'getFacetedRowModel', column_getFacetedRowModel, table, ).flatRows, ] }, table, }) } } function _createFacetedMinMaxValues< TFeatures extends TableFeatures, TData extends RowData = any, >( columnId: string, flatRows: Array>, ): undefined | [number, number] { if (!flatRows.length) return undefined const numericValues = flatRows .map((flatRow) => flatRow.getValue(columnId)) .map(Number) .filter((value) => !Number.isNaN(value)) if (!numericValues.length) return undefined let facetedMinValue = numericValues[0]! let facetedMaxValue = numericValues[0]! for (const value of numericValues) { if (value < facetedMinValue) facetedMinValue = value if (value > facetedMaxValue) facetedMaxValue = value } return [facetedMinValue, facetedMaxValue] } ================================================ FILE: packages/table-core/src/features/column-faceting/createFacetedRowModel.ts ================================================ import { tableMemo } from '../../utils' import { filterRows } from '../column-filtering/filterRowsUtils' import type { Table, Table_Internal } from '../../types/Table' import type { ColumnFiltersState, Row_ColumnFiltering, } from '../column-filtering/columnFilteringFeature.types' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Row } from '../../types/Row' import type { RowData } from '../../types/type-utils' export function createFacetedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(): ( table: Table, columnId: string, ) => () => RowModel { return (_table, columnId) => { const table = _table as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', table, fnName: 'createFacetedRowModel', memoDeps: () => [ table.getPreFilteredRowModel(), table.store.state.columnFilters, table.store.state.globalFilter, table.getFilteredRowModel(), ], fn: (preRowModel, columnFilters, globalFilter) => _createFacetedRowModel( table, columnId, preRowModel, columnFilters, globalFilter, ), }) } } function _createFacetedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >( table: Table_Internal, columnId: string, preRowModel: RowModel, columnFilters?: ColumnFiltersState, globalFilter?: string, ) { if (!preRowModel.rows.length || (!columnFilters?.length && !globalFilter)) { return preRowModel } const filterableIds = [ ...(columnFilters?.map((d) => d.id).filter((d) => d !== columnId) ?? []), globalFilter ? '__global__' : undefined, ].filter(Boolean) as Array const filterRowsImpl = ( row: Row & Partial>, ) => { // Horizontally filter rows through each column for (const colId of filterableIds) { if (row.columnFilters?.[colId] === false) { return false } } return true } return filterRows(preRowModel.rows, filterRowsImpl, table) } ================================================ FILE: packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts ================================================ import { callMemoOrStaticFn, tableMemo } from '../../utils' import { column_getFacetedRowModel } from './columnFacetingFeature.utils' import type { Row } from '../../types/Row' import type { Table, Table_Internal } from '../../types/Table' import type { TableFeatures } from '../../types/TableFeatures' import type { RowData } from '../../types/type-utils' export function createFacetedUniqueValues< TFeatures extends TableFeatures, TData extends RowData = any, >(): ( table: Table, columnId: string, ) => () => Map { return (_table, columnId) => { const table = _table as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', table, fnName: 'table.getFacetedUniqueValues', memoDeps: () => { const column = table.getColumn(columnId) if (!column) return [table.getPreFilteredRowModel().flatRows] return [ callMemoOrStaticFn( column, 'getFacetedRowModel', column_getFacetedRowModel, table, ).flatRows, ] }, fn: (flatRows) => _createFacetedUniqueValues(columnId, flatRows), }) } } function _createFacetedUniqueValues< TFeatures extends TableFeatures, TData extends RowData = any, >(columnId: string, flatRows: Array>): Map { const facetedUniqueValues = new Map() for (const row of flatRows) { const values = row.getUniqueValues(columnId) for (const value of values) { if (facetedUniqueValues.has(value)) { facetedUniqueValues.set( value, (facetedUniqueValues.get(value) ?? 0) + 1, ) } else { facetedUniqueValues.set(value, 1) } } } return facetedUniqueValues } ================================================ FILE: packages/table-core/src/features/column-filtering/columnFilteringFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { column_getAutoFilterFn, column_getCanFilter, column_getFilterFn, column_getFilterIndex, column_getFilterValue, column_getIsFiltered, column_setFilterValue, getDefaultColumnFiltersState, table_resetColumnFilters, table_setColumnFilters, } from './columnFilteringFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // CachedRowModel_Filtered, // ColumnDef_ColumnFiltering, // Column_ColumnFiltering, // CreateRowModel_Filtered, // RowModelFns_ColumnFiltering, // Row_ColumnFiltering, // TableOptions_ColumnFiltering, // TableState_ColumnFiltering, // Table_ColumnFiltering, // } from './columnFilteringFeature.types' interface ColumnFilteringFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // CachedRowModel: CachedRowModel_Filtered // Column: Column_ColumnFiltering // ColumnDef: ColumnDef_ColumnFiltering // CreateRowModels: CreateRowModel_Filtered // Row: Row_ColumnFiltering // RowModelFns: RowModelFns_ColumnFiltering // Table: Table_ColumnFiltering // TableOptions: TableOptions_ColumnFiltering // TableState: TableState_ColumnFiltering } export function constructColumnFilteringFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { columnFilters: getDefaultColumnFiltersState(), ...initialState, } }, getDefaultColumnDef: () => { return { filterFn: 'auto', } }, getDefaultTableOptions: (table) => { return { onColumnFiltersChange: makeStateUpdater('columnFilters', table), filterFromLeafRows: false, maxLeafRowFilterDepth: 100, } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnFilteringFeature', prototype, table, { column_getAutoFilterFn: { fn: (column) => column_getAutoFilterFn(column), }, column_getFilterFn: { fn: (column) => column_getFilterFn(column), }, column_getCanFilter: { fn: (column) => column_getCanFilter(column), }, column_getIsFiltered: { fn: (column) => column_getIsFiltered(column), }, column_getFilterValue: { fn: (column) => column_getFilterValue(column), }, column_getFilterIndex: { fn: (column) => column_getFilterIndex(column), }, column_setFilterValue: { fn: (column, value) => column_setFilterValue(column, value), }, }) }, initRowInstanceData: (row) => { ;(row as any).columnFilters = {} ;(row as any).columnFiltersMeta = {} }, constructTableAPIs: (table) => { assignTableAPIs('columnFilteringFeature', table, { table_setColumnFilters: { fn: (updater) => table_setColumnFilters(table, updater), }, table_resetColumnFilters: { fn: (defaultState) => table_resetColumnFilters(table, defaultState), }, }) }, } } /** * The Column Filtering feature adds column filtering state and APIs to the table, row, and column objects. * **Note:** This does not include Global Filtering. The globalFilteringFeature feature has been split out into its own standalone feature. */ export const columnFilteringFeature = constructColumnFilteringFeature() ================================================ FILE: packages/table-core/src/features/column-filtering/columnFilteringFeature.types.ts ================================================ import type { Table } from '../../types/Table' import type { BuiltInFilterFn } from '../../fns/filterFns' import type { CellData, OnChangeFn, RowData, Updater, } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Row } from '../../types/Row' import type { Column } from '../../types/Column' export interface FilterMeta {} export interface FilterFns {} export interface TableState_ColumnFiltering { columnFilters: ColumnFiltersState } export type ColumnFiltersState = Array export interface ColumnFilter { id: string value: unknown } export interface ResolvedColumnFilter< TFeatures extends TableFeatures, TData extends RowData, > { filterFn: FilterFn id: string resolvedValue: unknown } export interface RowModelFns_ColumnFiltering< TFeatures extends TableFeatures, TData extends RowData, > { filterFns: Record> } export interface FilterFn< TFeatures extends TableFeatures, TData extends RowData, > { ( row: Row, columnId: string, filterValue: any, addMeta?: (meta: FilterMeta) => void, ): boolean autoRemove?: ColumnFilterAutoRemoveTestFn resolveFilterValue?: TransformFilterValueFn } export type TransformFilterValueFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = (value: any, column?: Column) => TValue export type ColumnFilterAutoRemoveTestFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = (value: any, column?: Column) => boolean export type CustomFilterFns< TFeatures extends TableFeatures, TData extends RowData, > = Record> export type FilterFnOption< TFeatures extends TableFeatures, TData extends RowData, > = 'auto' | BuiltInFilterFn | keyof FilterFns | FilterFn export interface ColumnDef_ColumnFiltering< TFeatures extends TableFeatures, TData extends RowData, > { /** * Enables/disables the **column** filter for this column. */ enableColumnFilter?: boolean /** * The filter function to use with this column. Can be the name of a built-in filter function or a custom filter function. */ filterFn?: FilterFnOption } export interface Column_ColumnFiltering< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns an automatically calculated filter function for the column based off of the columns first known value. */ getAutoFilterFn: () => FilterFn /** * Returns whether or not the column can be **column** filtered. */ getCanFilter: () => boolean /** * Returns the filter function (either user-defined or automatic, depending on configuration) for the columnId specified. */ getFilterFn: () => FilterFn /** * Returns the index (including `-1`) of the column filter in the table's `state.columnFilters` array. */ getFilterIndex: () => number /** * Returns the current filter value for the column. */ getFilterValue: () => unknown /** * Returns whether or not the column is currently filtered. */ getIsFiltered: () => boolean /** * A function that sets the current filter value for the column. You can pass it a value or an updater function for immutability-safe operations on existing values. */ setFilterValue: (updater: Updater) => void } export interface Row_ColumnFiltering< TFeatures extends TableFeatures, TData extends RowData, > { /** * The column filters map for the row. This object tracks whether a row is passing/failing specific filters by their column ID. */ columnFilters: Record /** * The column filters meta map for the row. This object tracks any filter meta for a row as optionally provided during the filtering process. */ columnFiltersMeta: Record } export interface TableOptions_ColumnFiltering< TFeatures extends TableFeatures, TData extends RowData, > { /** * Enables/disables **column** filtering for all columns. */ enableColumnFilters?: boolean /** * Enables/disables all filtering for the table. */ enableFilters?: boolean /** * By default, filtering is done from parent rows down (so if a parent row is filtered out, all of its children will be filtered out as well). Setting this option to `true` will cause filtering to be done from leaf rows up (which means parent rows will be included so long as one of their child or grand-child rows is also included). */ filterFromLeafRows?: boolean /** * Disables the `getFilteredRowModel` from being used to filter data. This may be useful if your table needs to dynamically support both client-side and server-side filtering. */ manualFiltering?: boolean /** * By default, filtering is done for all rows (max depth of 100), no matter if they are root level parent rows or the child leaf rows of a parent row. Setting this option to `0` will cause filtering to only be applied to the root level parent rows, with all sub-rows remaining unfiltered. Similarly, setting this option to `1` will cause filtering to only be applied to child leaf rows 1 level deep, and so on. * This is useful for situations where you want a row's entire child hierarchy to be visible regardless of the applied filter. */ maxLeafRowFilterDepth?: number /** * If provided, this function will be called with an `updaterFn` when `state.columnFilters` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. */ onColumnFiltersChange?: OnChangeFn } export interface Table_ColumnFiltering { /** * Resets the **columnFilters** state to `initialState.columnFilters`, or `true` can be passed to force a default blank state reset to `[]`. */ resetColumnFilters: (defaultState?: boolean) => void /** * Sets or updates the `state.columnFilters` state. */ setColumnFilters: (updater: Updater) => void } export interface Table_RowModels_Filtered< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model for the table after **column** filtering has been applied. */ getFilteredRowModel: () => RowModel /** * Returns the row model for the table before any **column** filtering has been applied. */ getPreFilteredRowModel: () => RowModel } export interface CreateRowModel_Filtered< TFeatures extends TableFeatures, TData extends RowData, > { /** * If provided, this function is called **once** per table and should return a **new function** which will calculate and return the row model for the table when it's filtered. * - For server-side filtering, this function is unnecessary and can be ignored since the server should already return the filtered row model. * - For client-side filtering, this function is required. A default implementation is provided via any table adapter's `{ getFilteredRowModel }` export. */ filteredRowModel?: ( table: Table, ) => () => RowModel } export interface CachedRowModel_Filtered< TFeatures extends TableFeatures, TData extends RowData, > { filteredRowModel: () => RowModel } ================================================ FILE: packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts ================================================ import { functionalUpdate, isFunction } from '../../utils' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Column_Internal } from '../../types/Column' import type { ColumnFiltersState, FilterFn, } from './columnFilteringFeature.types' export function getDefaultColumnFiltersState(): ColumnFiltersState { return structuredClone([]) } export function column_getAutoFilterFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const filterFns = column.table._rowModelFns.filterFns as | Record> | undefined const firstRow = column.table.getCoreRowModel().flatRows[0] const value = firstRow ? firstRow.getValue(column.id) : undefined if (typeof value === 'string') { return filterFns?.includesString } if (typeof value === 'number') { return filterFns?.inNumberRange } if (typeof value === 'boolean') { return filterFns?.equals } if (value !== null && typeof value === 'object') { return filterFns?.equals } if (Array.isArray(value)) { return filterFns?.arrIncludes } return filterFns?.weakEquals } export function column_getFilterFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, ): FilterFn | undefined { let filterFn = null const filterFns = column.table._rowModelFns.filterFns as | Record> | undefined filterFn = isFunction(column.columnDef.filterFn) ? column.columnDef.filterFn : column.columnDef.filterFn === 'auto' ? column_getAutoFilterFn(column) : filterFns?.[column.columnDef.filterFn as string] if (process.env.NODE_ENV === 'development' && !filterFn) { console.warn( `Could not find a valid 'column.filterFn' for column with the ID: ${column.id}.`, ) } return filterFn } export function column_getCanFilter< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return ( (column.columnDef.enableColumnFilter ?? true) && (column.table.options.enableColumnFilters ?? true) && (column.table.options.enableFilters ?? true) && !!column.accessorFn ) } export function column_getIsFiltered< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return column_getFilterIndex(column) > -1 } export function column_getFilterValue< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return column.table.store.state.columnFilters?.find((d) => d.id === column.id) ?.value } export function column_getFilterIndex< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): number { return ( column.table.store.state.columnFilters?.findIndex( (d) => d.id === column.id, ) ?? -1 ) } export function column_setFilterValue< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal, value: any) { table_setColumnFilters(column.table, (old) => { const filterFn = column_getFilterFn(column) const previousFilter = old.find((d) => d.id === column.id) const newFilter = functionalUpdate( value, previousFilter ? previousFilter.value : undefined, ) if (shouldAutoRemoveFilter(filterFn, newFilter, column)) { return old.filter((d) => d.id !== column.id) } const newFilterObj = { id: column.id, value: newFilter } if (previousFilter) { return old.map((d) => { if (d.id === column.id) { return newFilterObj } return d }) } if (old.length) { return [...old, newFilterObj] } return [newFilterObj] }) } export function table_setColumnFilters< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ) { const leafColumns = table.getAllLeafColumns() const updateFn = (old: ColumnFiltersState) => { return functionalUpdate(updater, old).filter((filter) => { const column = leafColumns.find((d) => d.id === filter.id) if (column) { const filterFn = column_getFilterFn(column) if (shouldAutoRemoveFilter(filterFn, filter.value, column)) { return false } } return true }) } table.options.onColumnFiltersChange?.(updateFn) } export function table_resetColumnFilters< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setColumnFilters( table, defaultState ? [] : (table.initialState.columnFilters ?? []), ) } export function shouldAutoRemoveFilter< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( filterFn?: FilterFn, value?: any, column?: Column_Internal, ) { return ( (filterFn && filterFn.autoRemove ? filterFn.autoRemove( value, column as Column_Internal, ) : false) || typeof value === 'undefined' || (typeof value === 'string' && !value) ) } ================================================ FILE: packages/table-core/src/features/column-filtering/createFilteredRowModel.ts ================================================ import { tableMemo } from '../../utils' import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils' import { column_getCanGlobalFilter, table_getGlobalFilterFn, } from '../global-filtering/globalFilteringFeature.utils' import { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils' import { filterRows } from './filterRowsUtils' import { column_getFilterFn } from './columnFilteringFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table, Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { FilterFn, FilterFns, ResolvedColumnFilter, Row_ColumnFiltering, } from './columnFilteringFeature.types' export function createFilteredRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >( filterFns: Record>, ): (table: Table) => () => RowModel { return (_table) => { const table = _table as Table_Internal if (!table._rowModelFns.filterFns) table._rowModelFns.filterFns = filterFns return tableMemo({ feature: 'columnFilteringFeature', table, fnName: 'table.getFilteredRowModel', memoDeps: () => [ table.getPreFilteredRowModel(), table.store.state.columnFilters, table.store.state.globalFilter, ], fn: () => _createFilteredRowModel(table), onAfterUpdate: () => table_autoResetPageIndex(table), }) } } function _createFilteredRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(table: Table_Internal): RowModel { const rowModel = table.getPreFilteredRowModel() const { columnFilters, globalFilter } = table.store.state if (!rowModel.rows.length || (!columnFilters?.length && !globalFilter)) { for (const row of rowModel.flatRows as Array< Row & Partial> >) { row.columnFilters = {} row.columnFiltersMeta = {} } return rowModel } const resolvedColumnFilters: Array> = [] const resolvedGlobalFilters: Array> = [] columnFilters?.forEach((columnFilter) => { const column = table_getColumn(table, columnFilter.id) if (!column) { return } const filterFn = column_getFilterFn(column)! resolvedColumnFilters.push({ id: columnFilter.id, filterFn, resolvedValue: filterFn.resolveFilterValue?.(columnFilter.value) ?? columnFilter.value, }) }) const filterableIds = columnFilters?.map((d) => d.id) ?? [] const globalFilterFn = table_getGlobalFilterFn(table) const globallyFilterableColumns = table .getAllLeafColumns() .filter((column) => column_getCanGlobalFilter(column)) if (globalFilter && globalFilterFn && globallyFilterableColumns.length) { filterableIds.push('__global__') globallyFilterableColumns.forEach((column) => { resolvedGlobalFilters.push({ id: column.id, filterFn: globalFilterFn, resolvedValue: globalFilterFn.resolveFilterValue?.(globalFilter) ?? globalFilter, }) }) } // Flag the pre-filtered row model with each filter state for (const row of rowModel.flatRows as Array< Row & Partial> >) { row.columnFilters = {} if (resolvedColumnFilters.length) { for (const currentColumnFilter of resolvedColumnFilters) { const id = currentColumnFilter.id // Tag the row with the column filter state row.columnFilters[id] = currentColumnFilter.filterFn( row, id, currentColumnFilter.resolvedValue, (filterMeta) => { !row.columnFiltersMeta ? (row.columnFiltersMeta = {}) : (row.columnFiltersMeta[id] = filterMeta) }, ) } } if (resolvedGlobalFilters.length) { for (const currentGlobalFilter of resolvedGlobalFilters) { const id = currentGlobalFilter.id // Tag the row with the first truthy global filter state if ( currentGlobalFilter.filterFn( row, id, currentGlobalFilter.resolvedValue, (filterMeta) => { !row.columnFiltersMeta ? (row.columnFiltersMeta = {}) : (row.columnFiltersMeta[id] = filterMeta) }, ) ) { row.columnFilters.__global__ = true break } } if (row.columnFilters.__global__ !== true) { row.columnFilters.__global__ = false } } } const filterRowsImpl = ( row: Row & Row_ColumnFiltering, ) => { // Horizontally filter rows through each column for (const columnId of filterableIds) { if (row.columnFilters[columnId] === false) { return false } } return true } // Filter final rows using all of the active filters return filterRows(rowModel.rows, filterRowsImpl as any, table) } ================================================ FILE: packages/table-core/src/features/column-filtering/filterRowsUtils.ts ================================================ import { constructRow } from '../../core/rows/constructRow' import type { Row_ColumnFiltering } from './columnFilteringFeature.types' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Row } from '../../types/Row' import type { Table_Internal } from '../../types/Table' import type { TableFeatures } from '../../types/TableFeatures' import type { RowData } from '../../types/type-utils' export function filterRows< TFeatures extends TableFeatures, TData extends RowData, >( rows: Array>, filterRowImpl: (row: Row) => any, table: Table_Internal, ) { if (table.options.filterFromLeafRows) { return filterRowModelFromLeafs(rows, filterRowImpl, table) } return filterRowModelFromRoot(rows, filterRowImpl, table) } function filterRowModelFromLeafs< TFeatures extends TableFeatures, TData extends RowData, >( rowsToFilter: Array>, filterRow: ( row: Row, ) => Array> | undefined, table: Table_Internal, ): RowModel { const newFilteredFlatRows: Array> = [] const newFilteredRowsById: Record> = {} const maxDepth = table.options.maxLeafRowFilterDepth ?? 100 const recurseFilterRows = ( rowsToFilter: Array< Row & Partial> >, depth = 0, ) => { const filteredRows: Array> & Partial> = [] // Filter from children up first for (let row of rowsToFilter) { const newRow = constructRow( table, row.id, row.original, row.index, row.depth, undefined, row.parentId, ) as Row & Partial> newRow.columnFilters = row.columnFilters if (row.subRows.length && depth < maxDepth) { newRow.subRows = recurseFilterRows(row.subRows, depth + 1) row = newRow if (filterRow(row) && !newRow.subRows.length) { filteredRows.push(row) newFilteredRowsById[row.id] = row newFilteredFlatRows.push(row) continue } if (filterRow(row) || newRow.subRows.length) { filteredRows.push(row) newFilteredRowsById[row.id] = row newFilteredFlatRows.push(row) continue } } else { row = newRow if (filterRow(row)) { filteredRows.push(row) newFilteredRowsById[row.id] = row newFilteredFlatRows.push(row) } } } return filteredRows } return { rows: recurseFilterRows(rowsToFilter), flatRows: newFilteredFlatRows, rowsById: newFilteredRowsById, } } function filterRowModelFromRoot< TFeatures extends TableFeatures, TData extends RowData, >( rowsToFilter: Array>, filterRow: (row: Row) => any, table: Table_Internal, ): RowModel { const newFilteredFlatRows: Array> = [] const newFilteredRowsById: Record> = {} const maxDepth = table.options.maxLeafRowFilterDepth ?? 100 // Filters top level and nested rows const recurseFilterRows = ( rowsToFilter: Array>, depth = 0, ) => { // Filter from parents downward first const filteredRows: Array> = [] // Apply the filter to any subRows for (let row of rowsToFilter) { const pass = filterRow(row) if (pass) { if (row.subRows.length && depth < maxDepth) { const newRow = constructRow( table, row.id, row.original, row.index, row.depth, undefined, row.parentId, ) newRow.subRows = recurseFilterRows(row.subRows, depth + 1) row = newRow } filteredRows.push(row) newFilteredFlatRows.push(row) newFilteredRowsById[row.id] = row } } return filteredRows } return { rows: recurseFilterRows(rowsToFilter), flatRows: newFilteredFlatRows, rowsById: newFilteredRowsById, } } ================================================ FILE: packages/table-core/src/features/column-grouping/columnGroupingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { cell_getIsAggregated, cell_getIsGrouped, cell_getIsPlaceholder, column_getAggregationFn, column_getAutoAggregationFn, column_getCanGroup, column_getGroupedIndex, column_getIsGrouped, column_getToggleGroupingHandler, column_toggleGrouping, getDefaultGroupingState, row_getGroupingValue, row_getIsGrouped, table_resetGrouping, table_setGrouping, } from './columnGroupingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // CachedRowModel_Grouped, // Cell_ColumnGrouping, // ColumnDef_ColumnGrouping, // Column_ColumnGrouping, // CreateRowModel_Grouped, // RowModelFns_ColumnGrouping, // Row_ColumnGrouping, // TableOptions_ColumnGrouping, // TableState_ColumnGrouping, // Table_ColumnGrouping, // } from './columnGroupingFeature.types' interface ColumnGroupingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // CachedRowModel: CachedRowModel_Grouped // Cell: Cell_ColumnGrouping // Column: Column_ColumnGrouping // ColumnDef: ColumnDef_ColumnGrouping // CreateRowModels: CreateRowModel_Grouped // Row: Row_ColumnGrouping // RowModelFns: RowModelFns_ColumnGrouping // Table: Table_ColumnGrouping // TableOptions: TableOptions_ColumnGrouping // TableState: TableState_ColumnGrouping } export function constructColumnGroupingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { grouping: getDefaultGroupingState(), ...initialState, } }, getDefaultColumnDef: () => { return { aggregatedCell: ({ getValue }: any) => getValue()?.toString?.() ?? null, aggregationFn: 'auto', } }, getDefaultTableOptions: (table) => { return { onGroupingChange: makeStateUpdater('grouping', table), groupedColumnMode: 'reorder', } }, assignCellPrototype: (prototype, table) => { assignPrototypeAPIs('columnGroupingFeature', prototype, table, { cell_getIsGrouped: { fn: (cell) => cell_getIsGrouped(cell), }, cell_getIsPlaceholder: { fn: (cell) => cell_getIsPlaceholder(cell), }, cell_getIsAggregated: { fn: (cell) => cell_getIsAggregated(cell), }, }) }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnGroupingFeature', prototype, table, { column_toggleGrouping: { fn: (column) => column_toggleGrouping(column), }, column_getCanGroup: { fn: (column) => column_getCanGroup(column), }, column_getIsGrouped: { fn: (column) => column_getIsGrouped(column), }, column_getGroupedIndex: { fn: (column) => column_getGroupedIndex(column), }, column_getToggleGroupingHandler: { fn: (column) => column_getToggleGroupingHandler(column), }, column_getAutoAggregationFn: { fn: (column) => column_getAutoAggregationFn(column), }, column_getAggregationFn: { fn: (column) => column_getAggregationFn(column), }, }) }, assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('columnGroupingFeature', prototype, table, { row_getIsGrouped: { fn: (row) => row_getIsGrouped(row), }, row_getGroupingValue: { fn: (row, columnId) => row_getGroupingValue(row, columnId), }, }) }, initRowInstanceData: (row) => { ;(row as any)._groupingValuesCache = {} }, constructTableAPIs: (table) => { assignTableAPIs('columnGroupingFeature', table, { table_setGrouping: { fn: (updater) => table_setGrouping(table, updater), }, table_resetGrouping: { fn: (defaultState) => table_resetGrouping(table, defaultState), }, }) }, } } /** * The (Column) Grouping feature adds column grouping state and APIs to the table, row, column, and cell objects. */ export const columnGroupingFeature = constructColumnGroupingFeature() ================================================ FILE: packages/table-core/src/features/column-grouping/columnGroupingFeature.types.ts ================================================ import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table } from '../../types/Table' import type { BuiltInAggregationFn } from '../../fns/aggregationFns' import type { CellData, OnChangeFn, RowData, Updater, } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' import type { Cell } from '../../types/Cell' import type { ColumnDefTemplate } from '../../types/ColumnDef' export type GroupingState = Array export interface TableState_ColumnGrouping { grouping: GroupingState } export interface RowModelFns_ColumnGrouping< TFeatures extends TableFeatures, TData extends RowData, > { aggregationFns: Record> } export interface AggregationFns {} export type AggregationFn< TFeatures extends TableFeatures, TData extends RowData, > = ( columnId: string, leafRows: Array>, childRows: Array>, ) => any export type CustomAggregationFns< TFeatures extends TableFeatures, TData extends RowData, > = Record> export type AggregationFnOption< TFeatures extends TableFeatures, TData extends RowData, > = | 'auto' | keyof AggregationFns | BuiltInAggregationFn | AggregationFn export interface ColumnDef_ColumnGrouping< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { /** * The cell to display each row for the column if the cell is an aggregate. If a function is passed, it will be passed a props object with the context of the cell and should return the property type for your adapter (the exact type depends on the adapter being used). */ aggregatedCell?: ColumnDefTemplate< ReturnType['getContext']> > /** * The resolved aggregation function for the column. */ aggregationFn?: AggregationFnOption /** * Enables/disables grouping for this column. */ enableGrouping?: boolean /** * Specify a value to be used for grouping rows on this column. If this option is not specified, the value derived from `accessorKey` / `accessorFn` will be used instead. */ getGroupingValue?: (row: TData) => any } export interface Column_ColumnGrouping< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the aggregation function for the column. */ getAggregationFn: () => AggregationFn | undefined /** * Returns the automatically inferred aggregation function for the column. */ getAutoAggregationFn: () => AggregationFn | undefined /** * Returns whether or not the column can be grouped. */ getCanGroup: () => boolean /** * Returns the index of the column in the grouping state. */ getGroupedIndex: () => number /** * Returns whether or not the column is currently grouped. */ getIsGrouped: () => boolean /** * Returns a function that toggles the grouping state of the column. This is useful for passing to the `onClick` prop of a button. */ getToggleGroupingHandler: () => () => void /** * Toggles the grouping state of the column. */ toggleGrouping: () => void } export interface Row_ColumnGrouping { _groupingValuesCache: Record /** * Returns the grouping value for any row and column (including leaf rows). */ getGroupingValue: (columnId: string) => unknown /** * Returns whether or not the row is currently grouped. */ getIsGrouped: () => boolean /** * If this row is grouped, this is the id of the column that this row is grouped by. */ groupingColumnId?: string /** * If this row is grouped, this is the unique/shared value for the `groupingColumnId` for all of the rows in this group. */ groupingValue?: unknown } export interface Cell_ColumnGrouping { /** * Returns whether or not the cell is currently aggregated. */ getIsAggregated: () => boolean /** * Returns whether or not the cell is currently grouped. */ getIsGrouped: () => boolean /** * Returns whether or not the cell is currently a placeholder cell. */ getIsPlaceholder: () => boolean } export interface ColumnDefaultOptions { enableGrouping: boolean onGroupingChange: OnChangeFn } export interface TableOptions_ColumnGrouping { /** * Enables/disables grouping for the table. */ enableGrouping?: boolean /** * Grouping columns are automatically reordered by default to the start of the columns list. If you would rather remove them or leave them as-is, set the appropriate mode here. */ groupedColumnMode?: false | 'reorder' | 'remove' /** * Enables manual grouping. If this option is set to `true`, the table will not automatically group rows using `getGroupedRowModel()` and instead will expect you to manually group the rows before passing them to the table. This is useful if you are doing server-side grouping and aggregation. */ manualGrouping?: boolean /** * If this function is provided, it will be called when the grouping state changes and you will be expected to manage the state yourself. You can pass the managed state back to the table via the `tableOptions.state.grouping` option. */ onGroupingChange?: OnChangeFn } export type GroupingColumnMode = false | 'reorder' | 'remove' export interface Table_ColumnGrouping< TFeatures extends TableFeatures, TData extends RowData, > { /** * Resets the **grouping** state to `initialState.grouping`, or `true` can be passed to force a default blank state reset to `[]`. */ resetGrouping: (defaultState?: boolean) => void /** * Updates the grouping state of the table via an update function or value. */ setGrouping: (updater: Updater) => void } export interface Table_RowModels_Grouped< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model for the table after grouping has been applied. */ getGroupedRowModel: () => RowModel /** * Returns the row model for the table before any grouping has been applied. */ getPreGroupedRowModel: () => RowModel } export interface CreateRowModel_Grouped< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model after grouping has taken place, but no further. */ groupedRowModel?: ( table: Table, ) => () => RowModel } export interface CachedRowModel_Grouped< TFeatures extends TableFeatures, TData extends RowData, > { groupedRowModel: () => RowModel } ================================================ FILE: packages/table-core/src/features/column-grouping/columnGroupingFeature.utils.ts ================================================ import { isFunction } from '../../utils' import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils' import type { Column_Internal } from '../../types/Column' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { Cell } from '../../types/Cell' import type { AggregationFn, GroupingState, Row_ColumnGrouping, } from './columnGroupingFeature.types' export function getDefaultGroupingState(): GroupingState { return structuredClone([]) } export function column_toggleGrouping< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { table_setGrouping(column.table, (old) => { // Find any existing grouping for this column if (old.includes(column.id)) { return old.filter((d) => d !== column.id) } return [...old, column.id] }) } export function column_getCanGroup< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return ( (column.columnDef.enableGrouping ?? true) && (column.table.options.enableGrouping ?? true) && (!!column.accessorFn || !!column.columnDef.getGroupingValue) ) } export function column_getIsGrouped< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): boolean { return !!column.table.store.state.grouping?.includes(column.id) } export function column_getGroupedIndex< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): number { return column.table.store.state.grouping?.indexOf(column.id) ?? -1 } export function column_getToggleGroupingHandler< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const canGroup = column_getCanGroup(column) return () => { if (!canGroup) return column_toggleGrouping(column) } } export function column_getAutoAggregationFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const aggregationFns = column.table._rowModelFns.aggregationFns as | Record> | undefined const firstRow = column.table.getCoreRowModel().flatRows[0] const value = firstRow?.getValue(column.id) if (typeof value === 'number') { return aggregationFns?.sum } if (Object.prototype.toString.call(value) === '[object Date]') { return aggregationFns?.extent } } export function column_getAggregationFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const aggregationFns = column.table._rowModelFns.aggregationFns as | Record> | undefined return isFunction(column.columnDef.aggregationFn) ? column.columnDef.aggregationFn : column.columnDef.aggregationFn === 'auto' ? column_getAutoAggregationFn(column) : aggregationFns?.[column.columnDef.aggregationFn as string] } export function table_setGrouping< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { table.options.onGroupingChange?.(updater) } export function table_resetGrouping< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setGrouping( table, defaultState ? [] : (table.initialState.grouping ?? []), ) } export function row_getIsGrouped< TFeatures extends TableFeatures, TData extends RowData, >(row: Row & Partial) { return !!row.groupingColumnId } export function row_getGroupingValue< TFeatures extends TableFeatures, TData extends RowData, >(row: Row & Partial, columnId: string) { if (row._groupingValuesCache?.hasOwnProperty(columnId)) { return row._groupingValuesCache[columnId] } const column = table_getColumn(row.table, columnId) as Column_Internal< TFeatures, TData > if (!column.columnDef.getGroupingValue) { return row.getValue(columnId) } if (row._groupingValuesCache) { row._groupingValuesCache[columnId] = column.columnDef.getGroupingValue( row.original, ) } return row._groupingValuesCache?.[columnId] } export function cell_getIsGrouped< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(cell: Cell) { const row = cell.row as Row & Partial return ( column_getIsGrouped(cell.column) && cell.column.id === row.groupingColumnId ) } export function cell_getIsPlaceholder< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(cell: Cell) { return !cell_getIsGrouped(cell) && column_getIsGrouped(cell.column) } export function cell_getIsAggregated< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(cell: Cell) { return ( !cell_getIsGrouped(cell) && !cell_getIsPlaceholder(cell) && !!cell.row.subRows.length ) } ================================================ FILE: packages/table-core/src/features/column-grouping/createGroupedRowModel.ts ================================================ import { flattenBy, tableMemo } from '../../utils' import { constructRow } from '../../core/rows/constructRow' import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils' import { table_autoResetExpanded } from '../row-expanding/rowExpandingFeature.utils' import { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils' import { column_getAggregationFn, row_getGroupingValue, } from './columnGroupingFeature.utils' import type { Column } from '../../types/Column' import type { AggregationFn, AggregationFns, Row_ColumnGrouping, } from './columnGroupingFeature.types' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table, Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { RowData } from '../../types/type-utils' export function createGroupedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >( aggregationFns: Record>, ): (table: Table) => () => RowModel { return (_table) => { const table = _table as Table_Internal if (!table._rowModelFns.aggregationFns) table._rowModelFns.aggregationFns = aggregationFns return tableMemo({ feature: 'columnGroupingFeature', table, fnName: 'table.getGroupedRowModel', memoDeps: () => [ table.store.state.grouping, table.getPreGroupedRowModel(), ], fn: () => _createGroupedRowModel(table), onAfterUpdate: () => { table_autoResetExpanded(table) table_autoResetPageIndex(table) }, }) } } function _createGroupedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(table: Table_Internal): RowModel { const rowModel = table.getPreGroupedRowModel() const grouping = table.store.state.grouping if (!rowModel.rows.length || !grouping?.length) { rowModel.rows.forEach((row) => { row.depth = 0 row.parentId = undefined }) return rowModel } // Filter the grouping list down to columns that exist const existingGrouping = grouping.filter((columnId) => table_getColumn(table, columnId), ) const groupedFlatRows: Array> & Partial = [] const groupedRowsById: Record> = {} // Recursively group the data const groupUpRecursively = ( rows: Array>, depth = 0, parentId?: string, ) => { // Grouping depth has been been met // Stop grouping and simply rewrite thd depth and row relationships if (depth >= existingGrouping.length) { return rows.map((row) => { row.depth = depth groupedFlatRows.push(row) groupedRowsById[row.id] = row if (row.subRows.length) { row.subRows = groupUpRecursively(row.subRows, depth + 1, row.id) } return row }) } const columnId = existingGrouping[depth] as string // Group the rows together for this level const rowGroupsMap = groupBy(rows, columnId) // Perform aggregations for each group const aggregatedGroupedRows = Array.from(rowGroupsMap.entries()).map( ([groupingValue, groupedRows], index) => { let id = `${columnId}:${groupingValue}` id = parentId ? `${parentId}>${id}` : id // First, Recurse to group sub rows before aggregation const subRows = groupUpRecursively(groupedRows, depth + 1, id) subRows.forEach((subRow) => { subRow.parentId = id }) // Flatten the leaf rows of the rows in this group const leafRows = depth ? flattenBy(groupedRows, (row) => row.subRows) : groupedRows const row = constructRow( table, id, leafRows[0]!.original, index, depth, undefined, parentId, ) as Row & Partial Object.assign(row, { groupingColumnId: columnId, groupingValue, subRows, leafRows, getValue: (colId: string) => { // Don't aggregate columns that are in the grouping if (existingGrouping.includes(colId)) { if (row._valuesCache.hasOwnProperty(colId)) { return row._valuesCache[colId] } if (groupedRows[0]) { row._valuesCache[colId] = groupedRows[0].getValue(colId) ?? undefined } return row._valuesCache[colId] } if (row._groupingValuesCache?.hasOwnProperty(colId)) { return row._groupingValuesCache[colId] } // Aggregate the values const column = table.getColumn(colId) const aggregateFn = column_getAggregationFn( column as Column, ) if (!row._groupingValuesCache) row._groupingValuesCache = {} if (aggregateFn) { row._groupingValuesCache[colId] = aggregateFn( colId, leafRows, groupedRows, ) return row._groupingValuesCache[colId] } }, }) subRows.forEach((subRow) => { groupedFlatRows.push(subRow) groupedRowsById[subRow.id] = subRow }) return row }, ) return aggregatedGroupedRows } const groupedRows = groupUpRecursively(rowModel.rows, 0) groupedRows.forEach((subRow) => { groupedFlatRows.push(subRow) groupedRowsById[subRow.id] = subRow }) return { rows: groupedRows, flatRows: groupedFlatRows, rowsById: groupedRowsById, } } function groupBy( rows: Array>, columnId: string, ) { const groupMap = new Map>>() return rows.reduce((map, row) => { const resKey = `${row_getGroupingValue(row, columnId)}` const previous = map.get(resKey) if (!previous) { map.set(resKey, [row]) } else { previous.push(row) } return map }, groupMap) } ================================================ FILE: packages/table-core/src/features/column-ordering/columnOrderingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { column_getIndex, column_getIsFirstColumn, column_getIsLastColumn, getDefaultColumnOrderState, table_getOrderColumnsFn, table_resetColumnOrder, table_setColumnOrder, } from './columnOrderingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // Column_ColumnOrdering, // TableOptions_ColumnOrdering, // TableState_ColumnOrdering, // Table_ColumnOrdering, // } from './columnOrderingFeature.types' interface ColumnOrderingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Column: Column_ColumnOrdering // Table: Table_ColumnOrdering // TableOptions: TableOptions_ColumnOrdering // TableState: TableState_ColumnOrdering } export function constructColumnOrderingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { columnOrder: getDefaultColumnOrderState(), ...initialState, } }, getDefaultTableOptions: (table) => { return { onColumnOrderChange: makeStateUpdater('columnOrder', table), } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnOrderingFeature', prototype, table, { column_getIndex: { fn: (column, position) => column_getIndex(column, position), memoDeps: (column, position) => [ position, column.table.store.state.columnOrder, column.table.store.state.columnPinning, column.table.store.state.grouping, ], }, column_getIsFirstColumn: { fn: (column, position) => column_getIsFirstColumn(column, position), }, column_getIsLastColumn: { fn: (column, position) => column_getIsLastColumn(column, position), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('columnOrderingFeature', table, { table_setColumnOrder: { fn: (updater) => table_setColumnOrder(table, updater), }, table_resetColumnOrder: { fn: (defaultState) => table_resetColumnOrder(table, defaultState), }, table_getOrderColumnsFn: { fn: () => table_getOrderColumnsFn(table), memoDeps: () => [ table.store.state.columnOrder, table.store.state.grouping, table.options.groupedColumnMode, ], }, }) }, } } /** * The Column Ordering feature adds column ordering state and APIs to the table and column objects. */ export const columnOrderingFeature = constructColumnOrderingFeature() ================================================ FILE: packages/table-core/src/features/column-ordering/columnOrderingFeature.types.ts ================================================ import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { ColumnPinningPosition } from '../column-pinning/columnPinningFeature.types' export type ColumnOrderState = Array export interface TableState_ColumnOrdering { columnOrder: ColumnOrderState } export interface TableOptions_ColumnOrdering { /** * If provided, this function will be called with an `updaterFn` when `state.columnOrder` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. */ onColumnOrderChange?: OnChangeFn } export interface Column_ColumnOrdering { /** * Returns the index of the column in the order of the visible columns. Optionally pass a `position` parameter to get the index of the column in a sub-section of the table */ getIndex: (position?: ColumnPinningPosition | 'center') => number /** * Returns `true` if the column is the first column in the order of the visible columns. Optionally pass a `position` parameter to check if the column is the first in a sub-section of the table. */ getIsFirstColumn: (position?: ColumnPinningPosition | 'center') => boolean /** * Returns `true` if the column is the last column in the order of the visible columns. Optionally pass a `position` parameter to check if the column is the last in a sub-section of the table. */ getIsLastColumn: (position?: ColumnPinningPosition | 'center') => boolean } export interface ColumnOrderDefaultOptions { onColumnOrderChange: OnChangeFn } export interface Table_ColumnOrdering< TFeatures extends TableFeatures, TData extends RowData, > { /** * Resets the **columnOrder** state to `initialState.columnOrder`, or `true` can be passed to force a default blank state reset to `[]`. */ resetColumnOrder: (defaultState?: boolean) => void /** * Sets or updates the `state.columnOrder` state. */ setColumnOrder: (updater: Updater) => void } ================================================ FILE: packages/table-core/src/features/column-ordering/columnOrderingFeature.utils.ts ================================================ import { table_getPinnedVisibleLeafColumns } from '../column-pinning/columnPinningFeature.utils' import type { GroupingState } from '../column-grouping/columnGroupingFeature.types' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Column_Internal } from '../../types/Column' import type { ColumnPinningPosition } from '../column-pinning/columnPinningFeature.types' import type { ColumnOrderState } from './columnOrderingFeature.types' export function getDefaultColumnOrderState(): ColumnOrderState { return structuredClone([]) } export function column_getIndex< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, position?: ColumnPinningPosition | 'center', ) { const columns = table_getPinnedVisibleLeafColumns(column.table, position) return columns.findIndex((d) => d.id === column.id) } export function column_getIsFirstColumn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, position?: ColumnPinningPosition | 'center', ) { const columns = table_getPinnedVisibleLeafColumns(column.table, position) return columns[0]?.id === column.id } export function column_getIsLastColumn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, position?: ColumnPinningPosition | 'center', ) { const columns = table_getPinnedVisibleLeafColumns(column.table, position) return columns[columns.length - 1]?.id === column.id } export function table_setColumnOrder< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { table.options.onColumnOrderChange?.(updater) } export function table_resetColumnOrder< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setColumnOrder( table, defaultState ? [] : (table.initialState.columnOrder ?? []), ) } export function table_getOrderColumnsFn< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const { columnOrder = [] } = table.store.state return (columns: Array>) => { // Sort grouped columns to the start of the column list // before the headers are built let orderedColumns: Array> = [] // If there is no order, return the normal columns if (!columnOrder.length) { orderedColumns = columns } else { const columnOrderCopy = [...columnOrder] // If there is an order, make a copy of the columns const columnsCopy = [...columns] // And make a new ordered array of the columns // Loop over the columns and place them in order into the new array while (columnsCopy.length && columnOrderCopy.length) { const targetColumnId = columnOrderCopy.shift() const foundIndex = columnsCopy.findIndex((d) => d.id === targetColumnId) if (foundIndex > -1) { orderedColumns.push(columnsCopy.splice(foundIndex, 1)[0]!) } } // If there are any columns left, add them to the end orderedColumns = [...orderedColumns, ...columnsCopy] } return orderColumns(table, orderedColumns) } } export function orderColumns< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, leafColumns: Array>, ) { const grouping = table.store.state.grouping ?? ([] as GroupingState) const { groupedColumnMode } = table.options if (!grouping.length || !groupedColumnMode) { return leafColumns } const nonGroupingColumns = leafColumns.filter( (col) => !grouping.includes(col.id), ) if (groupedColumnMode === 'remove') { return nonGroupingColumns } const groupingColumns = grouping .map((g) => leafColumns.find((col) => col.id === g)!) .filter(Boolean) return [...groupingColumns, ...nonGroupingColumns] } ================================================ FILE: packages/table-core/src/features/column-pinning/columnPinningFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, makeStateUpdater, } from '../../utils' import { table_getVisibleLeafColumns } from '../column-visibility/columnVisibilityFeature.utils' import { column_getCanPin, column_getIsPinned, column_getPinnedIndex, column_pin, getDefaultColumnPinningState, row_getCenterVisibleCells, row_getLeftVisibleCells, row_getRightVisibleCells, table_getCenterFlatHeaders, table_getCenterFooterGroups, table_getCenterHeaderGroups, table_getCenterLeafColumns, table_getCenterLeafHeaders, table_getCenterVisibleLeafColumns, table_getIsSomeColumnsPinned, table_getLeftFlatHeaders, table_getLeftFooterGroups, table_getLeftHeaderGroups, table_getLeftLeafColumns, table_getLeftLeafHeaders, table_getLeftVisibleLeafColumns, table_getRightFlatHeaders, table_getRightFooterGroups, table_getRightHeaderGroups, table_getRightLeafColumns, table_getRightLeafHeaders, table_getRightVisibleLeafColumns, table_resetColumnPinning, table_setColumnPinning, } from './columnPinningFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // ColumnDef_ColumnPinning, // Column_ColumnPinning, // Row_ColumnPinning, // TableOptions_ColumnPinning, // TableState_ColumnPinning, // Table_ColumnPinning, // } from './columnPinningFeature.types' interface ColumnPinningFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Column: Column_ColumnPinning // ColumnDef: ColumnDef_ColumnPinning // Row: Row_ColumnPinning // Table: Table_ColumnPinning // TableOptions: TableOptions_ColumnPinning // TableState: TableState_ColumnPinning } export function constructColumnPinningFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { columnPinning: { ...getDefaultColumnPinningState(), ...initialState.columnPinning, }, } }, getDefaultTableOptions: (table) => { return { onColumnPinningChange: makeStateUpdater('columnPinning', table), } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnPinningFeature', prototype, table, { column_pin: { fn: (column, position) => column_pin(column, position), }, column_getCanPin: { fn: (column) => column_getCanPin(column), }, column_getPinnedIndex: { fn: (column) => column_getPinnedIndex(column), }, column_getIsPinned: { fn: (column) => column_getIsPinned(column), }, }) }, assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('columnPinningFeature', prototype, table, { row_getCenterVisibleCells: { fn: (row) => row_getCenterVisibleCells(row), memoDeps: (row) => [ row.getAllCells(), row.table.store.state.columnPinning, row.table.store.state.columnVisibility, ], }, row_getLeftVisibleCells: { fn: (row) => row_getLeftVisibleCells(row), memoDeps: (row) => [ row.getAllCells(), row.table.store.state.columnPinning?.left, row.table.store.state.columnVisibility, ], }, row_getRightVisibleCells: { fn: (row) => row_getRightVisibleCells(row), memoDeps: (row) => [ row.getAllCells(), row.table.store.state.columnPinning?.right, row.table.store.state.columnVisibility, ], }, }) }, constructTableAPIs: (table) => { assignTableAPIs('columnPinningFeature', table, { table_setColumnPinning: { fn: (updater) => table_setColumnPinning(table, updater), }, table_resetColumnPinning: { fn: (defaultState) => table_resetColumnPinning(table, defaultState), }, table_getIsSomeColumnsPinned: { fn: (position) => table_getIsSomeColumnsPinned(table, position), }, // header groups table_getLeftHeaderGroups: { fn: () => table_getLeftHeaderGroups(table), memoDeps: () => [ table.getAllColumns(), callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ), table.store.state.columnPinning?.left, ], }, table_getCenterHeaderGroups: { fn: () => table_getCenterHeaderGroups(table), memoDeps: () => [ table.getAllColumns(), callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ), table.store.state.columnPinning, ], }, table_getRightHeaderGroups: { fn: () => table_getRightHeaderGroups(table), memoDeps: () => [ table.getAllColumns(), callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ), table.store.state.columnPinning?.right, ], }, // footer groups table_getLeftFooterGroups: { fn: () => table_getLeftFooterGroups(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ), ], }, table_getCenterFooterGroups: { fn: () => table_getCenterFooterGroups(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ), ], }, table_getRightFooterGroups: { fn: () => table_getRightFooterGroups(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ), ], }, // flat headers table_getLeftFlatHeaders: { fn: () => table_getLeftFlatHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ), ], }, table_getRightFlatHeaders: { fn: () => table_getRightFlatHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ), ], }, table_getCenterFlatHeaders: { fn: () => table_getCenterFlatHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ), ], }, // leaf headers table_getLeftLeafHeaders: { fn: () => table_getLeftLeafHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ), ], }, table_getRightLeafHeaders: { fn: () => table_getRightLeafHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ), ], }, table_getCenterLeafHeaders: { fn: () => table_getCenterLeafHeaders(table), memoDeps: () => [ callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ), ], }, // leaf columns table_getLeftLeafColumns: { fn: () => table_getLeftLeafColumns(table), memoDeps: () => [ table.options.columns, table.store.state.columnPinning, ], }, table_getRightLeafColumns: { fn: () => table_getRightLeafColumns(table), memoDeps: () => [ table.options.columns, table.store.state.columnPinning, ], }, table_getCenterLeafColumns: { fn: () => table_getCenterLeafColumns(table), memoDeps: () => [ table.options.columns, table.store.state.columnPinning, ], }, // visible leaf columns table_getLeftVisibleLeafColumns: { fn: () => table_getLeftVisibleLeafColumns(table), memoDeps: () => [ table.options.columns, table.store.state.columnPinning, table.store.state.columnVisibility, ], }, table_getCenterVisibleLeafColumns: { fn: () => table_getCenterVisibleLeafColumns(table), memoDeps: () => [ table.options.columns, table.store.state.columnPinning, table.store.state.columnVisibility, ], }, table_getRightVisibleLeafColumns: { fn: () => table_getRightVisibleLeafColumns(table), memoDeps: () => [ table.options.columns, table.store.state.columnPinning, table.store.state.columnVisibility, ], }, }) }, } } /** * The Column Pinning feature adds column pinning state and APIs to the table, row, and column objects. */ export const columnPinningFeature = constructColumnPinningFeature() ================================================ FILE: packages/table-core/src/features/column-pinning/columnPinningFeature.types.ts ================================================ import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Cell } from '../../types/Cell' import type { Header } from '../../types/Header' import type { HeaderGroup } from '../../types/HeaderGroup' import type { Column } from '../../types/Column' export type ColumnPinningPosition = false | 'left' | 'right' export interface ColumnPinningState { left: Array right: Array } export interface TableState_ColumnPinning { columnPinning: ColumnPinningState } export interface TableOptions_ColumnPinning { /** * Enables/disables column pinning for the table. Defaults to `true`. */ enableColumnPinning?: boolean /** * If provided, this function will be called with an `updaterFn` when `state.columnPinning` changes. This overrides the default internal state management, so you will also need to supply `state.columnPinning` from your own managed state. */ onColumnPinningChange?: OnChangeFn } export interface ColumnPinningDefaultOptions { onColumnPinningChange: OnChangeFn } export interface ColumnDef_ColumnPinning { /** * Enables/disables column pinning for this column. Defaults to `true`. */ enablePinning?: boolean } export interface Column_ColumnPinning { /** * Returns whether or not the column can be pinned. */ getCanPin: () => boolean /** * Returns the pinned position of the column. (`'left'`, `'right'` or `false`) */ getIsPinned: () => ColumnPinningPosition /** * Returns the numeric pinned index of the column within a pinned column group. */ getPinnedIndex: () => number /** * Pins a column to the `'left'` or `'right'`, or unpins the column to the center if `false` is passed. */ pin: (position: ColumnPinningPosition) => void } export interface Row_ColumnPinning< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns all center pinned (unpinned) leaf cells in the row. */ getCenterVisibleCells: () => Array> /** * Returns all left pinned leaf cells in the row. */ getLeftVisibleCells: () => Array> /** * Returns all right pinned leaf cells in the row. */ getRightVisibleCells: () => Array> } export interface Table_ColumnPinning< TFeatures extends TableFeatures, TData extends RowData, > { /** * If pinning, returns headers for all columns that are not pinned, including parent headers. */ getCenterFlatHeaders: () => Array> /** * If pinning, returns the footer groups for columns that are not pinned. */ getCenterFooterGroups: () => Array> /** * If pinning, returns the header groups for columns that are not pinned. */ getCenterHeaderGroups: () => Array> /** * Returns all center pinned (unpinned) leaf columns. */ getCenterLeafColumns: () => Array> /** * If pinning, returns headers for all columns that are not pinned, (not including parent headers). */ getCenterLeafHeaders: () => Array> /** * If column pinning, returns a flat array of leaf-node columns that are visible in the unpinned/center portion of the table. */ getCenterVisibleLeafColumns: () => Array> /** * Returns whether or not any columns are pinned. Optionally specify to only check for pinned columns in either the `left` or `right` position. */ getIsSomeColumnsPinned: (position?: ColumnPinningPosition) => boolean /** * If pinning, returns headers for all left pinned columns in the table, including parent headers. */ getLeftFlatHeaders: () => Array> /** * If pinning, returns the footer groups for the left pinned columns. */ getLeftFooterGroups: () => Array> /** * If pinning, returns the header groups for the left pinned columns. */ getLeftHeaderGroups: () => Array> /** * Returns all left pinned leaf columns. */ getLeftLeafColumns: () => Array> /** * If pinning, returns headers for all left pinned leaf columns in the table, (not including parent headers). */ getLeftLeafHeaders: () => Array> /** * If column pinning, returns a flat array of leaf-node columns that are visible in the left portion of the table. */ getLeftVisibleLeafColumns: () => Array> /** * If pinning, returns headers for all right pinned columns in the table, including parent headers. */ getRightFlatHeaders: () => Array> /** * If pinning, returns the footer groups for the right pinned columns. */ getRightFooterGroups: () => Array> /** * If pinning, returns the header groups for the right pinned columns. */ getRightHeaderGroups: () => Array> /** * Returns all right pinned leaf columns. */ getRightLeafColumns: () => Array> /** * If pinning, returns headers for all right pinned leaf columns in the table, (not including parent headers). */ getRightLeafHeaders: () => Array> /** * If column pinning, returns a flat array of leaf-node columns that are visible in the right portion of the table. */ getRightVisibleLeafColumns: () => Array> /** * Resets the **columnPinning** state to `initialState.columnPinning`, or `true` can be passed to force a default blank state reset to `{ left: [], right: [], }`. */ resetColumnPinning: (defaultState?: boolean) => void /** * Sets or updates the `state.columnPinning` state. */ setColumnPinning: (updater: Updater) => void /** */ getPinnedLeafColumns: ( position: ColumnPinningPosition | 'center', ) => Array> /** */ getPinnedVisibleLeafColumns: ( position: ColumnPinningPosition | 'center', ) => Array> } ================================================ FILE: packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts ================================================ import { column_getIsVisible, row_getAllVisibleCells, table_getVisibleLeafColumns, } from '../column-visibility/columnVisibilityFeature.utils' import { buildHeaderGroups } from '../../core/headers/buildHeaderGroups' import { callMemoOrStaticFn } from '../../utils' import type { HeaderGroup } from '../../types/HeaderGroup' import type { Cell } from '../../types/Cell' import type { Row } from '../../types/Row' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Column_Internal } from '../../types/Column' import type { ColumnPinningPosition, ColumnPinningState, } from './columnPinningFeature.types' // State export function getDefaultColumnPinningState(): ColumnPinningState { return structuredClone({ left: [], right: [], }) } // Column APIs export function column_pin< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, position: ColumnPinningPosition, ) { const columnIds = column .getLeafColumns() .map((d) => d.id) .filter(Boolean) table_setColumnPinning(column.table, (old) => { if (position === 'right') { return { left: old.left.filter((d) => !columnIds.includes(d)), right: [ ...old.right.filter((d) => !columnIds.includes(d)), ...columnIds, ], } } if (position === 'left') { return { left: [...old.left.filter((d) => !columnIds.includes(d)), ...columnIds], right: old.right.filter((d) => !columnIds.includes(d)), } } return { left: old.left.filter((d) => !columnIds.includes(d)), right: old.right.filter((d) => !columnIds.includes(d)), } }) } export function column_getCanPin< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const leafColumns = column.getLeafColumns() as Array< Column_Internal > return leafColumns.some( (leafColumn) => (leafColumn.columnDef.enablePinning ?? true) && (column.table.options.enableColumnPinning ?? true), ) } export function column_getIsPinned< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, ): ColumnPinningPosition | false { const leafColumnIds = column.getLeafColumns().map((d) => d.id) const { left, right } = column.table.store.state.columnPinning ?? getDefaultColumnPinningState() const isLeft = leafColumnIds.some((d) => left.includes(d)) const isRight = leafColumnIds.some((d) => right.includes(d)) return isLeft ? 'left' : isRight ? 'right' : false } export function column_getPinnedIndex< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const position = column_getIsPinned(column) return position ? (column.table.store.state.columnPinning?.[position].indexOf(column.id) ?? -1) : 0 } // Row APIs export function row_getCenterVisibleCells< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const allCells = callMemoOrStaticFn( row, 'getAllVisibleCells', row_getAllVisibleCells, ) const { left, right } = row.table.store.state.columnPinning ?? getDefaultColumnPinningState() const leftAndRight: Array = [...left, ...right] return allCells.filter((d) => !leftAndRight.includes(d.column.id)) } export function row_getLeftVisibleCells< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): Array> { const allCells = callMemoOrStaticFn( row, 'getAllVisibleCells', row_getAllVisibleCells, ) const { left } = row.table.store.state.columnPinning ?? getDefaultColumnPinningState() const cells = left .map((columnId) => allCells.find((cell) => cell.column.id === columnId)!) .filter(Boolean) // Assign position property directly to preserve prototype chain cells.forEach((cell) => { cell.position = 'left' }) return cells as any } export function row_getRightVisibleCells< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const allCells = callMemoOrStaticFn( row, 'getAllVisibleCells', row_getAllVisibleCells, ) const { right } = row.table.store.state.columnPinning ?? getDefaultColumnPinningState() const cells = right .map((columnId) => allCells.find((cell) => cell.column.id === columnId)!) .filter(Boolean) // Assign position property directly to preserve prototype chain cells.forEach((cell) => { cell.position = 'right' }) return cells as any } // Table APIs export function table_setColumnPinning< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ) { table.options.onColumnPinningChange?.(updater) } export function table_resetColumnPinning< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setColumnPinning( table, defaultState ? getDefaultColumnPinningState() : (table.initialState.columnPinning ?? getDefaultColumnPinningState()), ) } export function table_getIsSomeColumnsPinned< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, position?: ColumnPinningPosition) { const pinningState = table.store.state.columnPinning if (!position) { return Boolean(pinningState?.left.length || pinningState?.right.length) } return Boolean(pinningState?.[position].length) } // header groups export function table_getLeftHeaderGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const allColumns = table.getAllColumns() const leafColumns = callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ) as Array> const { left } = table.store.state.columnPinning ?? getDefaultColumnPinningState() const orderedLeafColumns = left .map((columnId) => leafColumns.find((d) => d.id === columnId)!) .filter(Boolean) return buildHeaderGroups(allColumns, orderedLeafColumns, table, 'left') } export function table_getRightHeaderGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const allColumns = table.getAllColumns() const leafColumns = callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ) as unknown as Array> const { right } = table.store.state.columnPinning ?? getDefaultColumnPinningState() const orderedLeafColumns = right .map((columnId) => leafColumns.find((d) => d.id === columnId)!) .filter(Boolean) return buildHeaderGroups(allColumns, orderedLeafColumns, table, 'right') } export function table_getCenterHeaderGroups< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): Array> { const allColumns = table.getAllColumns() let leafColumns = callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ) as unknown as Array> const { left, right } = table.store.state.columnPinning ?? getDefaultColumnPinningState() const leftAndRight: Array = [...left, ...right] leafColumns = leafColumns.filter( (column) => !leftAndRight.includes(column.id), ) return buildHeaderGroups(allColumns, leafColumns, table, 'center') } // footer groups export function table_getLeftFooterGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const headerGroups = callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ) return [...headerGroups].reverse() } export function table_getRightFooterGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const headerGroups = callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ) return [...headerGroups].reverse() } export function table_getCenterFooterGroups< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const headerGroups = callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ) return [...headerGroups].reverse() } // flat headers export function table_getLeftFlatHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const leftHeaderGroups = callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, ) return leftHeaderGroups .map((headerGroup) => { return headerGroup.headers }) .flat() } export function table_getRightFlatHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const rightHeaderGroups = callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, ) return rightHeaderGroups .map((headerGroup) => { return headerGroup.headers }) .flat() } export function table_getCenterFlatHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const centerHeaderGroups = callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, ) return centerHeaderGroups .map((headerGroup) => { return headerGroup.headers }) .flat() } // leaf headers export function table_getLeftLeafHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return callMemoOrStaticFn( table, 'getLeftFlatHeaders', table_getLeftFlatHeaders, ).filter((header) => !header.subHeaders.length) } export function table_getRightLeafHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return callMemoOrStaticFn( table, 'getRightFlatHeaders', table_getRightFlatHeaders, ).filter((header) => !header.subHeaders.length) } export function table_getCenterLeafHeaders< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return callMemoOrStaticFn( table, 'getCenterFlatHeaders', table_getCenterFlatHeaders, ).filter((header) => !header.subHeaders.length) } // leaf columns export function table_getLeftLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const { left } = table.store.state.columnPinning ?? getDefaultColumnPinningState() return left .map( (columnId) => table.getAllLeafColumns().find((column) => column.id === columnId)!, ) .filter(Boolean) } export function table_getRightLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const { right } = table.store.state.columnPinning ?? getDefaultColumnPinningState() return right .map( (columnId) => table.getAllLeafColumns().find((column) => column.id === columnId)!, ) .filter(Boolean) } export function table_getCenterLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const { left, right } = table.store.state.columnPinning ?? getDefaultColumnPinningState() const leftAndRight: Array = [...left, ...right] return table.getAllLeafColumns().filter((d) => !leftAndRight.includes(d.id)) } export function table_getPinnedLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, position: ColumnPinningPosition | 'center', ) { return !position ? table.getAllLeafColumns() : position === 'left' ? callMemoOrStaticFn( table, 'getLeftLeafColumns', table_getLeftLeafColumns, ) : position === 'right' ? callMemoOrStaticFn( table, 'getRightLeafColumns', table_getRightLeafColumns, ) : callMemoOrStaticFn( table, 'getCenterLeafColumns', table_getCenterLeafColumns, ) } // visible leaf columns export function table_getLeftVisibleLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return callMemoOrStaticFn( table, 'getLeftLeafColumns', table_getLeftLeafColumns, ).filter((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_getRightVisibleLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return callMemoOrStaticFn( table, 'getRightLeafColumns', table_getRightLeafColumns, ).filter((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_getCenterVisibleLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return callMemoOrStaticFn( table, 'getCenterLeafColumns', table_getCenterLeafColumns, ).filter((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_getPinnedVisibleLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, position?: ColumnPinningPosition | 'center', ) { return !position ? callMemoOrStaticFn( table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, ) : position === 'left' ? callMemoOrStaticFn( table, 'getLeftVisibleLeafColumns', table_getLeftVisibleLeafColumns, ) : position === 'right' ? callMemoOrStaticFn( table, 'getRightVisibleLeafColumns', table_getRightVisibleLeafColumns, ) : callMemoOrStaticFn( table, 'getCenterVisibleLeafColumns', table_getCenterVisibleLeafColumns, ) } ================================================ FILE: packages/table-core/src/features/column-resizing/columnResizingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { column_getCanResize, column_getIsResizing, getDefaultColumnResizingState, header_getResizeHandler, table_resetHeaderSizeInfo, table_setColumnResizing, } from './columnResizingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // Column_ColumnResizing, // Header_ColumnResizing, // TableOptions_ColumnResizing, // TableState_ColumnResizing, // Table_ColumnResizing, // } from './columnResizingFeature.types' interface ColumnResizingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Column: Column_ColumnResizing // Header: Header_ColumnResizing // Table: Table_ColumnResizing // TableOptions: TableOptions_ColumnResizing // TableState: TableState_ColumnResizing } export function constructColumnResizingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { columnResizing: getDefaultColumnResizingState(), ...initialState, } }, getDefaultTableOptions: (table) => { return { columnResizeMode: 'onEnd', columnResizeDirection: 'ltr', onColumnResizingChange: makeStateUpdater('columnResizing', table), } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnResizingFeature', prototype, table, { column_getCanResize: { fn: (column) => column_getCanResize(column), }, column_getIsResizing: { fn: (column) => column_getIsResizing(column), }, }) }, assignHeaderPrototype: (prototype, table) => { assignPrototypeAPIs('columnResizingFeature', prototype, table, { header_getResizeHandler: { fn: (header, _contextDocument) => header_getResizeHandler(header, _contextDocument), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('columnResizingFeature', table, { table_setColumnResizing: { fn: (updater) => table_setColumnResizing(table, updater), }, table_resetHeaderSizeInfo: { fn: (defaultState) => table_resetHeaderSizeInfo(table, defaultState), }, }) }, } } /** * The Column Resizing feature adds column resizing state and APIs to the table and column objects. * **Note:** This is dependent on the Column Sizing feature. */ export const columnResizingFeature = constructColumnResizingFeature() ================================================ FILE: packages/table-core/src/features/column-resizing/columnResizingFeature.types.ts ================================================ import type { OnChangeFn, Updater } from '../../types/type-utils' export interface TableState_ColumnResizing { columnResizing: columnResizingState } export interface columnResizingState { columnSizingStart: Array<[string, number]> deltaOffset: null | number deltaPercentage: null | number isResizingColumn: false | string startOffset: null | number startSize: null | number } export type ColumnResizeMode = 'onChange' | 'onEnd' export type ColumnResizeDirection = 'ltr' | 'rtl' export interface TableOptions_ColumnResizing { /** * Determines when the columnSizing state is updated. `onChange` updates the state when the user is dragging the resize handle. `onEnd` updates the state when the user releases the resize handle. */ columnResizeMode?: ColumnResizeMode /** * Enables or disables column resizing for the column. */ enableColumnResizing?: boolean /** * Enables or disables right-to-left support for resizing the column. defaults to 'ltr'. */ columnResizeDirection?: ColumnResizeDirection /** * If provided, this function will be called with an `updaterFn` when `state.columnResizing` changes. This overrides the default internal state management, so you will also need to supply `state.columnResizing` from your own managed state. */ onColumnResizingChange?: OnChangeFn } export type ColumnResizingDefaultOptions = Pick< TableOptions_ColumnResizing, 'columnResizeMode' | 'onColumnResizingChange' | 'columnResizeDirection' > export interface Table_ColumnResizing { /** * Resets column sizing info to its initial state. If `defaultState` is `true`, the default state for the table will be used instead of the initialValue provided to the table. */ resetHeaderSizeInfo: (defaultState?: boolean) => void /** * Sets the column sizing info state using an updater function or a value. This will trigger the underlying `oncolumnResizingChange` function if one is passed to the table options, otherwise the state will be managed automatically by the table. */ setcolumnResizing: (updater: Updater) => void } export interface ColumnDef_ColumnResizing { /** * Enables or disables column resizing for the column. */ enableResizing?: boolean } export interface Column_ColumnResizing { /** * Returns `true` if the column can be resized. */ getCanResize: () => boolean /** * Returns `true` if the column is currently being resized. */ getIsResizing: () => boolean } export interface Header_ColumnResizing { /** * Returns an event handler function that can be used to resize the header. It can be used as an: * - `onMouseDown` handler * - `onTouchStart` handler * The dragging and release events are automatically handled for you. */ getResizeHandler: (context?: Document) => (event: unknown) => void } ================================================ FILE: packages/table-core/src/features/column-resizing/columnResizingFeature.utils.ts ================================================ import { column_getSize, header_getSize, table_setColumnSizing, } from '../column-sizing/columnSizingFeature.utils' import { table_getColumn } from '../../core/columns/coreColumnsFeature.utils' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Header } from '../../types/Header' import type { Column_Internal } from '../../types/Column' import type { ColumnSizingState } from '../column-sizing/columnSizingFeature.types' import type { columnResizingState } from './columnResizingFeature.types' export function getDefaultColumnResizingState(): columnResizingState { return structuredClone({ startOffset: null, startSize: null, deltaOffset: null, deltaPercentage: null, isResizingColumn: false, columnSizingStart: [], }) } export function column_getCanResize< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return ( (column.columnDef.enableResizing ?? true) && (column.table.options.enableColumnResizing ?? true) ) } export function column_getIsResizing< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return column.table.store.state.columnResizing?.isResizingColumn === column.id } export function header_getResizeHandler< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(header: Header, _contextDocument?: Document) { const column = table_getColumn(header.column.table, header.column.id)! const canResize = column_getCanResize(column) return (event: unknown) => { if (!canResize) { return } ;(event as any).persist?.() if (isTouchStartEvent(event)) { // lets not respond to multiple touches (e.g. 2 or 3 fingers) if (event.touches.length > 1) { return } } const startSize = header_getSize(header) const columnSizingStart: Array<[string, number]> = header .getLeafHeaders() .map((leafHeader) => [ leafHeader.column.id, column_getSize(leafHeader.column), ]) const clientX = isTouchStartEvent(event) ? Math.round(event.touches[0]!.clientX) : (event as MouseEvent).clientX const newColumnSizing: ColumnSizingState = {} const updateOffset = (eventType: 'move' | 'end', clientXPos?: number) => { if (typeof clientXPos !== 'number') { return } table_setColumnResizing(column.table, (old) => { const deltaDirection = column.table.options.columnResizeDirection === 'rtl' ? -1 : 1 const deltaOffset = (clientXPos - (old.startOffset ?? 0)) * deltaDirection const deltaPercentage = Math.max( deltaOffset / (old.startSize ?? 0), -0.999999, ) old.columnSizingStart.forEach(([columnId, headerSize]) => { newColumnSizing[columnId] = Math.round( Math.max(headerSize + headerSize * deltaPercentage, 0) * 100, ) / 100 }) return { ...old, deltaOffset, deltaPercentage, } }) if ( column.table.options.columnResizeMode === 'onChange' || eventType === 'end' ) { table_setColumnSizing(column.table, (old) => ({ ...old, ...newColumnSizing, })) } } const onMove = (clientXPos?: number) => updateOffset('move', clientXPos) const onEnd = (clientXPos?: number) => { updateOffset('end', clientXPos) table_setColumnResizing(column.table, (old) => ({ ...old, isResizingColumn: false, startOffset: null, startSize: null, deltaOffset: null, deltaPercentage: null, columnSizingStart: [], })) } const contextDocument = _contextDocument || typeof document !== 'undefined' ? document : null const mouseEvents = { moveHandler: (e: MouseEvent) => onMove(e.clientX), upHandler: (e: MouseEvent) => { contextDocument?.removeEventListener( 'mousemove', mouseEvents.moveHandler, ) contextDocument?.removeEventListener('mouseup', mouseEvents.upHandler) onEnd(e.clientX) }, } const touchEvents = { moveHandler: (touchEvent: TouchEvent) => { if (touchEvent.cancelable) { touchEvent.preventDefault() touchEvent.stopPropagation() } onMove(touchEvent.touches[0]!.clientX) return false }, upHandler: (e: TouchEvent) => { contextDocument?.removeEventListener( 'touchmove', touchEvents.moveHandler, ) contextDocument?.removeEventListener('touchend', touchEvents.upHandler) if (e.cancelable) { e.preventDefault() e.stopPropagation() } onEnd(e.touches[0]?.clientX) }, } const passiveIfSupported = passiveEventSupported() ? { passive: false } : false if (isTouchStartEvent(event)) { contextDocument?.addEventListener( 'touchmove', touchEvents.moveHandler, passiveIfSupported, ) contextDocument?.addEventListener( 'touchend', touchEvents.upHandler, passiveIfSupported, ) } else { contextDocument?.addEventListener( 'mousemove', mouseEvents.moveHandler, passiveIfSupported, ) contextDocument?.addEventListener( 'mouseup', mouseEvents.upHandler, passiveIfSupported, ) } table_setColumnResizing(column.table, (old) => ({ ...old, startOffset: clientX, startSize, deltaOffset: 0, deltaPercentage: 0, columnSizingStart, isResizingColumn: column.id, })) } } export function table_setColumnResizing< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ) { table.options.onColumnResizingChange?.(updater) } export function table_resetHeaderSizeInfo< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setColumnResizing( table, defaultState ? getDefaultColumnResizingState() : (table.initialState.columnResizing ?? getDefaultColumnResizingState()), ) } export function passiveEventSupported() { let passiveSupported: boolean | null = null if (typeof passiveSupported === 'boolean') return passiveSupported let supported = false try { const options = { get passive() { supported = true return false }, } const noop = () => {} window.addEventListener('test', noop, options) window.removeEventListener('test', noop) } catch (err) { supported = false } passiveSupported = supported return passiveSupported } export function isTouchStartEvent(e: unknown): e is TouchEvent { return (e as TouchEvent).type === 'touchstart' } ================================================ FILE: packages/table-core/src/features/column-sizing/columnSizingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, callMemoOrStaticFn, makeStateUpdater, } from '../../utils' import { table_getPinnedVisibleLeafColumns } from '../column-pinning/columnPinningFeature.utils' import { column_getAfter, column_getSize, column_getStart, column_resetSize, getDefaultColumnSizingColumnDef, getDefaultColumnSizingState, header_getSize, header_getStart, table_getCenterTotalSize, table_getLeftTotalSize, table_getRightTotalSize, table_getTotalSize, table_resetColumnSizing, table_setColumnSizing, } from './columnSizingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // ColumnDef_ColumnSizing, // Column_ColumnSizing, // Header_ColumnSizing, // TableOptions_ColumnSizing, // TableState_ColumnSizing, // Table_ColumnSizing, // } from './columnSizingFeature.types' interface ColumnSizingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // ColumnDef: ColumnDef_ColumnSizing // Column: Column_ColumnSizing // Header: Header_ColumnSizing // Table: Table_ColumnSizing // TableOptions: TableOptions_ColumnSizing // TableState: TableState_ColumnSizing } export function constructColumnSizingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { columnSizing: getDefaultColumnSizingState(), ...initialState, } }, getDefaultColumnDef: () => { return getDefaultColumnSizingColumnDef() }, getDefaultTableOptions: (table) => { return { onColumnSizingChange: makeStateUpdater('columnSizing', table), } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnSizingFeature', prototype, table, { column_getSize: { fn: (column) => column_getSize(column), }, column_getStart: { fn: (column, position) => column_getStart(column, position), memoDeps: (column, position) => [ position, callMemoOrStaticFn( column.table, 'getPinnedVisibleLeafColumns', table_getPinnedVisibleLeafColumns, position, ), column.table.store.state.columnSizing, ], }, column_getAfter: { fn: (column, position) => column_getAfter(column, position), memoDeps: (column, position) => [ position, callMemoOrStaticFn( column.table, 'getPinnedVisibleLeafColumns', table_getPinnedVisibleLeafColumns, position, ), column.table.store.state.columnSizing, ], }, column_resetSize: { fn: (column) => column_resetSize(column), }, }) }, assignHeaderPrototype: (prototype, table) => { assignPrototypeAPIs('columnSizingFeature', prototype, table, { header_getSize: { fn: (header) => header_getSize(header), }, header_getStart: { fn: (header) => header_getStart(header), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('columnSizingFeature', table, { table_setColumnSizing: { fn: (updater) => table_setColumnSizing(table, updater), }, table_resetColumnSizing: { fn: (defaultState) => table_resetColumnSizing(table, defaultState), }, table_getTotalSize: { fn: () => table_getTotalSize(table), }, table_getLeftTotalSize: { fn: () => table_getLeftTotalSize(table), }, table_getCenterTotalSize: { fn: () => table_getCenterTotalSize(table), }, table_getRightTotalSize: { fn: () => table_getRightTotalSize(table), }, }) }, } } /** * The Column Sizing feature adds column sizing state and APIs to the table, header, and column objects. * **Note:** This does not include column resizing. The columnResizingFeature feature has been split out into its own standalone feature. */ export const columnSizingFeature = constructColumnSizingFeature() ================================================ FILE: packages/table-core/src/features/column-sizing/columnSizingFeature.types.ts ================================================ import type { OnChangeFn, Updater } from '../../types/type-utils' import type { ColumnPinningPosition } from '../column-pinning/columnPinningFeature.types' export interface TableState_ColumnSizing { columnSizing: ColumnSizingState } export type ColumnSizingState = Record export interface TableOptions_ColumnSizing { /** * If provided, this function will be called with an `updaterFn` when `state.columnSizing` changes. This overrides the default internal state management, so you will also need to supply `state.columnSizing` from your own managed state. */ onColumnSizingChange?: OnChangeFn } export type ColumnSizingDefaultOptions = Pick< TableOptions_ColumnSizing, 'onColumnSizingChange' > export interface Table_ColumnSizing { /** * If pinning, returns the total size of the center portion of the table by calculating the sum of the sizes of all unpinned/center leaf-columns. */ getCenterTotalSize: () => number /** * Returns the total size of the left portion of the table by calculating the sum of the sizes of all left leaf-columns. */ getLeftTotalSize: () => number /** * Returns the total size of the right portion of the table by calculating the sum of the sizes of all right leaf-columns. */ getRightTotalSize: () => number /** * Returns the total size of the table by calculating the sum of the sizes of all leaf-columns. */ getTotalSize: () => number /** * Resets column sizing to its initial state. If `defaultState` is `true`, the default state for the table will be used instead of the initialValue provided to the table. */ resetColumnSizing: (defaultState?: boolean) => void /** * Sets the column sizing state using an updater function or a value. This will trigger the underlying `onColumnSizingChange` function if one is passed to the table options, otherwise the state will be managed automatically by the table. */ setColumnSizing: (updater: Updater) => void } export interface ColumnDef_ColumnSizing { /** * The maximum allowed size for the column */ maxSize?: number /** * The minimum allowed size for the column */ minSize?: number /** * The desired size for the column */ size?: number } export interface Column_ColumnSizing { /** * Returns the offset measurement along the row-axis (usually the x-axis for standard tables) for the header. This is effectively a sum of the offset measurements of all succeeding (right) headers in relation to the current column. */ getAfter: (position?: ColumnPinningPosition | 'center') => number /** * Returns the current size of the column. */ getSize: () => number /** * Returns the offset measurement along the row-axis (usually the x-axis for standard tables) for the header. This is effectively a sum of the offset measurements of all preceding (left) headers in relation to the current column. */ getStart: (position?: ColumnPinningPosition | 'center') => number /** * Resets the column to its initial size. */ resetSize: () => void } export interface Header_ColumnSizing { /** * Returns the current size of the header. */ getSize: () => number /** * Returns the offset measurement along the row-axis (usually the x-axis for standard tables) for the header. This is effectively a sum of the offset measurements of all preceding headers. */ getStart: (position?: ColumnPinningPosition) => number } ================================================ FILE: packages/table-core/src/features/column-sizing/columnSizingFeature.utils.ts ================================================ import { table_getCenterHeaderGroups, table_getLeftHeaderGroups, table_getPinnedVisibleLeafColumns, table_getRightHeaderGroups, } from '../column-pinning/columnPinningFeature.utils' import { column_getIndex } from '../column-ordering/columnOrderingFeature.utils' import { callMemoOrStaticFn } from '../../utils' import type { ColumnPinningPosition } from '../column-pinning/columnPinningFeature.types' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Header } from '../../types/Header' import type { Column_Internal } from '../../types/Column' import type { ColumnSizingState } from './columnSizingFeature.types' export function getDefaultColumnSizingState(): ColumnSizingState { return structuredClone({}) } export function getDefaultColumnSizingColumnDef() { return structuredClone({ size: 150, minSize: 20, maxSize: Number.MAX_SAFE_INTEGER, }) } export function column_getSize< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): number { const defaultSizes = getDefaultColumnSizingColumnDef() const columnSize = column.table.store.state.columnSizing?.[column.id] return Math.min( Math.max( column.columnDef.minSize ?? defaultSizes.minSize, columnSize ?? column.columnDef.size ?? defaultSizes.size, ), column.columnDef.maxSize ?? defaultSizes.maxSize, ) } export function column_getStart< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, position: ColumnPinningPosition | 'center', ): number { const visibleLeafColumns = callMemoOrStaticFn( column.table, 'getPinnedVisibleLeafColumns', table_getPinnedVisibleLeafColumns, position, ) return visibleLeafColumns .slice(0, callMemoOrStaticFn(column, 'getIndex', column_getIndex, position)) .reduce((sum: number, c) => sum + column_getSize(c), 0) } export function column_getAfter< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, position: ColumnPinningPosition | 'center', ): number { const visibleLeafColumns = callMemoOrStaticFn( column.table, 'getPinnedVisibleLeafColumns', table_getPinnedVisibleLeafColumns, position, ) return visibleLeafColumns .slice( callMemoOrStaticFn(column, 'getIndex', column_getIndex, position) + 1, ) .reduce((sum: number, c) => sum + column_getSize(c), 0) } export function column_resetSize< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { table_setColumnSizing(column.table, ({ [column.id]: _, ...rest }) => { return rest }) } export function header_getSize< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(header: Header) { let sum = 0 const recurse = (h: Header) => { if (h.subHeaders.length) { h.subHeaders.forEach(recurse) } else { sum += column_getSize(h.column) } } recurse(header) return sum } export function header_getStart< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(header: Header): number { if (header.index > 0) { const prevSiblingHeader = header.headerGroup?.headers[header.index - 1] if (prevSiblingHeader) { return ( header_getStart(prevSiblingHeader) + header_getSize(prevSiblingHeader) ) } } return 0 } // Table APIs export function table_setColumnSizing< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ) { table.options.onColumnSizingChange?.(updater) } export function table_resetColumnSizing< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setColumnSizing( table, defaultState ? {} : (table.initialState.columnSizing ?? {}), ) } export function table_getTotalSize< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return ( table.getHeaderGroups()[0]?.headers.reduce((sum, header) => { return sum + header_getSize(header) }, 0) ?? 0 ) } export function table_getLeftTotalSize< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return ( callMemoOrStaticFn( table, 'getLeftHeaderGroups', table_getLeftHeaderGroups, )[0]?.headers.reduce((sum: number, header: Header) => { return sum + header_getSize(header) }, 0) ?? 0 ) } export function table_getCenterTotalSize< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return ( callMemoOrStaticFn( table, 'getCenterHeaderGroups', table_getCenterHeaderGroups, )[0]?.headers.reduce((sum: number, header: Header) => { return sum + header_getSize(header) }, 0) ?? 0 ) } export function table_getRightTotalSize< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return ( callMemoOrStaticFn( table, 'getRightHeaderGroups', table_getRightHeaderGroups, )[0]?.headers.reduce((sum: number, header: Header) => { return sum + header_getSize(header) }, 0) ?? 0 ) } ================================================ FILE: packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { row_getCenterVisibleCells, row_getLeftVisibleCells, row_getRightVisibleCells, } from '../column-pinning/columnPinningFeature.utils' import { column_getCanHide, column_getIsVisible, column_getToggleVisibilityHandler, column_toggleVisibility, getDefaultColumnVisibilityState, row_getAllVisibleCells, row_getVisibleCells, table_getIsAllColumnsVisible, table_getIsSomeColumnsVisible, table_getToggleAllColumnsVisibilityHandler, table_getVisibleFlatColumns, table_getVisibleLeafColumns, table_resetColumnVisibility, table_setColumnVisibility, table_toggleAllColumnsVisible, } from './columnVisibilityFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // ColumnDef_ColumnVisibility, // Column_ColumnVisibility, // Row_ColumnVisibility, // TableOptions_ColumnVisibility, // TableState_ColumnVisibility, // Table_ColumnVisibility, // } from './columnVisibilityFeature.types' interface ColumnVisibilityFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // ColumnDef: ColumnDef_ColumnVisibility // Column: Column_ColumnVisibility // Row: Row_ColumnVisibility // Table: Table_ColumnVisibility // TableOptions: TableOptions_ColumnVisibility // TableState: TableState_ColumnVisibility } export function constructColumnVisibilityFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { columnVisibility: getDefaultColumnVisibilityState(), ...initialState, } }, getDefaultTableOptions: (table) => { return { onColumnVisibilityChange: makeStateUpdater('columnVisibility', table), } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { column_getIsVisible: { fn: (column) => column_getIsVisible(column), memoDeps: (column) => [ column.table.options.columns, column.table.store.state.columnVisibility, column.columns, ], }, column_getCanHide: { fn: (column) => column_getCanHide(column), }, column_getToggleVisibilityHandler: { fn: (column) => column_getToggleVisibilityHandler(column), }, column_toggleVisibility: { fn: (column, visible) => column_toggleVisibility(column, visible), }, }) }, assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { row_getAllVisibleCells: { fn: (row) => row_getAllVisibleCells(row), memoDeps: (row) => [ row.getAllCells(), row.table.store.state.columnVisibility, ], }, row_getVisibleCells: { fn: (row, left, center, right) => row_getVisibleCells(left, center, right), memoDeps: (row) => [ row_getLeftVisibleCells(row), row_getCenterVisibleCells(row), row_getRightVisibleCells(row), ], }, }) }, constructTableAPIs: (table) => { assignTableAPIs('columnVisibilityFeature', table, { table_getVisibleFlatColumns: { fn: () => table_getVisibleFlatColumns(table), memoDeps: () => [ table.store.state.columnVisibility, table.options.columns, ], }, table_getVisibleLeafColumns: { fn: () => table_getVisibleLeafColumns(table), memoDeps: () => [ table.store.state.columnVisibility, table.options.columns, ], }, table_setColumnVisibility: { fn: (updater) => table_setColumnVisibility(table, updater), }, table_resetColumnVisibility: { fn: (defaultState) => table_resetColumnVisibility(table, defaultState), }, table_toggleAllColumnsVisible: { fn: (value) => table_toggleAllColumnsVisible(table, value), }, table_getIsAllColumnsVisible: { fn: () => table_getIsAllColumnsVisible(table), }, table_getIsSomeColumnsVisible: { fn: () => table_getIsSomeColumnsVisible(table), }, table_getToggleAllColumnsVisibilityHandler: { fn: () => table_getToggleAllColumnsVisibilityHandler(table), }, }) }, } } /** * The Column Visibility feature adds column visibility state and APIs to the table, row, and column objects. */ export const columnVisibilityFeature = constructColumnVisibilityFeature() ================================================ FILE: packages/table-core/src/features/column-visibility/columnVisibilityFeature.types.ts ================================================ import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Cell } from '../../types/Cell' import type { Column } from '../../types/Column' export type ColumnVisibilityState = Record export interface TableState_ColumnVisibility { columnVisibility: ColumnVisibilityState } export interface TableOptions_ColumnVisibility { /** * Whether to enable column hiding. Defaults to `true`. */ enableHiding?: boolean /** * If provided, this function will be called with an `updaterFn` when `state.columnVisibility` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. */ onColumnVisibilityChange?: OnChangeFn } export type VisibilityDefaultOptions = Pick< TableOptions_ColumnVisibility, 'onColumnVisibilityChange' > export interface Table_ColumnVisibility< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns whether all columns are visible */ getIsAllColumnsVisible: () => boolean /** * Returns whether any columns are visible */ getIsSomeColumnsVisible: () => boolean /** * Returns a handler for toggling the visibility of all columns, meant to be bound to a `input[type=checkbox]` element. */ getToggleAllColumnsVisibilityHandler: () => (event: unknown) => void /** * Returns a flat array of columns that are visible, including parent columns. */ getVisibleFlatColumns: () => Array> /** * Returns a flat array of leaf-node columns that are visible. */ getVisibleLeafColumns: () => Array> /** * Resets the column visibility state to the initial state. If `defaultState` is provided, the state will be reset to `{}` */ resetColumnVisibility: (defaultState?: boolean) => void /** * Sets or updates the `state.columnVisibility` state. */ setColumnVisibility: (updater: Updater) => void /** * Toggles the visibility of all columns. */ toggleAllColumnsVisible: (value?: boolean) => void } export interface ColumnDef_ColumnVisibility { /** * Enables/disables column hiding for this column. Defaults to `true`. */ enableHiding?: boolean } export interface Row_ColumnVisibility< TFeatures extends TableFeatures, TData extends RowData, > { getAllVisibleCells: () => Array> /** * Returns an array of cells that account for column visibility for the row. */ getVisibleCells: () => Array> } export interface Column_ColumnVisibility { /** * Returns whether the column can be hidden */ getCanHide: () => boolean /** * Returns whether the column is visible */ getIsVisible: () => boolean /** * Returns a function that can be used to toggle the column visibility. This function can be used to bind to an event handler to a checkbox. */ getToggleVisibilityHandler: () => (event: unknown) => void /** * Toggles the visibility of the column. */ toggleVisibility: (value?: boolean) => void } ================================================ FILE: packages/table-core/src/features/column-visibility/columnVisibilityFeature.utils.ts ================================================ import { callMemoOrStaticFn } from '../../utils' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Cell } from '../../types/Cell' import type { Column_Internal } from '../../types/Column' import type { ColumnVisibilityState } from './columnVisibilityFeature.types' import type { Row } from '../../types/Row' export function getDefaultColumnVisibilityState(): ColumnVisibilityState { return structuredClone({}) } export function column_toggleVisibility< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal, visible?: boolean): void { if (column_getCanHide(column)) { table_setColumnVisibility(column.table, (old) => ({ ...old, [column.id]: visible ?? !callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), })) } } export function column_getIsVisible< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): boolean { const childColumns = column.columns return ( (childColumns.length ? childColumns.some((childColumn) => callMemoOrStaticFn(childColumn, 'getIsVisible', column_getIsVisible), ) : column.table.store.state.columnVisibility?.[column.id]) ?? true ) } export function column_getCanHide< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return ( (column.columnDef.enableHiding ?? true) && (column.table.options.enableHiding ?? true) ) } export function column_getToggleVisibilityHandler< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return (e: unknown) => { column_toggleVisibility( column, ((e as MouseEvent).target as HTMLInputElement).checked, ) } } export function row_getAllVisibleCells< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return row .getAllCells() .filter((cell) => callMemoOrStaticFn(cell.column, 'getIsVisible', column_getIsVisible), ) } export function row_getVisibleCells< TFeatures extends TableFeatures, TData extends RowData, >( left: Array>, center: Array>, right: Array>, ) { return [...left, ...center, ...right] } export function table_getVisibleFlatColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table .getAllFlatColumns() .filter((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_getVisibleLeafColumns< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table .getAllLeafColumns() .filter((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_setColumnVisibility< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ) { table.options.onColumnVisibilityChange?.(updater) } export function table_resetColumnVisibility< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setColumnVisibility( table, defaultState ? {} : (table.initialState.columnVisibility ?? {}), ) } export function table_toggleAllColumnsVisible< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, value?: boolean) { value = value ?? !table_getIsAllColumnsVisible(table) table_setColumnVisibility( table, table.getAllLeafColumns().reduce( (obj, column) => ({ ...obj, [column.id]: !value ? !column_getCanHide(column) : value, }), {}, ), ) } export function table_getIsAllColumnsVisible< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return !table .getAllLeafColumns() .some( (column) => !callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_getIsSomeColumnsVisible< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table .getAllLeafColumns() .some((column) => callMemoOrStaticFn(column, 'getIsVisible', column_getIsVisible), ) } export function table_getToggleAllColumnsVisibilityHandler< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return (e: unknown) => { table_toggleAllColumnsVisible( table, ((e as MouseEvent).target as HTMLInputElement).checked, ) } } ================================================ FILE: packages/table-core/src/features/global-filtering/globalFilteringFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { column_getCanGlobalFilter, table_getGlobalAutoFilterFn, table_getGlobalFilterFn, table_resetGlobalFilter, table_setGlobalFilter, } from './globalFilteringFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // ColumnDef_GlobalFiltering, // Column_GlobalFiltering, // TableOptions_GlobalFiltering, // TableState_GlobalFiltering, // Table_GlobalFiltering, // } from './globalFilteringFeature.types' interface GlobalFilteringFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Column: Column_GlobalFiltering // ColumnDef: ColumnDef_GlobalFiltering // Table: Table_GlobalFiltering // TableOptions: TableOptions_GlobalFiltering // TableState: TableState_GlobalFiltering } export function constructGlobalFilteringFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { globalFilter: undefined, ...initialState, } }, getDefaultTableOptions: (table) => { return { onGlobalFilterChange: makeStateUpdater('globalFilter', table), globalFilterFn: 'auto', getColumnCanGlobalFilter: (column) => { const value = table .getCoreRowModel() .flatRows[0]?.getAllCellsByColumnId() [column.id]?.getValue() return typeof value === 'string' || typeof value === 'number' }, } }, assignColumnPrototype: (prototype, table) => { assignPrototypeAPIs('globalFilteringFeature', prototype, table, { column_getCanGlobalFilter: { fn: (column) => column_getCanGlobalFilter(column), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('globalFilteringFeature', table, { table_getGlobalAutoFilterFn: { fn: () => table_getGlobalAutoFilterFn(), }, table_getGlobalFilterFn: { fn: () => table_getGlobalFilterFn(table), }, table_setGlobalFilter: { fn: (updater) => table_setGlobalFilter(table, updater), }, table_resetGlobalFilter: { fn: (defaultState) => table_resetGlobalFilter(table, defaultState), }, }) }, } } /** * The Global Filtering feature adds global filtering state and APIs to the table and column objects. * **Note:** This is dependent on the columnFilteringFeature feature. */ export const globalFilteringFeature = constructGlobalFilteringFeature() ================================================ FILE: packages/table-core/src/features/global-filtering/globalFilteringFeature.types.ts ================================================ import type { CellData, OnChangeFn, RowData, Updater, } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Column } from '../../types/Column' import type { FilterFn, FilterFnOption, } from '../column-filtering/columnFilteringFeature.types' export interface TableState_GlobalFiltering { globalFilter: any } export interface ColumnDef_GlobalFiltering { /** * Enables/disables the **global** filter for this column. */ enableGlobalFilter?: boolean } export interface Column_GlobalFiltering { /** * Returns whether or not the column can be **globally** filtered. Set to `false` to disable a column from being scanned during global filtering. */ getCanGlobalFilter: () => boolean } export interface TableOptions_GlobalFiltering< TFeatures extends TableFeatures, TData extends RowData, > { /** * Enables/disables **global** filtering for all columns. */ enableGlobalFilter?: boolean /** * If provided, this function will be called with the column and should return `true` or `false` to indicate whether this column should be used for global filtering. * This is useful if the column can contain data that is not `string` or `number` (i.e. `undefined`). */ getColumnCanGlobalFilter?: < TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column, ) => boolean /** * The filter function to use for global filtering. * - A `string` referencing a built-in filter function * - A `string` that references a custom filter functions provided via the `tableOptions.filterFns` option * - A custom filter function */ globalFilterFn?: FilterFnOption /** * If provided, this function will be called with an `updaterFn` when `state.globalFilter` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. */ onGlobalFilterChange?: OnChangeFn } export interface Table_GlobalFiltering< TFeatures extends TableFeatures, TData extends RowData, > { /** * Currently, this function returns the built-in `includesString` filter function. In future releases, it may return more dynamic filter functions based on the nature of the data provided. */ getGlobalAutoFilterFn: () => FilterFn | undefined /** * Returns the filter function (either user-defined or automatic, depending on configuration) for the global filter. */ getGlobalFilterFn: () => FilterFn | undefined /** * Resets the **globalFilter** state to `initialState.globalFilter`, or `true` can be passed to force a default blank state reset to `undefined`. */ resetGlobalFilter: (defaultState?: boolean) => void /** * Sets or updates the `state.globalFilter` state. */ setGlobalFilter: (updater: Updater) => void } ================================================ FILE: packages/table-core/src/features/global-filtering/globalFilteringFeature.utils.ts ================================================ import { filterFn_includesString } from '../../fns/filterFns' import { isFunction } from '../../utils' import type { Column_Internal } from '../../types/Column' import type { FilterFn } from '../column-filtering/columnFilteringFeature.types' import type { CellData, RowData } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' export function column_getCanGlobalFilter< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): boolean { return ( (column.columnDef.enableGlobalFilter ?? true) && (column.table.options.enableGlobalFilter ?? true) && (column.table.options.enableFilters ?? true) && (column.table.options.getColumnCanGlobalFilter?.(column) ?? true) && !!column.accessorFn ) } export function table_getGlobalAutoFilterFn() { return filterFn_includesString } export function table_getGlobalFilterFn< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, ): FilterFn | FilterFn | undefined { const { globalFilterFn: globalFilterFn } = table.options const filterFns = table._rowModelFns.filterFns as | Record> | undefined return isFunction(globalFilterFn) ? globalFilterFn : globalFilterFn === 'auto' ? table_getGlobalAutoFilterFn() : filterFns?.[globalFilterFn as string] } export function table_setGlobalFilter< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: any) { table.options.onGlobalFilterChange?.(updater) } export function table_resetGlobalFilter< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setGlobalFilter( table, defaultState ? undefined : table.initialState.globalFilter, ) } ================================================ FILE: packages/table-core/src/features/row-expanding/createExpandedRowModel.ts ================================================ import { tableMemo } from '../../utils' import { row_getIsExpanded } from './rowExpandingFeature.utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table, Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { RowData } from '../../types/type-utils' export function createExpandedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(): (table: Table) => () => RowModel { return (_table) => { const table = _table as Table_Internal return tableMemo({ feature: 'rowExpandingFeature', table, fnName: 'table.getExpandedRowModel', memoDeps: () => [ table.store.state.expanded, table.getPreExpandedRowModel(), table.options.paginateExpandedRows, ], fn: () => _createExpandedRowModel(table), }) } } function _createExpandedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(table: Table_Internal): RowModel { const rowModel = table.getPreExpandedRowModel() const expanded = table.store.state.expanded if ( !rowModel.rows.length || (expanded !== true && !Object.keys(expanded ?? {}).length) ) { return rowModel } if (!table.options.paginateExpandedRows) { // Only expand rows at this point if they are being paginated return rowModel } return expandRows(rowModel) } export function expandRows< TFeatures extends TableFeatures, TData extends RowData = any, >(rowModel: RowModel): RowModel { const expandedRows: Array> = [] const handleRow = (row: Row) => { expandedRows.push(row) if (row.subRows.length && row_getIsExpanded(row)) { row.subRows.forEach(handleRow) } } rowModel.rows.forEach(handleRow) return { rows: expandedRows, flatRows: rowModel.flatRows, rowsById: rowModel.rowsById, } } ================================================ FILE: packages/table-core/src/features/row-expanding/rowExpandingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { getDefaultExpandedState, row_getCanExpand, row_getIsAllParentsExpanded, row_getIsExpanded, row_getToggleExpandedHandler, row_toggleExpanded, table_autoResetExpanded, table_getCanSomeRowsExpand, table_getExpandedDepth, table_getIsAllRowsExpanded, table_getIsSomeRowsExpanded, table_getToggleAllRowsExpandedHandler, table_resetExpanded, table_setExpanded, table_toggleAllRowsExpanded, } from './rowExpandingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // CachedRowModel_Expanded, // CreateRowModel_Expanded, // Row_RowExpanding, // TableOptions_RowExpanding, // TableState_RowExpanding, // Table_RowExpanding, // } from './rowExpandingFeature.types' interface RowExpandingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // CachedRowModel: CachedRowModel_Expanded // CreateRowModels: CreateRowModel_Expanded // Row: Row_RowExpanding // Table: Table_RowExpanding // TableOptions: TableOptions_RowExpanding // TableState: TableState_RowExpanding } export function constructRowExpandingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { expanded: getDefaultExpandedState(), ...initialState, } }, getDefaultTableOptions: (table) => { return { onExpandedChange: makeStateUpdater('expanded', table), paginateExpandedRows: true, } }, assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('rowExpandingFeature', prototype, table, { row_toggleExpanded: { fn: (row, expanded) => row_toggleExpanded(row, expanded), }, row_getIsExpanded: { fn: (row) => row_getIsExpanded(row), }, row_getCanExpand: { fn: (row) => row_getCanExpand(row), }, row_getIsAllParentsExpanded: { fn: (row) => row_getIsAllParentsExpanded(row), }, row_getToggleExpandedHandler: { fn: (row) => row_getToggleExpandedHandler(row), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('rowExpandingFeature', table, { table_autoResetExpanded: { fn: () => table_autoResetExpanded(table), }, table_setExpanded: { fn: (updater) => table_setExpanded(table, updater), }, table_toggleAllRowsExpanded: { fn: (expanded) => table_toggleAllRowsExpanded(table, expanded), }, table_resetExpanded: { fn: (defaultState) => table_resetExpanded(table, defaultState), }, table_getCanSomeRowsExpand: { fn: () => table_getCanSomeRowsExpand(table), }, table_getToggleAllRowsExpandedHandler: { fn: () => table_getToggleAllRowsExpandedHandler(table), }, table_getIsSomeRowsExpanded: { fn: () => table_getIsSomeRowsExpanded(table), }, table_getIsAllRowsExpanded: { fn: () => table_getIsAllRowsExpanded(table), }, table_getExpandedDepth: { fn: () => table_getExpandedDepth(table), }, }) }, } } /** * The Row Expanding feature adds row expanding state and APIs to the table and row objects. */ export const rowExpandingFeature = constructRowExpandingFeature() ================================================ FILE: packages/table-core/src/features/row-expanding/rowExpandingFeature.types.ts ================================================ import type { Table } from '../../types/Table' import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Row } from '../../types/Row' export type ExpandedStateList = Record export type ExpandedState = true | Record export interface TableState_RowExpanding { expanded: ExpandedState } export interface Row_RowExpanding { /** * Returns whether the row can be expanded. */ getCanExpand: () => boolean /** * Returns whether all parent rows of the row are expanded. */ getIsAllParentsExpanded: () => boolean /** * Returns whether the row is expanded. */ getIsExpanded: () => boolean /** * Returns a function that can be used to toggle the expanded state of the row. This function can be used to bind to an event handler to a button. */ getToggleExpandedHandler: () => () => void /** * Toggles the expanded state (or sets it if `expanded` is provided) for the row. */ toggleExpanded: (expanded?: boolean) => void } export interface TableOptions_RowExpanding< TFeatures extends TableFeatures, TData extends RowData, > { /** * Enable this setting to automatically reset the expanded state of the table when expanding state changes. */ autoResetExpanded?: boolean /** * Enable/disable expanding for all rows. */ enableExpanding?: boolean /** * If provided, allows you to override the default behavior of determining whether a row is currently expanded. */ getIsRowExpanded?: (row: Row) => boolean /** * If provided, allows you to override the default behavior of determining whether a row can be expanded. */ getRowCanExpand?: (row: Row) => boolean /** * Enables manual row expansion. If this is set to `true`, `getExpandedRowModel` will not be used to expand rows and you would be expected to perform the expansion in your own data model. This is useful if you are doing server-side expansion. */ manualExpanding?: boolean /** * This function is called when the `expanded` table state changes. If a function is provided, you will be responsible for managing this state on your own. To pass the managed state back to the table, use the `tableOptions.state.expanded` option. */ onExpandedChange?: OnChangeFn /** * If `true` expanded rows will be paginated along with the rest of the table (which means expanded rows may span multiple pages). If `false` expanded rows will not be considered for pagination (which means expanded rows will always render on their parents page. This also means more rows will be rendered than the set page size) */ paginateExpandedRows?: boolean } export interface Table_RowExpanding< TFeatures extends TableFeatures, TData extends RowData, > { autoResetExpanded: () => void /** * Returns whether there are any rows that can be expanded. */ getCanSomeRowsExpand: () => boolean /** * Returns the maximum depth of the expanded rows. */ getExpandedDepth: () => number /** * Returns whether all rows are currently expanded. */ getIsAllRowsExpanded: () => boolean /** * Returns whether there are any rows that are currently expanded. */ getIsSomeRowsExpanded: () => boolean /** * Returns a handler that can be used to toggle the expanded state of all rows. This handler is meant to be used with an `input[type=checkbox]` element. */ getToggleAllRowsExpandedHandler: () => (event: unknown) => void /** * Resets the expanded state of the table to the initial state. */ resetExpanded: (defaultState?: boolean) => void /** * Updates the expanded state of the table via an update function or value. */ setExpanded: (updater: Updater) => void /** * Toggles the expanded state for all rows. */ toggleAllRowsExpanded: (expanded?: boolean) => void } export interface Table_RowModels_Expanded< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model after expansion has been applied. */ getExpandedRowModel: () => RowModel /** * Returns the row model before expansion has been applied. */ getPreExpandedRowModel: () => RowModel } export interface CreateRowModel_Expanded< TFeatures extends TableFeatures, TData extends RowData, > { /** * This function is responsible for returning the expanded row model. If this function is not provided, the table will not expand rows. You can use the default exported `getExpandedRowModel` function to get the expanded row model or implement your own. */ expandedRowModel?: ( table: Table, ) => () => RowModel } export interface CachedRowModel_Expanded< TFeatures extends TableFeatures, TData extends RowData, > { expandedRowModel: () => RowModel } ================================================ FILE: packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts ================================================ import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { ExpandedState, ExpandedStateList, } from './rowExpandingFeature.types' export function getDefaultExpandedState(): ExpandedState { return structuredClone({}) } export function table_autoResetExpanded< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { if ( table.options.autoResetAll ?? table.options.autoResetExpanded ?? !table.options.manualExpanding ) { queueMicrotask(() => table_resetExpanded(table)) } } export function table_setExpanded< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { table.options.onExpandedChange?.(updater) } export function table_toggleAllRowsExpanded< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, expanded?: boolean) { if (expanded ?? !table_getIsAllRowsExpanded(table)) { table_setExpanded(table, true) } else { table_setExpanded(table, {}) } } export function table_resetExpanded< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setExpanded( table, defaultState ? {} : (table.initialState.expanded ?? {}), ) } export function table_getCanSomeRowsExpand< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table .getPrePaginatedRowModel() .flatRows.some((row) => row_getCanExpand(row)) } export function table_getToggleAllRowsExpandedHandler< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return (e: unknown) => { ;(e as any).persist?.() table_toggleAllRowsExpanded(table) } } export function table_getIsSomeRowsExpanded< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const expanded = table.store.state.expanded ?? {} return expanded === true || Object.values(expanded).some(Boolean) } export function table_getIsAllRowsExpanded< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const expanded = table.store.state.expanded ?? {} // If expanded is true, save some cycles and return true if (expanded === true) { return true } if (!Object.keys(expanded).length) { return false } // If any row is not expanded, return false if (table.getRowModel().flatRows.some((row) => !row_getIsExpanded(row))) { return false } // They must all be expanded :shrug: return true } export function table_getExpandedDepth< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { let maxDepth = 0 const rowIds = table.store.state.expanded === true ? Object.keys(table.getRowModel().rowsById) : Object.keys(table.store.state.expanded ?? {}) rowIds.forEach((id) => { const splitId = id.split('.') maxDepth = Math.max(maxDepth, splitId.length) }) return maxDepth } export function row_toggleExpanded< TFeatures extends TableFeatures, TData extends RowData, >(row: Row, expanded?: boolean) { table_setExpanded(row.table, (old) => { const exists = old === true ? true : !!old[row.id] let oldExpanded: ExpandedStateList = {} if (old === true) { Object.keys(row.table.getRowModel().rowsById).forEach((rowId) => { oldExpanded[rowId] = true }) } else { oldExpanded = old } expanded = expanded ?? !exists if (!exists && expanded) { return { ...oldExpanded, [row.id]: true, } } if (exists && !expanded) { const { [row.id]: _, ...rest } = oldExpanded return rest } return old }) } export function row_getIsExpanded< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const expanded = row.table.store.state.expanded ?? ({} as ExpandedState) return !!( row.table.options.getIsRowExpanded?.(row) ?? (expanded === true || expanded[row.id]) ) } export function row_getCanExpand< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return ( row.table.options.getRowCanExpand?.(row) ?? ((row.table.options.enableExpanding ?? true) && !!row.subRows.length) ) } export function row_getIsAllParentsExpanded< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { let isFullyExpanded = true let currentRow = row while (isFullyExpanded && currentRow.parentId) { currentRow = row.table.getRow(currentRow.parentId, true) isFullyExpanded = row_getIsExpanded(row) } return isFullyExpanded } export function row_getToggleExpandedHandler< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const canExpand = row_getCanExpand(row) return () => { if (!canExpand) return row_toggleExpanded(row) } } ================================================ FILE: packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts ================================================ import { tableMemo } from '../../utils' import { expandRows } from '../row-expanding/createExpandedRowModel' import { getDefaultPaginationState } from './rowPaginationFeature.utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table, Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { RowData } from '../../types/type-utils' export function createPaginatedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(): (table: Table) => () => RowModel { return (_table) => { const table = _table as Table_Internal return tableMemo({ feature: 'rowPaginationFeature', table, fnName: 'table.getPaginatedRowModel', memoDeps: () => [ table.getPrePaginatedRowModel(), table.store.state.pagination, table.options.paginateExpandedRows ? table.store.state.expanded : undefined, ], fn: () => _createPaginatedRowModel(table), }) } } function _createPaginatedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(table: Table_Internal): RowModel { const prePaginatedRowModel = table.getPrePaginatedRowModel() const pagination = table.store.state.pagination if (!prePaginatedRowModel.rows.length) { return prePaginatedRowModel } const { pageSize, pageIndex } = pagination ?? getDefaultPaginationState() const { rows, flatRows, rowsById } = prePaginatedRowModel const pageStart = pageSize * pageIndex const pageEnd = pageStart + pageSize const paginatedRows = rows.slice(pageStart, pageEnd) let paginatedRowModel: RowModel if (!table.options.paginateExpandedRows) { paginatedRowModel = expandRows({ rows: paginatedRows, flatRows, rowsById, }) } else { paginatedRowModel = { rows: paginatedRows, flatRows, rowsById, } } paginatedRowModel.flatRows = [] const handleRow = (row: Row) => { paginatedRowModel.flatRows.push(row) if (row.subRows.length) { row.subRows.forEach(handleRow) } } paginatedRowModel.rows.forEach(handleRow) return paginatedRowModel } ================================================ FILE: packages/table-core/src/features/row-pagination/rowPaginationFeature.ts ================================================ import { assignTableAPIs, makeStateUpdater } from '../../utils' import { getDefaultPaginationState, table_autoResetPageIndex, table_firstPage, table_getCanNextPage, table_getCanPreviousPage, table_getPageCount, table_getPageOptions, table_getRowCount, table_lastPage, table_nextPage, table_previousPage, table_resetPageIndex, table_resetPageSize, table_resetPagination, table_setPageIndex, table_setPageSize, table_setPagination, } from './rowPaginationFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // CachedRowModel_Paginated, // CreateRowModel_Paginated, // TableOptions_RowPagination, // TableState_RowPagination, // Table_RowPagination, // } from './rowPaginationFeature.types' interface RowPaginationFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // CachedRowModel: CachedRowModel_Paginated // CreateRowModels: CreateRowModel_Paginated // Table: Table_RowPagination // TableOptions: TableOptions_RowPagination // TableState: TableState_RowPagination } export function constructRowPaginationFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { ...initialState, pagination: { ...getDefaultPaginationState(), ...initialState.pagination, }, } }, getDefaultTableOptions: (table) => { return { onPaginationChange: makeStateUpdater('pagination', table), } }, constructTableAPIs: (table) => { assignTableAPIs('rowPaginationFeature', table, { table_autoResetPageIndex: { fn: () => table_autoResetPageIndex(table), }, table_setPagination: { fn: (updater) => table_setPagination(table, updater), }, table_resetPagination: { fn: (defaultState) => table_resetPagination(table, defaultState), }, table_setPageIndex: { fn: (updater) => table_setPageIndex(table, updater), }, table_resetPageIndex: { fn: (defaultState) => table_resetPageIndex(table, defaultState), }, table_setPageSize: { fn: (updater) => table_setPageSize(table, updater), }, table_getPageCount: { fn: () => table_getPageCount(table), }, table_resetPageSize: { fn: (defaultState) => table_resetPageSize(table, defaultState), }, table_getPageOptions: { fn: () => table_getPageOptions(table), }, table_getCanPreviousPage: { fn: () => table_getCanPreviousPage(table), }, table_getCanNextPage: { fn: () => table_getCanNextPage(table), }, table_previousPage: { fn: () => table_previousPage(table), }, table_nextPage: { fn: () => table_nextPage(table), }, table_firstPage: { fn: () => table_firstPage(table), }, table_lastPage: { fn: () => table_lastPage(table), }, table_getRowCount: { fn: () => table_getRowCount(table), }, }) }, } } /** * The (Row) Pagination feature adds pagination state and APIs to the table object. */ export const rowPaginationFeature = constructRowPaginationFeature() ================================================ FILE: packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts ================================================ import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table } from '../../types/Table' import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' export interface PaginationState { pageIndex: number pageSize: number } export interface TableState_RowPagination { pagination: PaginationState } export interface TableOptions_RowPagination { /** * If set to `true`, pagination will be reset to the first page when page-altering state changes eg. `data` is updated, filters change, grouping changes, etc. */ autoResetPageIndex?: boolean /** * Enables manual pagination. If this option is set to `true`, the table will not automatically paginate rows using `getPaginatedRowModel()` and instead will expect you to manually paginate the rows before passing them to the table. This is useful if you are doing server-side pagination and aggregation. */ manualPagination?: boolean /** * If this function is provided, it will be called when the pagination state changes and you will be expected to manage the state yourself. You can pass the managed state back to the table via the `tableOptions.state.pagination` option. */ onPaginationChange?: OnChangeFn /** * When manually controlling pagination, you can supply a total `pageCount` value to the table if you know it (Or supply a `rowCount` and `pageCount` will be calculated). If you do not know how many pages there are, you can set this to `-1`. */ pageCount?: number /** * When manually controlling pagination, you can supply a total `rowCount` value to the table if you know it. The `pageCount` can be calculated from this value and the `pageSize`. */ rowCount?: number } export interface PaginationDefaultOptions { onPaginationChange: OnChangeFn } export interface Table_RowPagination< TFeatures extends TableFeatures, TData extends RowData, > { _autoResetPageIndex: () => void /** * Returns whether the table can go to the next page. */ getCanNextPage: () => boolean /** * Returns whether the table can go to the previous page. */ getCanPreviousPage: () => boolean /** * Returns the page count. If manually paginating or controlling the pagination state, this will come directly from the `options.pageCount` table option, otherwise it will be calculated from the table data using the total row count and current page size. */ getPageCount: () => number /** * Returns the row count. If manually paginating or controlling the pagination state, this will come directly from the `options.rowCount` table option, otherwise it will be calculated from the table data. */ getRowCount: () => number /** * Returns an array of page options (zero-index-based) for the current page size. */ getPageOptions: () => Array /** * Increments the page index by one, if possible. */ nextPage: () => void /** * Decrements the page index by one, if possible. */ previousPage: () => void /** * Sets the page index to `0`. */ firstPage: () => void /** * Sets the page index to the last page. */ lastPage: () => void /** * Resets the page index to its initial state. If `defaultState` is `true`, the page index will be reset to `0` regardless of initial state. */ resetPageIndex: (defaultState?: boolean) => void /** * Resets the page size to its initial state. If `defaultState` is `true`, the page size will be reset to `10` regardless of initial state. */ resetPageSize: (defaultState?: boolean) => void /** * Resets the **pagination** state to `initialState.pagination`, or `true` can be passed to force a default blank state reset to `[]`. */ resetPagination: (defaultState?: boolean) => void /** * Updates the page index using the provided function or value in the `state.pagination.pageIndex` state. */ setPageIndex: (updater: Updater) => void /** * Updates the page size using the provided function or value in the `state.pagination.pageSize` state. */ setPageSize: (updater: Updater) => void /** * Sets or updates the `state.pagination` state. */ setPagination: (updater: Updater) => void } export interface Table_RowModels_Paginated< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model for the table after pagination has been applied. */ getPaginatedRowModel: () => RowModel /** * Returns the row model for the table before any pagination has been applied. */ getPrePaginatedRowModel: () => RowModel } export interface CreateRowModel_Paginated< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model after pagination has taken place, but no further. * Pagination columns are automatically reordered by default to the start of the columns list. If you would rather remove them or leave them as-is, set the appropriate mode here. */ paginatedRowModel?: ( table: Table, ) => () => RowModel } export interface CachedRowModel_Paginated< TFeatures extends TableFeatures, TData extends RowData, > { paginatedRowModel: () => RowModel } ================================================ FILE: packages/table-core/src/features/row-pagination/rowPaginationFeature.utils.ts ================================================ import { functionalUpdate } from '../../utils' import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { PaginationState } from './rowPaginationFeature.types' const defaultPageIndex = 0 const defaultPageSize = 10 export function getDefaultPaginationState(): PaginationState { return structuredClone({ pageIndex: defaultPageIndex, pageSize: defaultPageSize, }) } export function table_autoResetPageIndex< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { if ( table.options.autoResetAll ?? table.options.autoResetPageIndex ?? !table.options.manualPagination ) { table_resetPageIndex(table) } } export function table_setPagination< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { const safeUpdater: Updater = (old) => { const newState = functionalUpdate(updater, old) return newState } return table.options.onPaginationChange?.(safeUpdater) } export function table_resetPagination< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setPagination( table, defaultState ? getDefaultPaginationState() : (table.initialState.pagination ?? getDefaultPaginationState()), ) } export function table_setPageIndex< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { table_setPagination(table, (old) => { let pageIndex = functionalUpdate(updater, old.pageIndex) const maxPageIndex = typeof table.options.pageCount === 'undefined' || table.options.pageCount === -1 ? Number.MAX_SAFE_INTEGER : table.options.pageCount - 1 pageIndex = Math.max(0, Math.min(pageIndex, maxPageIndex)) return { ...old, pageIndex, } }) } export function table_resetPageIndex< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setPageIndex( table, defaultState ? defaultPageIndex : (table.initialState.pagination?.pageIndex ?? defaultPageIndex), ) } export function table_resetPageSize< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setPageSize( table, defaultState ? defaultPageSize : (table.initialState.pagination?.pageSize ?? defaultPageSize), ) } export function table_setPageSize< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { table_setPagination(table, (old) => { const pageSize = Math.max(1, functionalUpdate(updater, old.pageSize)) const topRowIndex = old.pageSize * old.pageIndex const pageIndex = Math.floor(topRowIndex / pageSize) return { ...old, pageIndex, pageSize, } }) } export function table_getPageOptions< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const pageCount = table_getPageCount(table) let pageOptions: Array = [] if (pageCount && pageCount > 0) { pageOptions = [...new Array(pageCount)].fill(null).map((_, i) => i) } return pageOptions } export function table_getCanPreviousPage< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return (table.store.state.pagination?.pageIndex ?? 0) > 0 } export function table_getCanNextPage< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const pageIndex = table.store.state.pagination?.pageIndex ?? defaultPageIndex const pageCount = table_getPageCount(table) if (pageCount === -1) { return true } if (pageCount === 0) { return false } return pageIndex < pageCount - 1 } export function table_previousPage< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table_setPageIndex(table, (old) => old - 1) } export function table_nextPage< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table_setPageIndex(table, (old) => { return old + 1 }) } export function table_firstPage< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table_setPageIndex(table, 0) } export function table_lastPage< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table_setPageIndex(table, table_getPageCount(table) - 1) } export function table_getPageCount< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return ( table.options.pageCount ?? Math.ceil( table_getRowCount(table) / (table.store.state.pagination?.pageSize ?? defaultPageSize), ) ) } export function table_getRowCount< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return table.options.rowCount ?? table.getPrePaginatedRowModel().rows.length } ================================================ FILE: packages/table-core/src/features/row-pinning/rowPinningFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { getDefaultRowPinningState, row_getCanPin, row_getIsPinned, row_getPinnedIndex, row_pin, table_getBottomRows, table_getCenterRows, table_getIsSomeRowsPinned, table_getTopRows, table_resetRowPinning, table_setRowPinning, } from './rowPinningFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // Row_RowPinning, // TableOptions_RowPinning, // TableState_RowPinning, // Table_RowPinning, // } from './rowPinningFeature.types' interface RowPinningFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Row: Row_RowPinning // Table: Table_RowPinning // TableOptions: TableOptions_RowPinning // TableState: TableState_RowPinning } export function constructRowPinningFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { ...initialState, rowPinning: { ...getDefaultRowPinningState(), ...initialState.rowPinning, }, } }, getDefaultTableOptions: (table) => { return { onRowPinningChange: makeStateUpdater('rowPinning', table), } }, assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('rowPinningFeature', prototype, table, { row_getCanPin: { fn: (row) => row_getCanPin(row), }, row_getIsPinned: { fn: (row) => row_getIsPinned(row), }, row_getPinnedIndex: { fn: (row) => row_getPinnedIndex(row), memoDeps: (row) => [ row.table.getRowModel().rows, row.table.store.state.rowPinning, ], }, row_pin: { fn: (row, position, includeLeafRows, includeParentRows) => row_pin(row, position, includeLeafRows, includeParentRows), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('rowPinningFeature', table, { table_setRowPinning: { fn: (updater) => table_setRowPinning(table, updater), }, table_resetRowPinning: { fn: (defaultState) => table_resetRowPinning(table, defaultState), }, table_getIsSomeRowsPinned: { fn: (position) => table_getIsSomeRowsPinned(table, position), }, table_getTopRows: { fn: () => table_getTopRows(table), memoDeps: () => [ table.getRowModel().rows, table.store.state.rowPinning?.top, ], }, table_getBottomRows: { fn: () => table_getBottomRows(table), memoDeps: () => [ table.getRowModel().rows, table.store.state.rowPinning?.bottom, ], }, table_getCenterRows: { fn: () => table_getCenterRows(table), memoDeps: () => [ table.getRowModel().rows, table.store.state.rowPinning, ], }, }) }, } } /** * The Row Pinning feature adds row pinning state and APIs to the table and row objects. */ export const rowPinningFeature = constructRowPinningFeature() ================================================ FILE: packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts ================================================ import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' export type RowPinningPosition = false | 'top' | 'bottom' export interface RowPinningState { bottom: Array top: Array } export interface TableState_RowPinning { rowPinning: RowPinningState } export interface TableOptions_RowPinning< TFeatures extends TableFeatures, TData extends RowData, > { /** * Enables/disables row pinning for the table. Defaults to `true`. */ enableRowPinning?: boolean | ((row: Row) => boolean) /** * When `false`, pinned rows will not be visible if they are filtered or paginated out of the table. When `true`, pinned rows will always be visible regardless of filtering or pagination. Defaults to `true`. */ keepPinnedRows?: boolean /** * If provided, this function will be called with an `updaterFn` when `state.rowPinning` changes. This overrides the default internal state management, so you will also need to supply `state.rowPinning` from your own managed state. */ onRowPinningChange?: OnChangeFn } export interface RowPinningDefaultOptions { onRowPinningChange: OnChangeFn } export interface Row_RowPinning { /** * Returns whether or not the row can be pinned. */ getCanPin: () => boolean /** * Returns the pinned position of the row. (`'top'`, `'bottom'` or `false`) */ getIsPinned: () => RowPinningPosition /** * Returns the numeric pinned index of the row within a pinned row group. */ getPinnedIndex: () => number /** * Pins a row to the `'top'` or `'bottom'`, or unpins the row to the center if `false` is passed. */ pin: ( position: RowPinningPosition, includeLeafRows?: boolean, includeParentRows?: boolean, ) => void } export interface Table_RowPinning< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns all bottom pinned rows. */ getBottomRows: () => Array> /** * Returns all rows that are not pinned to the top or bottom. */ getCenterRows: () => Array> /** * Returns whether or not any rows are pinned. Optionally specify to only check for pinned rows in either the `top` or `bottom` position. */ getIsSomeRowsPinned: (position?: RowPinningPosition) => boolean /** * Returns all top pinned rows. */ getTopRows: () => Array> /** * Resets the **rowPinning** state to `initialState.rowPinning`, or `true` can be passed to force a default blank state reset to `{ top: [], bottom: [], }`. */ resetRowPinning: (defaultState?: boolean) => void /** * Sets or updates the `state.rowPinning` state. */ setRowPinning: (updater: Updater) => void } ================================================ FILE: packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts ================================================ import { row_getIsAllParentsExpanded } from '../row-expanding/rowExpandingFeature.utils' import { callMemoOrStaticFn } from '../../utils' import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { RowPinningPosition, RowPinningState, } from './rowPinningFeature.types' // State Utils export function getDefaultRowPinningState(): RowPinningState { return structuredClone({ top: [], bottom: [], }) } export function table_setRowPinning< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ): void { table.options.onRowPinningChange?.(updater) } export function table_resetRowPinning< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean): void { table_setRowPinning( table, defaultState ? getDefaultRowPinningState() : (table.initialState.rowPinning ?? getDefaultRowPinningState()), ) } // Table Utils export function table_getIsSomeRowsPinned< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, position?: RowPinningPosition, ): boolean { const rowPinning = table.store.state.rowPinning if (!position) { return Boolean(rowPinning?.top.length || rowPinning?.bottom.length) } return Boolean(rowPinning?.[position].length) } function table_getPinnedRows< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, position: 'top' | 'bottom', ): Array> { const visibleRows = table.getRowModel().rows const pinnedRowIds = table.store.state.rowPinning?.[position] ?? [] const rows = (table.options.keepPinnedRows ?? true) ? // get all rows that are pinned even if they would not be otherwise visible // account for expanded parent rows, but not pagination or filtering pinnedRowIds.map((rowId) => { const row = table.getRow(rowId, true) return row_getIsAllParentsExpanded(row) ? row : null }) : // else get only visible rows that are pinned pinnedRowIds.map( (rowId) => visibleRows.find((row) => row.id === rowId)!, ) const filteredRows = rows.filter((r) => !!r) // Assign position property directly to preserve prototype chain filteredRows.forEach((row) => { ;(row as any).position = position }) return filteredRows } export function table_getTopRows< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): Array> { return table_getPinnedRows(table, 'top') } export function table_getBottomRows< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): Array> { return table_getPinnedRows(table, 'bottom') } export function table_getCenterRows< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): Array> { const { top, bottom } = table.store.state.rowPinning ?? getDefaultRowPinningState() const allRows = table.getRowModel().rows const topAndBottom = new Set([...top, ...bottom]) return allRows.filter((d) => !topAndBottom.has(d.id)) } // Row Utils export function row_getCanPin< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): boolean { const { enableRowPinning } = row.table.options if (typeof enableRowPinning === 'function') { return enableRowPinning(row) } return enableRowPinning ?? true } export function row_getIsPinned< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): RowPinningPosition { const { top, bottom } = row.table.store.state.rowPinning ?? getDefaultRowPinningState() return top.includes(row.id) ? 'top' : bottom.includes(row.id) ? 'bottom' : false } export function row_getPinnedIndex< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): number { const position = row_getIsPinned(row) if (!position) return -1 const visiblePinnedRowIds = ( position === 'top' ? callMemoOrStaticFn(row.table, 'getTopRows', table_getTopRows) : callMemoOrStaticFn(row.table, 'getBottomRows', table_getBottomRows) ).map(({ id }) => id) return visiblePinnedRowIds.indexOf(row.id) } export function row_pin( row: Row, position: RowPinningPosition, includeLeafRows?: boolean, includeParentRows?: boolean, ): void { const leafRowIds = includeLeafRows ? row.getLeafRows().map(({ id }) => id) : [] const parentRowIds = includeParentRows ? row.getParentRows().map(({ id }) => id) : [] const rowIds: Set = new Set([...parentRowIds, row.id, ...leafRowIds]) table_setRowPinning(row.table, (old) => { if (position === 'bottom') { return { top: old.top.filter((d) => !rowIds.has(d)), bottom: [ ...old.bottom.filter((d) => !rowIds.has(d)), ...Array.from(rowIds), ], } } if (position === 'top') { return { top: [...old.top.filter((d) => !rowIds.has(d)), ...Array.from(rowIds)], bottom: old.bottom.filter((d) => !rowIds.has(d)), } } return { top: old.top.filter((d) => !rowIds.has(d)), bottom: old.bottom.filter((d) => !rowIds.has(d)), } }) } ================================================ FILE: packages/table-core/src/features/row-selection/rowSelectionFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { getDefaultRowSelectionState, row_getCanMultiSelect, row_getCanSelect, row_getCanSelectSubRows, row_getIsAllSubRowsSelected, row_getIsSelected, row_getIsSomeSelected, row_getToggleSelectedHandler, row_toggleSelected, table_getFilteredSelectedRowModel, table_getGroupedSelectedRowModel, table_getIsAllPageRowsSelected, table_getIsAllRowsSelected, table_getIsSomePageRowsSelected, table_getIsSomeRowsSelected, table_getPreSelectedRowModel, table_getSelectedRowModel, table_getToggleAllPageRowsSelectedHandler, table_getToggleAllRowsSelectedHandler, table_resetRowSelection, table_setRowSelection, table_toggleAllPageRowsSelected, table_toggleAllRowsSelected, } from './rowSelectionFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // Row_RowSelection, // TableOptions_RowSelection, // TableState_RowSelection, // Table_RowSelection, // } from './rowSelectionFeature.types' interface RowSelectionFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // Row: Row_RowSelection // Table: Table_RowSelection // TableOptions: TableOptions_RowSelection // TableState: TableState_RowSelection } export function constructRowSelectionFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState: (initialState) => { return { rowSelection: getDefaultRowSelectionState(), ...initialState, } }, getDefaultTableOptions: (table) => { return { onRowSelectionChange: makeStateUpdater('rowSelection', table), enableRowSelection: true, enableMultiRowSelection: true, enableSubRowSelection: true, } }, assignRowPrototype: (prototype, table) => { assignPrototypeAPIs('rowSelectionFeature', prototype, table, { row_toggleSelected: { fn: (row, value, opts) => row_toggleSelected(row, value, opts), }, row_getIsSelected: { fn: (row) => row_getIsSelected(row), }, row_getIsSomeSelected: { fn: (row) => row_getIsSomeSelected(row), }, row_getIsAllSubRowsSelected: { fn: (row) => row_getIsAllSubRowsSelected(row), }, row_getCanSelect: { fn: (row) => row_getCanSelect(row), }, row_getCanSelectSubRows: { fn: (row) => row_getCanSelectSubRows(row), }, row_getCanMultiSelect: { fn: (row) => row_getCanMultiSelect(row), }, row_getToggleSelectedHandler: { fn: (row) => row_getToggleSelectedHandler(row), }, }) }, constructTableAPIs: (table) => { assignTableAPIs('rowSelectionFeature', table, { table_setRowSelection: { fn: (updater) => table_setRowSelection(table, updater), }, table_resetRowSelection: { fn: (defaultState) => table_resetRowSelection(table, defaultState), }, table_toggleAllRowsSelected: { fn: (value) => table_toggleAllRowsSelected(table, value), }, table_toggleAllPageRowsSelected: { fn: (value) => table_toggleAllPageRowsSelected(table, value), }, table_getPreSelectedRowModel: { fn: () => table_getPreSelectedRowModel(table), }, table_getSelectedRowModel: { fn: () => table_getSelectedRowModel(table), memoDeps: () => [ table.store.state.rowSelection, table.getCoreRowModel(), ], }, table_getFilteredSelectedRowModel: { fn: () => table_getFilteredSelectedRowModel(table), memoDeps: () => [ table.store.state.rowSelection, table.getFilteredRowModel(), ], }, table_getGroupedSelectedRowModel: { fn: () => table_getGroupedSelectedRowModel(table), memoDeps: () => [ table.store.state.rowSelection, table.getSortedRowModel(), ], }, table_getIsAllRowsSelected: { fn: () => table_getIsAllRowsSelected(table), }, table_getIsAllPageRowsSelected: { fn: () => table_getIsAllPageRowsSelected(table), }, table_getIsSomeRowsSelected: { fn: () => table_getIsSomeRowsSelected(table), }, table_getIsSomePageRowsSelected: { fn: () => table_getIsSomePageRowsSelected(table), }, table_getToggleAllRowsSelectedHandler: { fn: () => table_getToggleAllRowsSelectedHandler(table), }, table_getToggleAllPageRowsSelectedHandler: { fn: () => table_getToggleAllPageRowsSelectedHandler(table), }, }) }, } } /** * The Row Selection feature adds row selection state and APIs to the table and row objects. */ export const rowSelectionFeature = constructRowSelectionFeature() ================================================ FILE: packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts ================================================ import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Row } from '../../types/Row' export type RowSelectionState = Record export interface TableState_RowSelection { rowSelection: RowSelectionState } export interface TableOptions_RowSelection< TFeatures extends TableFeatures, TData extends RowData, > { /** * - Enables/disables multiple row selection for all rows in the table OR * - A function that given a row, returns whether to enable/disable multiple row selection for that row's children/grandchildren */ enableMultiRowSelection?: boolean | ((row: Row) => boolean) /** * - Enables/disables row selection for all rows in the table OR * - A function that given a row, returns whether to enable/disable row selection for that row */ enableRowSelection?: boolean | ((row: Row) => boolean) /** * Enables/disables automatic sub-row selection when a parent row is selected, or a function that enables/disables automatic sub-row selection for each row. * (Use in combination with expanding or grouping features) */ enableSubRowSelection?: boolean | ((row: Row) => boolean) /** * If provided, this function will be called with an `updaterFn` when `state.rowSelection` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. */ onRowSelectionChange?: OnChangeFn // enableGroupingRowSelection?: // | boolean // | (( // row: Row // ) => boolean) // isAdditiveSelectEvent?: (e: unknown) => boolean // isInclusiveSelectEvent?: (e: unknown) => boolean // selectRowsFn?: ( // table: Table, // rowModel: RowModel // ) => RowModel } export interface Row_RowSelection { /** * Returns whether or not the row can multi-select. */ getCanMultiSelect: () => boolean /** * Returns whether or not the row can be selected. */ getCanSelect: () => boolean /** * Returns whether or not the row can select sub rows automatically when the parent row is selected. */ getCanSelectSubRows: () => boolean /** * Returns whether or not all of the row's sub rows are selected. */ getIsAllSubRowsSelected: () => boolean /** * Returns whether or not the row is selected. */ getIsSelected: () => boolean /** * Returns whether or not some of the row's sub rows are selected. */ getIsSomeSelected: () => boolean /** * Returns a handler that can be used to toggle the row. */ getToggleSelectedHandler: () => (event: unknown) => void /** * Selects/deselects the row. */ toggleSelected: (value?: boolean, opts?: { selectChildren?: boolean }) => void } export interface Table_RowSelection< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model of all rows that are selected after filtering has been applied. */ getFilteredSelectedRowModel: () => RowModel /** * Returns the row model of all rows that are selected after grouping has been applied. */ getGroupedSelectedRowModel: () => RowModel /** * Returns whether or not all rows on the current page are selected. */ getIsAllPageRowsSelected: () => boolean /** * Returns whether or not all rows in the table are selected. */ getIsAllRowsSelected: () => boolean /** * Returns whether or not any rows on the current page are selected. */ getIsSomePageRowsSelected: () => boolean /** * Returns whether or not any rows in the table are selected. */ getIsSomeRowsSelected: () => boolean /** * Returns the core row model of all rows before row selection has been applied. */ getPreSelectedRowModel: () => RowModel /** * Returns the row model of all rows that are selected. */ getSelectedRowModel: () => RowModel /** * Returns a handler that can be used to toggle all rows on the current page. */ getToggleAllPageRowsSelectedHandler: () => (event: unknown) => void /** * Returns a handler that can be used to toggle all rows in the table. */ getToggleAllRowsSelectedHandler: () => (event: unknown) => void /** * Resets the **rowSelection** state to the `initialState.rowSelection`, or `true` can be passed to force a default blank state reset to `{}`. */ resetRowSelection: (defaultState?: boolean) => void /** * Sets or updates the `state.rowSelection` state. */ setRowSelection: (updater: Updater) => void /** * Selects/deselects all rows on the current page. */ toggleAllPageRowsSelected: (value?: boolean) => void /** * Selects/deselects all rows in the table. */ toggleAllRowsSelected: (value?: boolean) => void } ================================================ FILE: packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts ================================================ import type { RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { RowSelectionState } from './rowSelectionFeature.types' // State APIs export function getDefaultRowSelectionState(): RowSelectionState { return structuredClone({}) } export function table_setRowSelection< TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal, updater: Updater, ) { table.options.onRowSelectionChange?.(updater) } export function table_resetRowSelection< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setRowSelection( table, defaultState ? {} : (table.initialState.rowSelection ?? {}), ) } // Table APIs export function table_toggleAllRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, value?: boolean) { table_setRowSelection(table, (old) => { value = typeof value !== 'undefined' ? value : !table_getIsAllRowsSelected(table) const rowSelection = { ...old } const preGroupedFlatRows = table.getPreGroupedRowModel().flatRows // We don't use `mutateRowIsSelected` here for performance reasons. // All of the rows are flat already, so it wouldn't be worth it if (value) { preGroupedFlatRows.forEach((row) => { if (!row_getCanSelect(row)) { return } rowSelection[row.id] = true }) } else { preGroupedFlatRows.forEach((row) => { delete rowSelection[row.id] }) } return rowSelection }) } export function table_toggleAllPageRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, value?: boolean) { table_setRowSelection(table, (old) => { const resolvedValue = typeof value !== 'undefined' ? value : !table_getIsAllPageRowsSelected(table) const rowSelection: RowSelectionState = { ...old } table.getRowModel().rows.forEach((row) => { mutateRowIsSelected(rowSelection, row.id, resolvedValue, true, table) }) return rowSelection }) } export function table_getPreSelectedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal): RowModel { return table.getCoreRowModel() } export function table_getSelectedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const rowModel = table.getCoreRowModel() if (!Object.keys(table.store.state.rowSelection ?? {}).length) { return { rows: [], flatRows: [], rowsById: {}, } } return selectRowsFn(rowModel) } export function table_getFilteredSelectedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const rowModel = table.getCoreRowModel() if (!Object.keys(table.store.state.rowSelection ?? {}).length) { return { rows: [], flatRows: [], rowsById: {}, } } return selectRowsFn(rowModel) } export function table_getGroupedSelectedRowModel< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const rowModel = table.getCoreRowModel() if (!Object.keys(table.store.state.rowSelection ?? {}).length) { return { rows: [], flatRows: [], rowsById: {}, } } return selectRowsFn(rowModel) } export function table_getIsAllRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const preGroupedFlatRows = table.getFilteredRowModel().flatRows const rowSelection = table.store.state.rowSelection ?? ({} as RowSelectionState) let isAllRowsSelected = Boolean( preGroupedFlatRows.length && Object.keys(rowSelection).length, ) if (isAllRowsSelected) { if ( preGroupedFlatRows.some( (row) => row_getCanSelect(row) && !rowSelection[row.id], ) ) { isAllRowsSelected = false } } return isAllRowsSelected } export function table_getIsAllPageRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const paginationFlatRows = table .getPaginatedRowModel() .flatRows.filter((row) => row_getCanSelect(row)) const rowSelection = table.store.state.rowSelection ?? ({} as RowSelectionState) let isAllPageRowsSelected = !!paginationFlatRows.length if ( isAllPageRowsSelected && paginationFlatRows.some((row) => !rowSelection[row.id]) ) { isAllPageRowsSelected = false } return isAllPageRowsSelected } export function table_getIsSomeRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const totalSelected = Object.keys(table.store.state.rowSelection ?? {}).length return ( totalSelected > 0 && totalSelected < table.getFilteredRowModel().flatRows.length ) } export function table_getIsSomePageRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { const paginationFlatRows = table.getPaginatedRowModel().flatRows return table_getIsAllPageRowsSelected(table) ? false : paginationFlatRows .filter((row) => row_getCanSelect(row)) .some((row) => row_getIsSelected(row) || row_getIsSomeSelected(row)) } export function table_getToggleAllRowsSelectedHandler< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return (e: unknown) => { table_toggleAllRowsSelected( table, ((e as MouseEvent).target as HTMLInputElement).checked, ) } } export function table_getToggleAllPageRowsSelectedHandler< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal) { return (e: unknown) => { table_toggleAllPageRowsSelected( table, ((e as MouseEvent).target as HTMLInputElement).checked, ) } } // Row APIs export function row_toggleSelected< TFeatures extends TableFeatures, TData extends RowData, >( row: Row, value?: boolean, opts?: { selectChildren?: boolean }, ) { const isSelected = row_getIsSelected(row) table_setRowSelection(row.table, (old) => { value = typeof value !== 'undefined' ? value : !isSelected if (row_getCanSelect(row) && isSelected === value) { return old } const selectedRowIds = { ...old } mutateRowIsSelected( selectedRowIds, row.id, value, opts?.selectChildren ?? true, row.table, ) return selectedRowIds }) } export function row_getIsSelected< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return isRowSelected(row) } export function row_getIsSomeSelected< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return isSubRowSelected(row) === 'some' } export function row_getIsAllSubRowsSelected< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { return isSubRowSelected(row) === 'all' } export function row_getCanSelect< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const options = row.table.options if (typeof options.enableRowSelection === 'function') { return options.enableRowSelection(row) } return options.enableRowSelection ?? true } export function row_getCanSelectSubRows< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const options = row.table.options if (typeof options.enableSubRowSelection === 'function') { return options.enableSubRowSelection(row) } return options.enableSubRowSelection ?? true } export function row_getCanMultiSelect< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const options = row.table.options if (typeof options.enableMultiRowSelection === 'function') { return options.enableMultiRowSelection(row) } return options.enableMultiRowSelection ?? true } export function row_getToggleSelectedHandler< TFeatures extends TableFeatures, TData extends RowData, >(row: Row) { const canSelect = row_getCanSelect(row) return (e: unknown) => { if (!canSelect) return row_toggleSelected( row, ((e as MouseEvent).target as HTMLInputElement).checked, ) } } const mutateRowIsSelected = < TFeatures extends TableFeatures, TData extends RowData, >( selectedRowIds: Record, rowId: string, value: boolean, includeChildren: boolean, table: Table_Internal, ) => { const row = table.getRow(rowId, true) if (value) { if (!row_getCanMultiSelect(row)) { Object.keys(selectedRowIds).forEach((key) => delete selectedRowIds[key]) } if (row_getCanSelect(row)) { selectedRowIds[rowId] = true } } else { delete selectedRowIds[rowId] } if (includeChildren && row.subRows.length && row_getCanSelectSubRows(row)) { row.subRows.forEach((r) => mutateRowIsSelected(selectedRowIds, r.id, value, includeChildren, table), ) } } export function selectRowsFn< TFeatures extends TableFeatures, TData extends RowData, >(rowModel: RowModel): RowModel { const newSelectedFlatRows: Array> = [] const newSelectedRowsById: Record> = {} // Filters top level and nested rows const recurseRows = ( rows: Array>, depth = 0, ): Array> => { return rows .map((row) => { const isSelected = isRowSelected(row) if (isSelected) { newSelectedFlatRows.push(row) newSelectedRowsById[row.id] = row } if (row.subRows.length) { row = { ...row, subRows: recurseRows(row.subRows, depth + 1), } } if (isSelected) { return row } }) .filter((x) => !!x) } return { rows: recurseRows(rowModel.rows), flatRows: newSelectedFlatRows, rowsById: newSelectedRowsById, } } export function isRowSelected< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): boolean { return (row.table.store.state.rowSelection ?? {})[row.id] ?? false } export function isSubRowSelected< TFeatures extends TableFeatures, TData extends RowData, >(row: Row): boolean | 'some' | 'all' { if (!row.subRows.length) return false let allChildrenSelected = true let someSelected = false row.subRows.forEach((subRow) => { // Bail out early if we know both of these if (someSelected && !allChildrenSelected) { return } if (row_getCanSelect(subRow)) { if (isRowSelected(subRow)) { someSelected = true } else { allChildrenSelected = false } } // Check row selection of nested subrows if (subRow.subRows.length) { const subRowChildrenSelected = isSubRowSelected(subRow) if (subRowChildrenSelected === 'all') { someSelected = true } else if (subRowChildrenSelected === 'some') { someSelected = true allChildrenSelected = false } else { allChildrenSelected = false } } }) // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition return allChildrenSelected ? 'all' : someSelected ? 'some' : false } ================================================ FILE: packages/table-core/src/features/row-sorting/createSortedRowModel.ts ================================================ import { tableMemo } from '../../utils' import { table_autoResetPageIndex } from '../row-pagination/rowPaginationFeature.utils' import { column_getCanSort, column_getSortFn } from './rowSortingFeature.utils' import type { Column_Internal } from '../../types/Column' import type { TableFeatures } from '../../types/TableFeatures' import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table, Table_Internal } from '../../types/Table' import type { Row } from '../../types/Row' import type { SortFn, SortFns } from './rowSortingFeature.types' import type { RowData } from '../../types/type-utils' export function createSortedRowModel< TFeatures extends TableFeatures, TData extends RowData, >( sortFns: Record>, ): (table: Table) => () => RowModel { return (_table) => { const table = _table as Table_Internal if (!table._rowModelFns.sortFns) table._rowModelFns.sortFns = sortFns return tableMemo({ feature: 'rowSortingFeature', table, fnName: 'table.getSortedRowModel', memoDeps: () => [table.store.state.sorting, table.getPreSortedRowModel()], fn: () => _createSortedRowModel(table), onAfterUpdate: () => table_autoResetPageIndex(table), }) } } function _createSortedRowModel< TFeatures extends TableFeatures, TData extends RowData = any, >(table: Table_Internal): RowModel { const preSortedRowModel = table.getPreSortedRowModel() const sorting = table.store.state.sorting if (!preSortedRowModel.rows.length || !sorting?.length) { return preSortedRowModel } const sortedFlatRows: Array> = [] // Filter out sortings that correspond to non existing columns const availableSorting = sorting.filter((sort) => column_getCanSort( table.getColumn(sort.id) as Column_Internal, ), ) const columnInfoById: Record< string, { sortUndefined?: false | -1 | 1 | 'first' | 'last' invertSorting?: boolean sortFn: SortFn } > = {} availableSorting.forEach((sortEntry) => { const column = table.getColumn(sortEntry.id) as | Column_Internal | undefined if (!column) return columnInfoById[sortEntry.id] = { sortUndefined: column.columnDef.sortUndefined, invertSorting: column.columnDef.invertSorting, sortFn: column_getSortFn(column), } }) const sortData = (rows: Array>) => { // This will also perform a stable sorting using the row index // if needed. // Preserve prototype chain so methods like getValue() remain accessible const sortedData = rows.map((row) => { const cloned = Object.create(Object.getPrototypeOf(row)) return Object.assign(cloned, row) }) sortedData.sort((rowA, rowB) => { for (const sortEntry of availableSorting) { const columnInfo = columnInfoById[sortEntry.id]! const sortUndefined = columnInfo.sortUndefined const isDesc = sortEntry.desc let sortInt = 0 // All sorting ints should always return in ascending order if (sortUndefined) { const aValue = rowA.getValue(sortEntry.id) const bValue = rowB.getValue(sortEntry.id) const aUndefined = aValue === undefined const bUndefined = bValue === undefined if (aUndefined || bUndefined) { if (sortUndefined === 'first') return aUndefined ? -1 : 1 if (sortUndefined === 'last') return aUndefined ? 1 : -1 sortInt = aUndefined && bUndefined ? 0 : aUndefined ? sortUndefined : -sortUndefined } } if (sortInt === 0) { sortInt = columnInfo.sortFn(rowA, rowB, sortEntry.id) } // If sorting is non-zero, take care of desc and inversion if (sortInt !== 0) { if (isDesc) { sortInt *= -1 } if (columnInfo.invertSorting) { sortInt *= -1 } return sortInt } } return rowA.index - rowB.index }) // If there are sub-rows, sort them sortedData.forEach((row) => { sortedFlatRows.push(row) if (row.subRows.length) { row.subRows = sortData(row.subRows) } }) return sortedData } return { rows: sortData(preSortedRowModel.rows), flatRows: sortedFlatRows, rowsById: preSortedRowModel.rowsById, } } ================================================ FILE: packages/table-core/src/features/row-sorting/rowSortingFeature.ts ================================================ import { assignPrototypeAPIs, assignTableAPIs, makeStateUpdater, } from '../../utils' import { column_clearSorting, column_getAutoSortDir, column_getAutoSortFn, column_getCanMultiSort, column_getCanSort, column_getFirstSortDir, column_getIsSorted, column_getNextSortingOrder, column_getSortFn, column_getSortIndex, column_getToggleSortingHandler, column_toggleSorting, getDefaultSortingState, table_resetSorting, table_setSorting, } from './rowSortingFeature.utils' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' // import type { // CachedRowModel_Sorted, // ColumnDef_RowSorting, // Column_RowSorting, // CreateRowModel_Sorted, // RowModelFns_RowSorting, // TableOptions_RowSorting, // TableState_RowSorting, // Table_RowSorting, // } from './rowSortingFeature.types' interface RowSortingFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > { // CachedRowModel: CachedRowModel_Sorted // Column: Column_RowSorting // ColumnDef: ColumnDef_RowSorting // CreateRowModels: CreateRowModel_Sorted // RowModelFns: RowModelFns_RowSorting // Table: Table_RowSorting // TableOptions: TableOptions_RowSorting // TableState: TableState_RowSorting } export function constructRowSortingFeature< TFeatures extends TableFeatures, TData extends RowData, >(): TableFeature> { return { getInitialState(initialState) { return { sorting: getDefaultSortingState(), ...initialState, } }, getDefaultColumnDef() { return { sortFn: 'auto', sortUndefined: 1, } }, getDefaultTableOptions(table) { return { onSortingChange: makeStateUpdater('sorting', table), isMultiSortEvent: (e: unknown) => { return (e as MouseEvent).shiftKey }, } }, assignColumnPrototype(prototype, table) { assignPrototypeAPIs('rowSortingFeature', prototype, table, { 'column.getAutoSortFn': { fn: (column) => column_getAutoSortFn(column), }, 'column.getAutoSortDir': { fn: (column) => column_getAutoSortDir(column), }, column_getSortFn: { fn: (column) => column_getSortFn(column), }, column_toggleSorting: { fn: (column, desc, multi) => column_toggleSorting(column, desc, multi), }, column_getFirstSortDir: { fn: (column) => column_getFirstSortDir(column), }, column_getNextSortingOrder: { fn: (column, multi) => column_getNextSortingOrder(column, multi), }, column_getCanSort: { fn: (column) => column_getCanSort(column), }, column_getCanMultiSort: { fn: (column) => column_getCanMultiSort(column), }, column_getIsSorted: { fn: (column) => column_getIsSorted(column), }, column_getSortIndex: { fn: (column) => column_getSortIndex(column), }, column_clearSorting: { fn: (column) => column_clearSorting(column), }, column_getToggleSortingHandler: { fn: (column) => column_getToggleSortingHandler(column), }, }) }, constructTableAPIs(table) { assignTableAPIs('rowSortingFeature', table, { table_setSorting: { fn: (updater) => table_setSorting(table, updater), }, table_resetSorting: { fn: (defaultState) => table_resetSorting(table, defaultState), }, }) }, } } /** * The (Row) Sorting feature adds sorting state and APIs to the table and column objects. */ export const rowSortingFeature = constructRowSortingFeature() ================================================ FILE: packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts ================================================ import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types' import type { Table } from '../../types/Table' import type { BuiltInSortFn } from '../../fns/sortFns' import type { OnChangeFn, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Row } from '../../types/Row' export type SortDirection = 'asc' | 'desc' export interface ColumnSort { desc: boolean id: string } export type SortingState = Array export interface TableState_RowSorting { sorting: SortingState } export interface RowModelFns_RowSorting< TFeatures extends TableFeatures, TData extends RowData, > { sortFns: Record> } export interface SortFns {} export interface SortFn< TFeatures extends TableFeatures, TData extends RowData, > { ( rowA: Row, rowB: Row, columnId: string, ): number } export type CustomSortFns< TFeatures extends TableFeatures, TData extends RowData, > = Record> export type SortFnOption< TFeatures extends TableFeatures, TData extends RowData, > = 'auto' | keyof SortFns | BuiltInSortFn | SortFn export interface ColumnDef_RowSorting< TFeatures extends TableFeatures, TData extends RowData, > { /** * Enables/Disables multi-sorting for this column. */ enableMultiSort?: boolean /** * Enables/Disables sorting for this column. */ enableSorting?: boolean /** * Inverts the order of the sorting for this column. This is useful for values that have an inverted best/worst scale where lower numbers are better, eg. a ranking (1st, 2nd, 3rd) or golf-like scoring */ invertSorting?: boolean /** * Set to `true` for sorting toggles on this column to start in the descending direction. */ sortDescFirst?: boolean /** * The sorting function to use with this column. * - A `string` referencing a built-in sorting function * - A custom sorting function */ sortFn?: SortFnOption /** * The priority of undefined values when sorting this column. * - `false` * - Undefined values will be considered tied and need to be sorted by the next column filter or original index (whichever applies) * - `-1` * - Undefined values will be sorted with higher priority (ascending) (if ascending, undefined will appear on the beginning of the list) * - `1` * - Undefined values will be sorted with lower priority (descending) (if ascending, undefined will appear on the end of the list) */ sortUndefined?: false | -1 | 1 | 'first' | 'last' } export interface Column_RowSorting< TFeatures extends TableFeatures, TData extends RowData, > { /** * Removes this column from the table's sorting state */ clearSorting: () => void /** * Returns a sort direction automatically inferred based on the columns values. */ getAutoSortDir: () => SortDirection /** * Returns a sorting function automatically inferred based on the columns values. */ getAutoSortFn: () => SortFn /** * Returns whether this column can be multi-sorted. */ getCanMultiSort: () => boolean /** * Returns whether this column can be sorted. */ getCanSort: () => boolean /** * Returns the first direction that should be used when sorting this column. */ getFirstSortDir: () => SortDirection /** * Returns the current sort direction of this column. */ getIsSorted: () => false | SortDirection /** * Returns the next sorting order. */ getNextSortingOrder: () => SortDirection | false /** * Returns the index position of this column's sorting within the sorting state */ getSortIndex: () => number /** * Returns the resolved sorting function to be used for this column */ getSortFn: () => SortFn /** * Returns a function that can be used to toggle this column's sorting state. This is useful for attaching a click handler to the column header. */ getToggleSortingHandler: () => undefined | ((event: unknown) => void) /** * Toggles this columns sorting state. If `desc` is provided, it will force the sort direction to that value. If `isMulti` is provided, it will additivity multi-sort the column (or toggle it if it is already sorted). */ toggleSorting: (desc?: boolean, isMulti?: boolean) => void } export interface TableOptions_RowSorting { /** * Enables/disables the ability to remove multi-sorts */ enableMultiRemove?: boolean /** * Enables/Disables multi-sorting for the table. */ enableMultiSort?: boolean /** * Enables/Disables sorting for the table. */ enableSorting?: boolean /** * Enables/Disables the ability to remove sorting for the table. * - If `true` then changing sort order will circle like: 'none' -> 'desc' -> 'asc' -> 'none' -> ... * - If `false` then changing sort order will circle like: 'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ... */ enableSortingRemoval?: boolean /** * Pass a custom function that will be used to determine if a multi-sort event should be triggered. It is passed the event from the sort toggle handler and should return `true` if the event should trigger a multi-sort. */ isMultiSortEvent?: (e: unknown) => boolean /** * Enables manual sorting for the table. If this is `true`, you will be expected to sort your data before it is passed to the table. This is useful if you are doing server-side sorting. */ manualSorting?: boolean /** * Set a maximum number of columns that can be multi-sorted. */ maxMultiSortColCount?: number /** * If provided, this function will be called with an `updaterFn` when `state.sorting` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table. */ onSortingChange?: OnChangeFn /** * If `true`, all sorts will default to descending as their first toggle state. */ sortDescFirst?: boolean } export interface Table_RowSorting< TFeatures extends TableFeatures, TData extends RowData, > { /** * Resets the **sorting** state to `initialState.sorting`, or `true` can be passed to force a default blank state reset to `[]`. */ resetSorting: (defaultState?: boolean) => void /** * Sets or updates the `state.sorting` state. */ setSorting: (updater: Updater) => void } export interface Table_RowModels_Sorted< TFeatures extends TableFeatures, TData extends RowData, > { /** * Returns the row model for the table before any sorting has been applied. */ getPreSortedRowModel: () => RowModel /** * Returns the row model for the table after sorting has been applied. */ getSortedRowModel: () => RowModel } export interface CreateRowModel_Sorted< TFeatures extends TableFeatures, TData extends RowData, > { /** * This function is used to retrieve the sorted row model. If using server-side sorting, this function is not required. To use client-side sorting, pass the exported `getSortedRowModel()` from your adapter to your table or implement your own. */ sortedRowModel?: ( table: Table, ) => () => RowModel } export interface CachedRowModel_Sorted< TFeatures extends TableFeatures, TData extends RowData, > { sortedRowModel: () => RowModel } ================================================ FILE: packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts ================================================ import { reSplitAlphaNumeric, sortFn_basic } from '../../fns/sortFns' import { isFunction } from '../../utils' import type { CellData, RowData, Updater } from '../../types/type-utils' import type { TableFeatures } from '../../types/TableFeatures' import type { Table_Internal } from '../../types/Table' import type { Column_Internal } from '../../types/Column' import type { SortDirection, SortFn, SortingState, } from './rowSortingFeature.types' // State Utils export function getDefaultSortingState(): SortingState { return structuredClone([]) } export function table_setSorting< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, updater: Updater) { table.options.onSortingChange?.(updater) } export function table_resetSorting< TFeatures extends TableFeatures, TData extends RowData, >(table: Table_Internal, defaultState?: boolean) { table_setSorting( table, defaultState ? [] : (table.initialState.sorting ?? []), ) } // Column Utils export function column_getAutoSortFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): SortFn { const sortFns = column.table._rowModelFns.sortFns as | Record> | undefined let sortFn: SortFn | undefined const firstRows = column.table.getFilteredRowModel().flatRows.slice(10) let isString = false for (const row of firstRows) { const value = row.getValue(column.id) if (Object.prototype.toString.call(value) === '[object Date]') { sortFn = sortFns?.datetime } if (typeof value === 'string') { isString = true if (value.split(reSplitAlphaNumeric).length > 1) { sortFn = sortFns?.alphanumeric } } } if (isString) { sortFn = sortFns?.text } return sortFn ?? sortFn_basic } export function column_getAutoSortDir< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const firstRow = column.table.getFilteredRowModel().flatRows[0] const value = firstRow ? firstRow.getValue(column.id) : undefined if (typeof value === 'string') { return 'asc' } return 'desc' } export function column_getSortFn< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): SortFn { const sortFns = column.table._rowModelFns.sortFns as | Record> | undefined return isFunction(column.columnDef.sortFn) ? column.columnDef.sortFn : column.columnDef.sortFn === 'auto' ? column_getAutoSortFn(column) : (sortFns?.[column.columnDef.sortFn as string] ?? sortFn_basic) } export function column_toggleSorting< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, desc?: boolean, multi?: boolean, ) { // if (column.columns.length) { // column.columns.forEach((c, i) => { // if (c.id) { // table.toggleColumnSorting(c.id, undefined, multi || !!i) // } // }) // return // } // this needs to be outside of table.setSorting to be in sync with rerender const nextSortingOrder = column_getNextSortingOrder(column) const hasManualValue = typeof desc !== 'undefined' table_setSorting(column.table, (old) => { // Find any existing sorting for this column const existingSorting = old.find((d) => d.id === column.id) const existingIndex = old.findIndex((d) => d.id === column.id) let newSorting: SortingState = [] // What should we do with this sort action? let sortAction: 'add' | 'remove' | 'toggle' | 'replace' const nextDesc = hasManualValue ? desc : nextSortingOrder === 'desc' // Multi-mode if (old.length && column_getCanMultiSort(column) && multi) { if (existingSorting) { sortAction = 'toggle' } else { sortAction = 'add' } } else { // Normal mode if (old.length && existingIndex !== old.length - 1) { sortAction = 'replace' } else if (existingSorting) { sortAction = 'toggle' } else { sortAction = 'replace' } } // Handle toggle states that will remove the sorting if (sortAction === 'toggle') { // If we are "actually" toggling (not a manual set value), should we remove the sorting? if (!hasManualValue) { // Is our intention to remove? if (!nextSortingOrder) { sortAction = 'remove' } } } if (sortAction === 'add') { newSorting = [ ...old, { id: column.id, desc: nextDesc, }, ] // Take latest n columns newSorting.splice( 0, newSorting.length - (column.table.options.maxMultiSortColCount ?? Number.MAX_SAFE_INTEGER), ) } else if (sortAction === 'toggle') { // This flips (or sets) the newSorting = old.map((d) => { if (d.id === column.id) { return { ...d, desc: nextDesc, } } return d }) } else if (sortAction === 'remove') { newSorting = old.filter((d) => d.id !== column.id) } else { newSorting = [ { id: column.id, desc: nextDesc, }, ] } return newSorting }) } export function column_getFirstSortDir< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const sortDescFirst = column.columnDef.sortDescFirst ?? column.table.options.sortDescFirst ?? column_getAutoSortDir(column) === 'desc' return sortDescFirst ? 'desc' : 'asc' } export function column_getNextSortingOrder< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal, multi?: boolean) { const firstSortDirection = column_getFirstSortDir(column) const isSorted = column_getIsSorted(column) if (!isSorted) { return firstSortDirection } if ( isSorted !== firstSortDirection && (column.table.options.enableSortingRemoval ?? true) && // If enableSortRemove, enable in general (multi ? (column.table.options.enableMultiRemove ?? true) : true) // If multi, don't allow if enableMultiRemove)) ) { return false } return isSorted === 'desc' ? 'asc' : 'desc' } export function column_getCanSort< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { return ( (column.columnDef.enableSorting ?? true) && (column.table.options.enableSorting ?? true) && !!column.accessorFn ) } export function column_getCanMultiSort< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): boolean { return ( column.columnDef.enableMultiSort ?? column.table.options.enableMultiSort ?? !!column.accessorFn ) } export function column_getIsSorted< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): false | SortDirection { const columnSort = column.table.store.state.sorting?.find( (d) => d.id === column.id, ) return !columnSort ? false : columnSort.desc ? 'desc' : 'asc' } export function column_getSortIndex< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal): number { return ( column.table.store.state.sorting?.findIndex((d) => d.id === column.id) ?? -1 ) } export function column_clearSorting< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { // clear sorting for just 1 column table_setSorting(column.table, (old) => old.length ? old.filter((d) => d.id !== column.id) : [], ) } export function column_getToggleSortingHandler< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >(column: Column_Internal) { const canSort = column_getCanSort(column) return (e: unknown) => { if (!canSort) return ;(e as any).persist?.() column_toggleSorting( column, undefined, column_getCanMultiSort(column) ? column.table.options.isMultiSortEvent?.(e) : false, ) } } ================================================ FILE: packages/table-core/src/features/stockFeatures.ts ================================================ import { columnFacetingFeature } from './column-faceting/columnFacetingFeature' import { columnFilteringFeature } from './column-filtering/columnFilteringFeature' import { columnGroupingFeature } from './column-grouping/columnGroupingFeature' import { columnOrderingFeature } from './column-ordering/columnOrderingFeature' import { columnPinningFeature } from './column-pinning/columnPinningFeature' import { columnResizingFeature } from './column-resizing/columnResizingFeature' import { columnSizingFeature } from './column-sizing/columnSizingFeature' import { columnVisibilityFeature } from './column-visibility/columnVisibilityFeature' import { globalFilteringFeature } from './global-filtering/globalFilteringFeature' import { rowExpandingFeature } from './row-expanding/rowExpandingFeature' import { rowPaginationFeature } from './row-pagination/rowPaginationFeature' import { rowPinningFeature } from './row-pinning/rowPinningFeature' import { rowSelectionFeature } from './row-selection/rowSelectionFeature' import { rowSortingFeature } from './row-sorting/rowSortingFeature' export interface StockFeatures { columnFacetingFeature: typeof columnFacetingFeature columnFilteringFeature: typeof columnFilteringFeature columnGroupingFeature: typeof columnGroupingFeature columnOrderingFeature: typeof columnOrderingFeature columnPinningFeature: typeof columnPinningFeature columnResizingFeature: typeof columnResizingFeature columnSizingFeature: typeof columnSizingFeature columnVisibilityFeature: typeof columnVisibilityFeature globalFilteringFeature: typeof globalFilteringFeature rowExpandingFeature: typeof rowExpandingFeature rowPaginationFeature: typeof rowPaginationFeature rowPinningFeature: typeof rowPinningFeature rowSelectionFeature: typeof rowSelectionFeature rowSortingFeature: typeof rowSortingFeature } export const stockFeatures: StockFeatures = { columnFacetingFeature, columnFilteringFeature, columnGroupingFeature, columnOrderingFeature, columnPinningFeature, columnResizingFeature, columnSizingFeature, columnVisibilityFeature, globalFilteringFeature, rowExpandingFeature, rowPaginationFeature, rowPinningFeature, rowSelectionFeature, rowSortingFeature, } as const ================================================ FILE: packages/table-core/src/features/table-reactivity/tableReactivityFeature.ts ================================================ import type { ReadonlyStore, Store } from '@tanstack/store' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' import type { RowData } from '../../types/type-utils' interface TableReactivityFeatureConstructors< TFeatures extends TableFeatures, TData extends RowData, > {} export function constructReactivityFeature< TFeatures extends TableFeatures, TData extends RowData, >(bindings: { stateNotifier?: () => unknown optionsNotifier?: () => unknown }): TableFeature> { return { constructTableAPIs: (table) => { table.store = bindStore(table.store, bindings.stateNotifier) table.optionsStore = bindStore( table.optionsStore, bindings.optionsNotifier, ) }, } } const bindStore = | ReadonlyStore>( store: T, notifier?: () => unknown, ): T => { const stateDescriptor = Object.getOwnPropertyDescriptor( Object.getPrototypeOf(store), 'state', )! Object.defineProperty(store, 'state', { configurable: true, enumerable: true, get() { notifier?.() return stateDescriptor.get!.call(store) }, }) return store } ================================================ FILE: packages/table-core/src/fns/aggregationFns.ts ================================================ import { isNumberArray } from '../utils' import type { RowData } from '../types/type-utils' import type { TableFeatures } from '../types/TableFeatures' import type { Row } from '../types/Row' import type { AggregationFn } from '../features/column-grouping/columnGroupingFeature.types' /** * Aggregation function for summing up the values of a column. */ export const aggregationFn_sum: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, _leafRows: Array>, childRows: Array>, ) => { // It's faster to just add the aggregations together instead of // process leaf nodes individually return childRows.reduce((sumValue, next) => { const nextValue = next.getValue(columnId) return sumValue + (typeof nextValue === 'number' ? nextValue : 0) }, 0) } /** * Aggregation function for finding the minimum value of a column. */ export const aggregationFn_min: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, _leafRows: Array>, childRows: Array>, ) => { let minValue: number | undefined childRows.forEach((row) => { const value = row.getValue(columnId) if ( value != null && typeof value === 'number' && (minValue === undefined || value < minValue) ) { minValue = value } }) return minValue } /** * Aggregation function for finding the maximum value of a column. */ export const aggregationFn_max: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, _leafRows: Array>, childRows: Array>, ) => { let maxValue: number | undefined childRows.forEach((row) => { const value = row.getValue(columnId) if ( value != null && typeof value === 'number' && (maxValue === undefined || value > maxValue) ) { maxValue = value } }) return maxValue } /** * Aggregation function for finding the extent (min and max) of a column. */ export const aggregationFn_extent: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, _leafRows: Array>, childRows: Array>, ) => { let minValue: number | undefined let maxValue: number | undefined childRows.forEach((row) => { const value = row.getValue(columnId) if (value != null && typeof value === 'number') { if (minValue === undefined) { minValue = maxValue = value } else { if (minValue > value) minValue = value if (maxValue! < value) maxValue = value } } }) return [minValue, maxValue] } /** * Aggregation function for finding the mean (average) of a column. */ export const aggregationFn_mean: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, leafRows: Array>, ) => { let count = 0 let sumValue = 0 leafRows.forEach((row) => { const value = row.getValue(columnId) if (value != null && typeof value === 'number') { ++count sumValue += value } else if (value != null) { const numValue = +value if (!Number.isNaN(numValue)) { ++count sumValue += numValue } } }) if (count) return sumValue / count return } /** * Aggregation function for finding the median value of a column. */ export const aggregationFn_median: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, leafRows: Array>, ) => { if (!leafRows.length) { return } const values = leafRows.map((row) => row.getValue(columnId)) if (!isNumberArray(values)) { return } if (values.length === 1) { return values[0] } const mid = Math.floor(values.length / 2) const nums = values.sort((a, b) => a - b) return values.length % 2 !== 0 ? nums[mid] : (nums[mid - 1]! + nums[mid]!) / 2 } /** * Aggregation function for finding the unique values of a column. */ export const aggregationFn_unique: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, leafRows: Array>, ) => { return Array.from(new Set(leafRows.map((d) => d.getValue(columnId))).values()) } /** * Aggregation function for finding the count of unique values of a column. */ export const aggregationFn_uniqueCount: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, leafRows: Array>, ) => { return new Set(leafRows.map((d) => d.getValue(columnId))).size } /** * Aggregation function for counting the number of rows in a column. */ export const aggregationFn_count: AggregationFn = < TFeatures extends TableFeatures, TData extends RowData, >( _columnId: string, leafRows: Array>, ) => { return leafRows.length } export const aggregationFns = { sum: aggregationFn_sum, min: aggregationFn_min, max: aggregationFn_max, extent: aggregationFn_extent, mean: aggregationFn_mean, median: aggregationFn_median, unique: aggregationFn_unique, uniqueCount: aggregationFn_uniqueCount, count: aggregationFn_count, } export type BuiltInAggregationFn = keyof typeof aggregationFns ================================================ FILE: packages/table-core/src/fns/filterFns.ts ================================================ import type { RowData } from '../types/type-utils' import type { TableFeatures } from '../types/TableFeatures' import type { Row } from '../types/Row' import type { FilterFn } from '../features/column-filtering/columnFilteringFeature.types' // Basic filters /** * Filter function for checking if a value is exactly equal to a given value. (JS === comparison) */ export const filterFn_equals: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { return row.getValue(columnId) === filterValue } filterFn_equals.autoRemove = (val: any) => testFalsy(val) /** * Filter function for checking if a value is weakly equal to a given value. (JS == comparison) */ export const filterFn_weakEquals: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: unknown, ) => { return row.getValue(columnId) == filterValue } filterFn_weakEquals.autoRemove = (val: any) => testFalsy(val) // String filters /** * Filter function for checking if a string includes a given substring. (Case-sensitive) */ export const filterFn_includesStringSensitive: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: string, ) => { return Boolean( row.getValue(columnId)?.toString().includes(filterValue.toString()), ) } filterFn_includesStringSensitive.autoRemove = (val: any) => testFalsy(val) /** * Filter function for checking if a string includes a given substring. (Non-case-sensitive) */ export const filterFn_includesString: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: string, ) => { return Boolean( row .getValue(columnId) ?.toString() .toLowerCase() .includes(filterValue.toString().toLowerCase()), ) } filterFn_includesString.autoRemove = (val: any) => testFalsy(val) /** * Filter function for checking if a string is exactly equal to a given string. (Non-case-sensitive) */ export const filterFn_equalsString: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: string, ) => { return ( row.getValue(columnId)?.toString().toLowerCase() === filterValue.toLowerCase() ) } filterFn_equalsString.autoRemove = (val: any) => testFalsy(val) /** * Filter function for checking if a string is exactly equal to a given string. (Case-sensitive) */ export const filterFn_equalsStringSensitive: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: string, ) => { return row.getValue(columnId)?.toString() === filterValue } filterFn_equalsStringSensitive.autoRemove = (val: any) => testFalsy(val) // Number filters /** * Filter function for checking if a number is greater than a given number. */ export const filterFn_greaterThan: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Date | number | string, ) => { const rowValue = row.getValue(columnId) const numericRowValue = rowValue === null || rowValue === undefined ? 0 : +rowValue const numericFilterValue = +filterValue if (!isNaN(numericFilterValue) && !isNaN(numericRowValue)) { return numericRowValue > numericFilterValue } const stringValue = (rowValue ?? '').toString().toLowerCase().trim() const stringFilterValue = filterValue.toString().toLowerCase().trim() return stringValue > stringFilterValue } filterFn_greaterThan.resolveFilterValue = (val: any) => testFalsy(val) /** * Filter function for checking if a number is greater than or equal to a given number. */ export const filterFn_greaterThanOrEqualTo: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Date | number | string, ) => { return ( filterFn_greaterThan(row as any, columnId, filterValue) || filterFn_equals(row as any, columnId, filterValue) ) } filterFn_greaterThanOrEqualTo.resolveFilterValue = (val: any) => testFalsy(val) /** * Filter function for checking if a number is less than a given number. */ export const filterFn_lessThan: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Date | number | string, ) => { return !filterFn_greaterThanOrEqualTo(row as any, columnId, filterValue) } filterFn_lessThan.resolveFilterValue = (val: any) => testFalsy(val) /** * Filter function for checking if a number is less than or equal to a given number. */ export const filterFn_lessThanOrEqualTo: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Date | number | string, ) => { return !filterFn_greaterThan(row as any, columnId, filterValue) } filterFn_lessThanOrEqualTo.resolveFilterValue = (val: any) => testFalsy(val) // Range filters /** * Filter function for checking if a number or a string is between two given values. */ const filterFn_between: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValues: [number | string, number | string], ): boolean => ((['', undefined] as Array).includes(filterValues[0]) || filterFn_greaterThan(row as any, columnId, filterValues[0])) && ((!isNaN(+filterValues[0]) && !isNaN(+filterValues[1]) && +filterValues[0] > +filterValues[1]) || (['', undefined] as Array).includes(filterValues[1]) || filterFn_lessThan(row as any, columnId, filterValues[1])) filterFn_between.autoRemove = (val: any) => !val /** * Filter function for checking if a number or a string is between two given values or equal to them. */ const filterFn_betweenInclusive: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValues: [number | string, number | string], ): boolean => ((['', undefined] as Array).includes(filterValues[0]) || filterFn_greaterThanOrEqualTo(row as any, columnId, filterValues[0])) && ((!isNaN(+filterValues[0]) && !isNaN(+filterValues[1]) && +filterValues[0] > +filterValues[1]) || (['', undefined] as Array).includes(filterValues[1]) || filterFn_lessThanOrEqualTo(row as any, columnId, filterValues[1])) filterFn_betweenInclusive.autoRemove = (val: any) => !val /** * Filter function for checking if a number is within a given range. */ export const filterFn_inNumberRange: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: [number, number], ) => { const [min, max] = filterValue const rowValue: number = row.getValue(columnId) return rowValue >= min && rowValue <= max } filterFn_inNumberRange.resolveFilterValue = (val: [any, any]) => { const [unsafeMin, unsafeMax] = val const parsedMin = typeof unsafeMin !== 'number' ? parseFloat(unsafeMin) : unsafeMin const parsedMax = typeof unsafeMax !== 'number' ? parseFloat(unsafeMax) : unsafeMax let min = unsafeMin === null || Number.isNaN(parsedMin) ? -Infinity : parsedMin let max = unsafeMax === null || Number.isNaN(parsedMax) ? Infinity : parsedMax if (min > max) { const temp = min min = max max = temp } return [min, max] as const } filterFn_inNumberRange.autoRemove = (val: any) => testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])) // Array filters /** * Filter function for checking if an array has a given value. */ export const filterFn_arrHas: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Array, ) => { return filterValue.some((val) => row.getValue(columnId) === val) } /** * Filter function for checking if an array includes a given value. */ export const filterFn_arrIncludes: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Array, ) => { return filterValue.some((val) => (row.getValue(columnId) as Array | string).includes( val as any, ), ) } filterFn_arrIncludes.autoRemove = (val: any) => testFalsy(val) || !val?.length /** * Filter function for checking if an array includes all of the given values. */ export const filterFn_arrIncludesAll: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Array, ) => { const value = row.getValue>(columnId) if (!Array.isArray(value)) return false return !filterValue.some((val) => !value.includes(val)) } filterFn_arrIncludesAll.autoRemove = (val: any) => testFalsy(val) || !val?.length /** * Filter function for checking if an array includes any of the given values. */ export const filterFn_arrIncludesSome: FilterFn = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row, columnId: string, filterValue: Array, ) => { const value = row.getValue>(columnId) if (!Array.isArray(value)) return false return filterValue.some((val) => value.includes(val)) } filterFn_arrIncludesSome.autoRemove = (val: any) => testFalsy(val) || !val?.length // Export export const filterFns = { arrIncludes: filterFn_arrIncludes, arrIncludesAll: filterFn_arrIncludesAll, arrHas: filterFn_arrHas, arrIncludesSome: filterFn_arrIncludesSome, between: filterFn_between, betweenInclusive: filterFn_betweenInclusive, equals: filterFn_equals, equalsString: filterFn_equalsString, inNumberRange: filterFn_inNumberRange, includesString: filterFn_includesString, includesStringSensitive: filterFn_includesStringSensitive, weakEquals: filterFn_weakEquals, } export type BuiltInFilterFn = keyof typeof filterFns // Utils function testFalsy(val: any) { return val === undefined || val === null || val === '' } ================================================ FILE: packages/table-core/src/fns/sortFns.ts ================================================ import type { RowData } from '../types/type-utils' import type { TableFeatures } from '../types/TableFeatures' import type { Row } from '../types/Row' import type { SortFn } from '../features/row-sorting/rowSortingFeature.types' export const reSplitAlphaNumeric = /([0-9]+)/gm export const sortFn_alphanumeric: SortFn = < TFeatures extends TableFeatures, TData extends RowData, >( rowA: Row, rowB: Row, columnId: string, ) => { return compareAlphanumeric( toString(rowA.getValue(columnId)).toLowerCase(), toString(rowB.getValue(columnId)).toLowerCase(), ) } export const sortFn_alphanumericCaseSensitive: SortFn = < TFeatures extends TableFeatures, TData extends RowData, >( rowA: Row, rowB: Row, columnId: string, ) => { return compareAlphanumeric( toString(rowA.getValue(columnId)), toString(rowB.getValue(columnId)), ) } // The text filter is more basic (less numeric support) // but is much faster export const sortFn_text: SortFn = < TFeatures extends TableFeatures, TData extends RowData, >( rowA: Row, rowB: Row, columnId: string, ) => { return compareBasic( toString(rowA.getValue(columnId)).toLowerCase(), toString(rowB.getValue(columnId)).toLowerCase(), ) } // The text filter is more basic (less numeric support) // but is much faster export const sortFn_textCaseSensitive: SortFn = < TFeatures extends TableFeatures, TData extends RowData, >( rowA: Row, rowB: Row, columnId: string, ) => { return compareBasic( toString(rowA.getValue(columnId)), toString(rowB.getValue(columnId)), ) } export const sortFn_datetime: SortFn = < TFeatures extends TableFeatures, TData extends RowData, >( rowA: Row, rowB: Row, columnId: string, ) => { const a: number | string = rowA.getValue(columnId) const b: number | string = rowB.getValue(columnId) // Can handle nullish values // Use > and < because == (and ===) doesn't work with // Date objects (would require calling getTime()). return a > b ? 1 : a < b ? -1 : 0 } export const sortFn_basic: SortFn = < TFeatures extends TableFeatures, TData extends RowData, >( rowA: Row, rowB: Row, columnId: string, ) => { return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId)) } // Utils function compareBasic(a: any, b: any) { return a === b ? 0 : a > b ? 1 : -1 } function toString(a: any) { if (typeof a === 'number') { if (isNaN(a) || a === Infinity || a === -Infinity) { return '' } return String(a) } if (typeof a === 'string') { return a } return '' } // Mixed sorting is slow, but very inclusive of many edge cases. // It handles numbers, mixed alphanumeric combinations, and even // null, undefined, and Infinity function compareAlphanumeric(aStr: string, bStr: string) { // Split on number groups, but keep the delimiter // Then remove falsey split values const a = aStr.split(reSplitAlphaNumeric).filter(Boolean) const b = bStr.split(reSplitAlphaNumeric).filter(Boolean) // While while (a.length && b.length) { const aa = a.shift()! const bb = b.shift()! const an = parseInt(aa, 10) const bn = parseInt(bb, 10) const combo = [an, bn].sort() // Both are string if (isNaN(combo[0]!)) { if (aa > bb) { return 1 } if (bb > aa) { return -1 } continue } // One is a string, one is a number if (isNaN(combo[1]!)) { return isNaN(an) ? -1 : 1 } // Both are numbers if (an > bn) { return 1 } if (bn > an) { return -1 } } return a.length - b.length } // Exports export const sortFns = { alphanumeric: sortFn_alphanumeric, alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive, basic: sortFn_basic, datetime: sortFn_datetime, text: sortFn_text, textCaseSensitive: sortFn_textCaseSensitive, } export type BuiltInSortFn = keyof typeof sortFns ================================================ FILE: packages/table-core/src/helpers/columnHelper.ts ================================================ import type { DeepKeys, DeepValue, RowData } from '../types/type-utils' import type { TableFeatures } from '../types/TableFeatures' import type { AccessorFn, AccessorFnColumnDef, AccessorKeyColumnDef, ColumnDef, DisplayColumnDef, GroupColumnDef, IdentifiedColumnDef, } from '../types/ColumnDef' export type ColumnHelper< TFeatures extends TableFeatures, TData extends RowData, > = { /** * Creates a data column definition with an accessor key or function to extract the cell value. * @example * ```ts * helper.accessor('firstName', { cell: (info) => info.getValue() }) * helper.accessor((row) => row.lastName, { id: 'lastName' }) * ``` */ accessor: < TAccessor extends AccessorFn | DeepKeys, TValue extends TAccessor extends AccessorFn ? TReturn : TAccessor extends DeepKeys ? DeepValue : never, >( accessor: TAccessor, column: TAccessor extends AccessorFn ? DisplayColumnDef : IdentifiedColumnDef, ) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef /** * Wraps an array of column definitions to preserve each column's individual TValue type. * Uses variadic tuple types to infer element types before checking constraints, preventing type widening. * @example * ```ts * helper.columns([helper.accessor('firstName', {}), helper.accessor('age', {})]) * ``` */ columns: >>( columns: [...TColumns], ) => Array> & [...TColumns] /** * Creates a display column definition for non-data columns like actions or row selection. * @example * ```ts * helper.display({ id: 'actions', header: 'Actions', cell: () => }) * ``` */ display: ( column: DisplayColumnDef, ) => DisplayColumnDef /** * Creates a group column definition that contains nested child columns. * @example * ```ts * helper.group({ * id: 'name', * header: 'Name', * columns: helper.columns([ * helper.accessor('firstName', {}), * helper.accessor('lastName', { id: 'lastName' }), * ]), * }) * ``` */ group: ( column: GroupColumnDef, ) => GroupColumnDef } /** * A helper utility for creating column definitions with slightly better type inference for each individual column. * The `TValue` generic is inferred based on the accessor key or function provided. * **Note:** From a JavaScript perspective, the functions in these helpers do not do anything. They are only used to help TypeScript infer the correct types for the column definitions. * @example * ```tsx * const helper = createColumnHelper() // _features is the result of `tableFeatures({})` helper * const columns = [ * helper.display({ id: 'actions', header: 'Actions' }), * helper.accessor('firstName', {}), * helper.accessor((row) => row.lastName, {} * ] * ``` */ export function createColumnHelper< TFeatures extends TableFeatures, TData extends RowData, >(): ColumnHelper { return { accessor: (accessor, column) => { return typeof accessor === 'function' ? ({ ...column, accessorFn: accessor, } as any) : { ...column, accessorKey: accessor, } }, columns: >>( columns: [...TColumns], ): Array> & [...TColumns] => columns as Array> & [...TColumns], display: (column) => column, group: (column) => column, } } ================================================ FILE: packages/table-core/src/helpers/tableFeatures.ts ================================================ import type { TableFeatures } from '../types/TableFeatures' /** * A helper function to help define the features that are to be imported and applied to a table instance. * Use this utility to make it easier to have the correct type inference for the features that are being imported. * **Note:** It is recommended to use this utility statically outside of a component. * @example * ``` * import { tableFeatures, columnVisibilityFeature, rowPinningFeature } from '@tanstack/react-table' * const _features = tableFeatures({ columnVisibilityFeature, rowPinningFeature }); * const table = useTable({ _features, rowModels: {}, columns, data }); * ``` */ export function tableFeatures( features: TFeatures, ): TFeatures { return features } // test // const features = tableFeatures({ // rowPinningFeature: {}, // }); ================================================ FILE: packages/table-core/src/helpers/tableHelper.ts ================================================ import { createColumnHelper } from './columnHelper' import type { ColumnHelper } from './columnHelper' import type { RowData } from '../types/type-utils' import type { TableFeatures } from '../types/TableFeatures' import type { Table } from '../types/Table' import type { TableOptions } from '../types/TableOptions' /** * Options for creating a table helper to share common options across multiple tables * coreColumnsFeature, data, and state are excluded from this type and reserved for only the `useTable`/`createTable` functions */ export type TableHelperOptions = Omit< TableOptions, 'columns' | 'data' | 'store' | 'state' | 'initialState' > & { _features: TFeatures } /** * Internal type that each adapter package will build off of to create a table helper */ export type TableHelper_Core = { createColumnHelper: () => ColumnHelper< TFeatures, TData > features: TFeatures options: Omit< TableOptions, 'columns' | 'data' | 'store' | 'state' | 'initialState' > tableCreator: ( tableOptions: Omit< TableOptions, '_features' | '_rowModels' >, selector?: any, ) => Table } /** * Internal function to create a table helper that each adapter package will use to create their own table helper */ export function constructTableHelper( tableCreator: ( tableOptions: Omit< TableOptions, '_features' | '_rowModels' >, selector?: any, ) => Table, tableHelperOptions: TableHelperOptions, ): TableHelper_Core { return { createColumnHelper, features: tableHelperOptions._features, options: tableHelperOptions, tableCreator: (tableOptions, selector) => tableCreator({ ...tableHelperOptions, ...tableOptions }, selector), } } ================================================ FILE: packages/table-core/src/helpers/tableOptions.ts ================================================ import type { RowData } from '../types/type-utils' import type { TableFeatures } from '../types/TableFeatures' import type { TableOptions } from '../types/TableOptions' export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit, 'columns'> & { _features: TFeatures }, ): Omit, 'columns' | '_features'> & { _features: TFeatures } export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit, 'data'> & { _features: TFeatures }, ): Omit, 'data' | '_features'> & { _features: TFeatures } export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit, '_features'>, ): Omit, '_features'> export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit, 'data' | 'columns'> & { _features: TFeatures }, ): Omit, 'data' | 'columns' | '_features'> & { _features: TFeatures } export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit, 'data' | '_features'>, ): Omit, 'data' | '_features'> export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit, 'columns' | '_features'>, ): Omit, 'columns' | '_features'> export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >( options: Omit< TableOptions, 'data' | 'columns' | '_features' >, ): Omit, 'data' | 'columns' | '_features'> export function tableOptions< TFeatures extends TableFeatures, TData extends RowData = any, >(options: TableOptions): TableOptions export function tableOptions(options: unknown) { return options } // test // const options = tableOptions({ // _features: {}, // }) ================================================ FILE: packages/table-core/src/index.ts ================================================ /** * Types */ export * from './types/Cell' export * from './types/Column' export * from './types/ColumnDef' export * from './types/Header' export * from './types/HeaderGroup' export * from './types/Row' export * from './types/RowModel' export * from './types/RowModelFns' export * from './types/Table' export * from './types/TableFeatures' export * from './types/TableOptions' export * from './types/TableState' export * from './types/type-utils' /** * Core */ export * from './core/coreFeatures' export * from './helpers/columnHelper' export * from './helpers/tableFeatures' export * from './helpers/tableHelper' export * from './helpers/tableOptions' export * from './utils' // Cells export * from './core/cells/constructCell' export * from './core/cells/coreCellsFeature' export * from './core/cells/coreCellsFeature.types' export * from './core/cells/coreCellsFeature.utils' // Columns export * from './core/columns/constructColumn' export * from './core/columns/coreColumnsFeature' export * from './core/columns/coreColumnsFeature.types' export * from './core/columns/coreColumnsFeature.utils' // Headers export * from './core/headers/buildHeaderGroups' export * from './core/headers/constructHeader' export * from './core/headers/coreHeadersFeature' export * from './core/headers/coreHeadersFeature.types' export * from './core/headers/coreHeadersFeature.utils' // Rows export * from './core/rows/constructRow' export * from './core/rows/coreRowsFeature' export * from './core/rows/coreRowsFeature.types' export * from './core/rows/coreRowsFeature.utils' // Row Models export * from './core/row-models/coreRowModelsFeature' export * from './core/row-models/coreRowModelsFeature.types' export * from './core/row-models/coreRowModelsFeature.utils' export * from './core/row-models/createCoreRowModel' // Tables export * from './core/table/constructTable' export * from './core/table/coreTablesFeature' export * from './core/table/coreTablesFeature.types' export * from './core/table/coreTablesFeature.utils' /** * RowModelFns */ export * from './fns/aggregationFns' export * from './fns/filterFns' export * from './fns/sortFns' /** * Features */ export * from './features/stockFeatures' // tableReactivityFeature export * from './features/table-reactivity/tableReactivityFeature' // columnFacetingFeature export * from './features/column-faceting/columnFacetingFeature' export * from './features/column-faceting/columnFacetingFeature.types' export * from './features/column-faceting/columnFacetingFeature.utils' export * from './features/column-faceting/createFacetedMinMaxValues' export * from './features/column-faceting/createFacetedRowModel' export * from './features/column-faceting/createFacetedUniqueValues' // columnFilteringFeature export * from './features/column-filtering/columnFilteringFeature' export * from './features/column-filtering/columnFilteringFeature.types' export * from './features/column-filtering/columnFilteringFeature.utils' export * from './features/column-filtering/createFilteredRowModel' // columnGroupingFeature export * from './features/column-grouping/columnGroupingFeature' export * from './features/column-grouping/columnGroupingFeature.types' export * from './features/column-grouping/columnGroupingFeature.utils' export * from './features/column-grouping/createGroupedRowModel' // columnOrderingFeature export * from './features/column-ordering/columnOrderingFeature' export * from './features/column-ordering/columnOrderingFeature.types' export * from './features/column-ordering/columnOrderingFeature.utils' // columnPinningFeature export * from './features/column-pinning/columnPinningFeature' export * from './features/column-pinning/columnPinningFeature.types' export * from './features/column-pinning/columnPinningFeature.utils' // columnResizingFeature export * from './features/column-resizing/columnResizingFeature' export * from './features/column-resizing/columnResizingFeature.types' export * from './features/column-resizing/columnResizingFeature.utils' // columnSizingFeature export * from './features/column-sizing/columnSizingFeature' export * from './features/column-sizing/columnSizingFeature.types' export * from './features/column-sizing/columnSizingFeature.utils' // columnVisibilityFeature export * from './features/column-visibility/columnVisibilityFeature' export * from './features/column-visibility/columnVisibilityFeature.types' export * from './features/column-visibility/columnVisibilityFeature.utils' // globalFilteringFeature export * from './features/global-filtering/globalFilteringFeature' export * from './features/global-filtering/globalFilteringFeature.types' export * from './features/global-filtering/globalFilteringFeature.utils' // rowExpandingFeature export * from './features/row-expanding/rowExpandingFeature' export * from './features/row-expanding/rowExpandingFeature.types' export * from './features/row-expanding/rowExpandingFeature.utils' export * from './features/row-expanding/createExpandedRowModel' // rowPaginationFeature export * from './features/row-pagination/rowPaginationFeature' export * from './features/row-pagination/rowPaginationFeature.types' export * from './features/row-pagination/rowPaginationFeature.utils' export * from './features/row-pagination/createPaginatedRowModel' // rowPinningFeature export * from './features/row-pinning/rowPinningFeature' export * from './features/row-pinning/rowPinningFeature.types' export * from './features/row-pinning/rowPinningFeature.utils' // rowSelectionFeature export * from './features/row-selection/rowSelectionFeature' export * from './features/row-selection/rowSelectionFeature.types' export * from './features/row-selection/rowSelectionFeature.utils' // rowSortingFeature export * from './features/row-sorting/rowSortingFeature' export * from './features/row-sorting/rowSortingFeature.types' export * from './features/row-sorting/rowSortingFeature.utils' export * from './features/row-sorting/createSortedRowModel' ================================================ FILE: packages/table-core/src/types/Cell.ts ================================================ import type { Cell_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { CellData, RowData, UnionToIntersection } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { Cell_Cell } from '../core/cells/coreCellsFeature.types' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface Cell_Plugins< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > {} export interface Cell_Core< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > extends Cell_Cell {} export type Cell< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = Cell_Cell & UnionToIntersection< 'columnGroupingFeature' extends keyof TFeatures ? Cell_ColumnGrouping : never > & ExtractFeatureTypes<'Cell', TFeatures> & Cell_Plugins // export type Cell< // TFeatures extends TableFeatures, // TData extends RowData, // TValue extends CellData = CellData, // > = Cell_Core & // ExtractFeatureTypes & // Cell_Plugins ================================================ FILE: packages/table-core/src/types/Column.ts ================================================ import type { Column_RowSorting } from '../features/row-sorting/rowSortingFeature.types' import type { Column_ColumnFaceting } from '../features/column-faceting/columnFacetingFeature.types' import type { Column_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { Column_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { Column_ColumnOrdering } from '../features/column-ordering/columnOrderingFeature.types' import type { Column_GlobalFiltering } from '../features/global-filtering/globalFilteringFeature.types' import type { Column_ColumnPinning } from '../features/column-pinning/columnPinningFeature.types' import type { Column_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types' import type { Column_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { Column_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { ColumnDefBase_All } from './ColumnDef' import type { RowData, UnionToIntersection } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { Column_Column } from '../core/columns/coreColumnsFeature.types' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface Column_Plugins< TFeatures extends TableFeatures, TData extends RowData, TValue = unknown, > {} export interface Column_Core< TFeatures extends TableFeatures, TData extends RowData, TValue = unknown, > extends Column_Column {} export type Column< TFeatures extends TableFeatures, TData extends RowData, TValue = unknown, > = Column_Core & UnionToIntersection< | ('columnFacetingFeature' extends keyof TFeatures ? Column_ColumnFaceting : never) | ('columnFilteringFeature' extends keyof TFeatures ? Column_ColumnFiltering : never) | ('columnGroupingFeature' extends keyof TFeatures ? Column_ColumnGrouping : never) | ('columnOrderingFeature' extends keyof TFeatures ? Column_ColumnOrdering : never) | ('columnPinningFeature' extends keyof TFeatures ? Column_ColumnPinning : never) | ('columnResizingFeature' extends keyof TFeatures ? Column_ColumnResizing : never) | ('columnSizingFeature' extends keyof TFeatures ? Column_ColumnSizing : never) | ('columnVisibilityFeature' extends keyof TFeatures ? Column_ColumnVisibility : never) | ('globalFilteringFeature' extends keyof TFeatures ? Column_GlobalFiltering : never) | ('rowSortingFeature' extends keyof TFeatures ? Column_RowSorting : never) > & ExtractFeatureTypes<'Column', TFeatures> & Column_Plugins // export type Column< // TFeatures extends TableFeatures, // TData extends RowData, // TValue = unknown, // > = Column_Core & // ExtractFeatureTypes<'Column', TFeatures> & // Column_Plugins export type Column_Internal< TFeatures extends TableFeatures, TData extends RowData, TValue = unknown, > = Column & { columnDef: ColumnDefBase_All } ================================================ FILE: packages/table-core/src/types/ColumnDef.ts ================================================ import type { CellData, RowData, UnionToIntersection } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { CellContext } from '../core/cells/coreCellsFeature.types' import type { HeaderContext } from '../core/headers/coreHeadersFeature.types' import type { ColumnDef_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { ColumnDef_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { ColumnDef_ColumnPinning } from '../features/column-pinning/columnPinningFeature.types' import type { ColumnDef_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types' import type { ColumnDef_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { ColumnDef_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { ColumnDef_GlobalFiltering } from '../features/global-filtering/globalFilteringFeature.types' import type { ColumnDef_RowSorting } from '../features/row-sorting/rowSortingFeature.types' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface ColumnDef_Plugins< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > {} export interface ColumnMeta< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > {} export type AccessorFn< TData extends RowData, TValue extends CellData = CellData, > = (originalRow: TData, index: number) => TValue export type ColumnDefTemplate = | string | ((props: TProps) => any) export type StringOrTemplateHeader< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = string | ColumnDefTemplate> export interface StringHeaderIdentifier { header: string id?: string } export interface IdIdentifier< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { id: string header?: StringOrTemplateHeader } type ColumnIdentifiers< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = IdIdentifier | StringHeaderIdentifier interface ColumnDefBase_Core< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > { getUniqueValues?: AccessorFn> footer?: ColumnDefTemplate> cell?: ColumnDefTemplate> meta?: ColumnMeta } export type ColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase_Core & UnionToIntersection< | ('columnVisibilityFeature' extends keyof TFeatures ? ColumnDef_ColumnVisibility : never) | ('columnPinningFeature' extends keyof TFeatures ? ColumnDef_ColumnPinning : never) | ('columnFilteringFeature' extends keyof TFeatures ? ColumnDef_ColumnFiltering : never) | ('globalFilteringFeature' extends keyof TFeatures ? ColumnDef_GlobalFiltering : never) | ('rowSortingFeature' extends keyof TFeatures ? ColumnDef_RowSorting : never) | ('columnGroupingFeature' extends keyof TFeatures ? ColumnDef_ColumnGrouping : never) | ('columnSizingFeature' extends keyof TFeatures ? ColumnDef_ColumnSizing : never) | ('columnResizingFeature' extends keyof TFeatures ? ColumnDef_ColumnResizing : never) > & ExtractFeatureTypes<'ColumnDef', TFeatures> & ColumnDef_Plugins // export type ColumnDefBase< // TFeatures extends TableFeatures, // TData extends RowData, // TValue extends CellData = CellData, // > = ColumnDefBase_Core & // ExtractFeatureTypes<'ColumnDef', TFeatures> & // ColumnDef_Plugins export type ColumnDefBase_All< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase_Core & Partial< ColumnDef_ColumnVisibility & ColumnDef_ColumnPinning & ColumnDef_ColumnFiltering & ColumnDef_GlobalFiltering & ColumnDef_RowSorting & ColumnDef_ColumnGrouping & ColumnDef_ColumnSizing & ColumnDef_ColumnResizing > export type IdentifiedColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase & { id?: string header?: StringOrTemplateHeader } export type DisplayColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase & ColumnIdentifiers type GroupColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase & { columns?: ReadonlyArray> } export type GroupColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = GroupColumnDefBase & ColumnIdentifiers export type AccessorFnColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase & { accessorFn: AccessorFn } export type AccessorFnColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = AccessorFnColumnDefBase & ColumnIdentifiers export type AccessorKeyColumnDefBase< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = ColumnDefBase & { id?: string accessorKey: (string & {}) | keyof TData } export type AccessorKeyColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = AccessorKeyColumnDefBase & Partial> export type AccessorColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = | AccessorKeyColumnDef | AccessorFnColumnDef export type ColumnDef< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = | DisplayColumnDef | GroupColumnDef | AccessorColumnDef export type ColumnDefResolved< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = Partial>> & { accessorKey?: string } ================================================ FILE: packages/table-core/src/types/Header.ts ================================================ import type { Header_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { CellData, RowData, UnionToIntersection } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { Header_Header } from '../core/headers/coreHeadersFeature.types' import type { Header_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface Header_Plugins< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > {} export interface Header_Core< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > extends Header_Header {} export type Header< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, > = Header_Core & UnionToIntersection< | ('columnSizingFeature' extends keyof TFeatures ? Header_ColumnSizing : never) | ('columnResizingFeature' extends keyof TFeatures ? Header_ColumnResizing : never) > & ExtractFeatureTypes<'Header', TFeatures> & Header_Plugins // export type Header< // TFeatures extends TableFeatures, // TData extends RowData, // TValue extends CellData = CellData, // > = Header_Core & // ExtractFeatureTypes<'Header', TFeatures> & // Header_Plugins ================================================ FILE: packages/table-core/src/types/HeaderGroup.ts ================================================ import type { HeaderGroup_Header } from '../core/headers/coreHeadersFeature.types' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { RowData } from './type-utils' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface HeaderGroup_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} export interface HeaderGroup_Core< TFeatures extends TableFeatures, TData extends RowData, > extends HeaderGroup_Header {} export type HeaderGroup< TFeatures extends TableFeatures, TData extends RowData, > = HeaderGroup_Core & ExtractFeatureTypes<'HeaderGroup', TFeatures> & HeaderGroup_Plugins ================================================ FILE: packages/table-core/src/types/Row.ts ================================================ import type { Row_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { Row_ColumnPinning } from '../features/column-pinning/columnPinningFeature.types' import type { Row_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { Row_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { RowData, UnionToIntersection } from './type-utils' import type { Row_RowExpanding } from '../features/row-expanding/rowExpandingFeature.types' import type { Row_RowPinning } from '../features/row-pinning/rowPinningFeature.types' import type { Row_RowSelection } from '../features/row-selection/rowSelectionFeature.types' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { Row_Row } from '../core/rows/coreRowsFeature.types' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface Row_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} export interface Row_Core< TFeatures extends TableFeatures, TData extends RowData, > extends Row_Row {} export type Row< TFeatures extends TableFeatures, TData extends RowData, > = Row_Core & UnionToIntersection< | ('columnFilteringFeature' extends keyof TFeatures ? Row_ColumnFiltering : never) | ('columnGroupingFeature' extends keyof TFeatures ? Row_ColumnGrouping : never) | ('columnPinningFeature' extends keyof TFeatures ? Row_ColumnPinning : never) | ('columnVisibilityFeature' extends keyof TFeatures ? Row_ColumnVisibility : never) | ('rowExpandingFeature' extends keyof TFeatures ? Row_RowExpanding : never) | ('rowPinningFeature' extends keyof TFeatures ? Row_RowPinning : never) | ('rowSelectionFeature' extends keyof TFeatures ? Row_RowSelection : never) > & ExtractFeatureTypes<'Row', TFeatures> & Row_Plugins // export type Row< // TFeatures extends TableFeatures, // TData extends RowData, // > = Row_Core & // ExtractFeatureTypes<'Row', TFeatures> & // Row_Plugins ================================================ FILE: packages/table-core/src/types/RowModel.ts ================================================ import type { CachedRowModel_Faceted, CreateRowModel_Faceted, } from '../features/column-faceting/columnFacetingFeature.types' import type { CachedRowModel_Grouped, CreateRowModel_Grouped, } from '../features/column-grouping/columnGroupingFeature.types' import type { CachedRowModel_Filtered, CreateRowModel_Filtered, } from '../features/column-filtering/columnFilteringFeature.types' import type { CachedRowModel_Core, CreateRowModel_Core, RowModel, } from '../core/row-models/coreRowModelsFeature.types' import type { CachedRowModel_Expanded, CreateRowModel_Expanded, } from '../features/row-expanding/rowExpandingFeature.types' import type { CachedRowModel_Paginated, CreateRowModel_Paginated, } from '../features/row-pagination/rowPaginationFeature.types' import type { CachedRowModel_Sorted, CreateRowModel_Sorted, } from '../features/row-sorting/rowSortingFeature.types' import type { RowData, UnionToIntersection } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface CreateRowModels_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} export type CreateRowModels< TFeatures extends TableFeatures, TData extends RowData, > = CreateRowModel_Core & UnionToIntersection< | ('columnFacetingFeature' extends keyof TFeatures ? CreateRowModel_Faceted : never) | ('columnFilteringFeature' extends keyof TFeatures ? CreateRowModel_Filtered : never) | ('rowExpandingFeature' extends keyof TFeatures ? CreateRowModel_Expanded : never) | ('columnGroupingFeature' extends keyof TFeatures ? CreateRowModel_Grouped : never) | ('rowPaginationFeature' extends keyof TFeatures ? CreateRowModel_Paginated : never) | ('rowSortingFeature' extends keyof TFeatures ? CreateRowModel_Sorted : never) > & ExtractFeatureTypes<'CreateRowModels', TFeatures> & CreateRowModels_Plugins // export type CreateRowModels< // TFeatures extends TableFeatures, // TData extends RowData, // > = CreateRowModel_Core & // ExtractFeatureTypes<'CreateRowModels', TFeatures> & // CreateRowModels_Plugins export type CreateRowModels_All< TFeatures extends TableFeatures, TData extends RowData, > = CreateRowModel_Core & CreateRowModel_Expanded & CreateRowModel_Faceted & CreateRowModel_Filtered & CreateRowModel_Grouped & CreateRowModel_Paginated & CreateRowModel_Sorted export interface CachedRowModels_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} export type CachedRowModels< TFeatures extends TableFeatures, TData extends RowData, > = { CachedRowModel_Core: () => RowModel } & UnionToIntersection< | ('columnFacetingFeature' extends keyof TFeatures ? CachedRowModel_Faceted : never) | ('columnFilteringFeature' extends keyof TFeatures ? CachedRowModel_Filtered : never) | ('rowExpandingFeature' extends keyof TFeatures ? CachedRowModel_Expanded : never) | ('columnGroupingFeature' extends keyof TFeatures ? CachedRowModel_Grouped : never) | ('rowPaginationFeature' extends keyof TFeatures ? CachedRowModel_Paginated : never) | ('rowSortingFeature' extends keyof TFeatures ? CachedRowModel_Sorted : never) > & ExtractFeatureTypes<'CachedRowModel', TFeatures> & CachedRowModels_Plugins // export type CachedRowModels< // TFeatures extends TableFeatures, // TData extends RowData, // > = ExtractFeatureTypes<'CachedRowModel', TFeatures> & // CachedRowModels_Plugins export type CachedRowModel_All< TFeatures extends TableFeatures, TData extends RowData = any, > = Partial< CachedRowModel_Core & CachedRowModel_Expanded & CachedRowModel_Faceted & CachedRowModel_Filtered & CachedRowModel_Grouped & CachedRowModel_Paginated & CachedRowModel_Sorted > ================================================ FILE: packages/table-core/src/types/RowModelFns.ts ================================================ import type { RowModelFns_RowSorting } from '../features/row-sorting/rowSortingFeature.types' import type { RowModelFns_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { RowData, UnionToIntersection } from './type-utils' import type { RowModelFns_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface RowModelFns_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} export interface RowModelFns_Core {} export type RowModelFns< TFeatures extends TableFeatures, TData extends RowData, > = Partial< UnionToIntersection< | ('columnFilteringFeature' extends keyof TFeatures ? RowModelFns_ColumnFiltering : never) | ('columnGroupingFeature' extends keyof TFeatures ? RowModelFns_ColumnGrouping : never) | ('rowSortingFeature' extends keyof TFeatures ? RowModelFns_RowSorting : never) > & ExtractFeatureTypes<'RowModelFns', TFeatures> & RowModelFns_Plugins > // export type RowModelFns< // TFeatures extends TableFeatures, // TData extends RowData, // > = RowModelFns_Core & // ExtractFeatureTypes<'RowModelFns', TFeatures> & // RowModelFns_Plugins export type RowModelFns_All< TFeatures extends TableFeatures, TData extends RowData, > = Partial< RowModelFns_ColumnFiltering & RowModelFns_ColumnGrouping & RowModelFns_RowSorting > ================================================ FILE: packages/table-core/src/types/Table.ts ================================================ import type { ReadonlyStore, Store } from '@tanstack/store' import type { Table_ColumnFaceting } from '../features/column-faceting/columnFacetingFeature.types' import type { Table_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types' import type { Table_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { Table_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { Table_ColumnPinning } from '../features/column-pinning/columnPinningFeature.types' import type { Table_ColumnOrdering } from '../features/column-ordering/columnOrderingFeature.types' import type { Table_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { Table_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { Table_RowPinning } from '../features/row-pinning/rowPinningFeature.types' import type { Table_GlobalFiltering } from '../features/global-filtering/globalFilteringFeature.types' import type { Table_RowExpanding } from '../features/row-expanding/rowExpandingFeature.types' import type { Table_RowPagination } from '../features/row-pagination/rowPaginationFeature.types' import type { Table_RowSelection } from '../features/row-selection/rowSelectionFeature.types' import type { Table_RowSorting } from '../features/row-sorting/rowSortingFeature.types' import type { Table_RowModels } from '../core/row-models/coreRowModelsFeature.types' import type { CachedRowModel_All, CreateRowModels_All } from './RowModel' import type { RowModelFns_All } from './RowModelFns' import type { TableState_All } from './TableState' import type { RowData, UnionToIntersection } from './type-utils' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' import type { Table_Columns } from '../core/columns/coreColumnsFeature.types' import type { Table_Headers } from '../core/headers/coreHeadersFeature.types' import type { Table_Rows } from '../core/rows/coreRowsFeature.types' import type { Table_Table } from '../core/table/coreTablesFeature.types' import type { TableOptions_All } from './TableOptions' /** * Use this interface as a target for declaration merging to add your own plugin properties. * Note: This will affect the types of all tables in your project. */ export interface Table_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} /** * The core table object that only includes the core table functionality such as column, header, row, and table APIS. * No features are included. */ export type Table_Core< TFeatures extends TableFeatures, TData extends RowData, > = Table_Table & Table_Columns & Table_Rows & Table_RowModels & Table_Headers /** * The table object that includes both the core table functionality and the features that are enabled via the `_features` table option. */ export type Table< TFeatures extends TableFeatures, TData extends RowData, > = Table_Core & UnionToIntersection< | ('columnFilteringFeature' extends keyof TFeatures ? Table_ColumnFiltering : never) | ('columnGroupingFeature' extends keyof TFeatures ? Table_ColumnGrouping : never) | ('columnOrderingFeature' extends keyof TFeatures ? Table_ColumnOrdering : never) | ('columnPinningFeature' extends keyof TFeatures ? Table_ColumnPinning : never) | ('columnResizingFeature' extends keyof TFeatures ? Table_ColumnResizing : never) | ('columnSizingFeature' extends keyof TFeatures ? Table_ColumnSizing : never) | ('columnVisibilityFeature' extends keyof TFeatures ? Table_ColumnVisibility : never) | ('columnFacetingFeature' extends keyof TFeatures ? Table_ColumnFaceting : never) | ('globalFilteringFeature' extends keyof TFeatures ? Table_GlobalFiltering : never) | ('rowExpandingFeature' extends keyof TFeatures ? Table_RowExpanding : never) | ('rowPaginationFeature' extends keyof TFeatures ? Table_RowPagination : never) | ('rowPinningFeature' extends keyof TFeatures ? Table_RowPinning : never) | ('rowSelectionFeature' extends keyof TFeatures ? Table_RowSelection : never) | ('rowSortingFeature' extends keyof TFeatures ? Table_RowSorting : never) > & ExtractFeatureTypes<'Table', TFeatures> & Table_Plugins // export type Table< // TFeatures extends TableFeatures, // TData extends RowData, // > = Table_Core & // ExtractFeatureTypes<'Table', TFeatures> & // Table_Plugins export type Table_Internal< TFeatures extends TableFeatures, TData extends RowData = any, > = Table & { _rowModels: CachedRowModel_All _rowModelFns: RowModelFns_All options: TableOptions_All & { _rowModels?: CreateRowModels_All state?: TableState_All initialState?: TableState_All } initialState: TableState_All baseStore: Store store: ReadonlyStore } ================================================ FILE: packages/table-core/src/types/TableFeatures.ts ================================================ import type { CoreFeatures } from '../core/coreFeatures' import type { CellData, RowData, UnionToIntersection } from './type-utils' import type { ColumnDefBase_All } from './ColumnDef' import type { Row } from './Row' import type { Table_Internal } from './Table' import type { TableOptions_All } from './TableOptions' import type { TableState_All } from './TableState' import type { StockFeatures } from '../features/stockFeatures' export type ExtractFeatureTypes< TKey extends keyof FeatureConstructors, TFeatures extends TableFeatures, > = UnionToIntersection< { [K in keyof TFeatures]: TFeatures[K] extends TableFeature< infer FeatureConstructorOptions > ? TKey extends keyof FeatureConstructorOptions ? FeatureConstructorOptions[TKey] : never : any }[keyof TFeatures] > interface FeatureConstructors { CachedRowModel?: any Cell?: any Column?: any ColumnDef?: any CreateRowModels?: any Header?: any HeaderGroup?: any Row?: any RowModelFns?: any Table?: any TableOptions?: any TableState?: any } export interface Plugins {} export interface TableFeatures extends Partial, Partial, Partial {} export type ConstructTableAPIs = < TFeatures extends TableFeatures, TData extends RowData, >( table: Table_Internal & Partial & { options: Partial }, ) => void export type GetDefaultColumnDef = < TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >() => ColumnDefBase_All & Partial export type GetDefaultTableOptions = ( table: Table_Internal & Partial, ) => Partial> & Partial export type GetInitialState = ( initialState: Partial & Partial, ) => TableState_All & Partial export type GetDefaultStateSelector = ( state: TableState_All, ) => Partial & Partial export type AssignCellPrototype = < TFeatures extends TableFeatures, TData extends RowData, >( prototype: Record, table: Table_Internal, ) => void export type AssignColumnPrototype = < TFeatures extends TableFeatures, TData extends RowData, >( prototype: Record, table: Table_Internal, ) => void export type AssignHeaderPrototype = < TFeatures extends TableFeatures, TData extends RowData, >( prototype: Record, table: Table_Internal, ) => void export type AssignRowPrototype = < TFeatures extends TableFeatures, TData extends RowData, >( prototype: Record, table: Table_Internal, ) => void export type InitRowInstanceData = < TFeatures extends TableFeatures, TData extends RowData, >( row: Row & Partial, ) => void export interface TableFeature { /** * Assigns Cell APIs to the cell prototype for memory-efficient method sharing. * This is called once per table to build a shared prototype for all cells. */ assignCellPrototype?: AssignCellPrototype /** * Assigns Column APIs to the column prototype for memory-efficient method sharing. * This is called once per table to build a shared prototype for all columns. */ assignColumnPrototype?: AssignColumnPrototype /** * Assigns Header APIs to the header prototype for memory-efficient method sharing. * This is called once per table to build a shared prototype for all headers. */ assignHeaderPrototype?: AssignHeaderPrototype /** * Assigns Row APIs to the row prototype for memory-efficient method sharing. * This is called once per table to build a shared prototype for all rows. */ assignRowPrototype?: AssignRowPrototype /** * Assigns Table APIs to the table instance. * Unlike row/cell/column/header, the table is a singleton so methods are assigned directly. */ constructTableAPIs?: ConstructTableAPIs getDefaultColumnDef?: GetDefaultColumnDef getDefaultTableOptions?: GetDefaultTableOptions getInitialState?: GetInitialState /** * Initializes instance-specific data on each row (e.g., caches). * Methods should be assigned via assignRowPrototype instead. */ initRowInstanceData?: InitRowInstanceData } ================================================ FILE: packages/table-core/src/types/TableOptions.ts ================================================ import type { CoreFeatures } from '../core/coreFeatures' import type { TableOptions_Cell } from '../core/cells/coreCellsFeature.types' import type { TableOptions_Columns } from '../core/columns/coreColumnsFeature.types' import type { TableOptions_Rows } from '../core/rows/coreRowsFeature.types' import type { TableOptions_Table } from '../core/table/coreTablesFeature.types' import type { TableOptions_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { TableOptions_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { TableOptions_ColumnOrdering } from '../features/column-ordering/columnOrderingFeature.types' import type { TableOptions_ColumnPinning } from '../features/column-pinning/columnPinningFeature.types' import type { TableOptions_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types' import type { TableOptions_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { TableOptions_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { TableOptions_GlobalFiltering } from '../features/global-filtering/globalFilteringFeature.types' import type { TableOptions_RowExpanding } from '../features/row-expanding/rowExpandingFeature.types' import type { TableOptions_RowPagination } from '../features/row-pagination/rowPaginationFeature.types' 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 { ExtractFeatureTypes, TableFeatures } from './TableFeatures' export interface TableOptions_Plugins< TFeatures extends TableFeatures, TData extends RowData, > {} export interface TableOptions_Core< TFeatures extends TableFeatures, TData extends RowData, > extends TableOptions_Table, TableOptions_Cell, TableOptions_Columns, TableOptions_Rows {} type DebugKeysFor = { [K in keyof TFeatures & string as `debug${Capitalize}`]?: boolean } export type DebugOptions = { debugAll?: boolean debugCache?: boolean debugCells?: boolean debugColumns?: boolean debugHeaders?: boolean debugRows?: boolean debugTable?: boolean } & DebugKeysFor export type TableOptions< TFeatures extends TableFeatures, TData extends RowData, > = TableOptions_Core & UnionToIntersection< | ('columnFilteringFeature' extends keyof TFeatures ? TableOptions_ColumnFiltering : never) | ('columnGroupingFeature' extends keyof TFeatures ? TableOptions_ColumnGrouping : never) | ('columnOrderingFeature' extends keyof TFeatures ? TableOptions_ColumnOrdering : never) | ('columnPinningFeature' extends keyof TFeatures ? TableOptions_ColumnPinning : never) | ('columnResizingFeature' extends keyof TFeatures ? TableOptions_ColumnResizing : never) | ('columnSizingFeature' extends keyof TFeatures ? TableOptions_ColumnSizing : never) | ('columnVisibilityFeature' extends keyof TFeatures ? TableOptions_ColumnVisibility : never) | ('globalFilteringFeature' extends keyof TFeatures ? TableOptions_GlobalFiltering : never) | ('rowExpandingFeature' extends keyof TFeatures ? TableOptions_RowExpanding : never) | ('rowPaginationFeature' extends keyof TFeatures ? TableOptions_RowPagination : never) | ('rowPinningFeature' extends keyof TFeatures ? TableOptions_RowPinning : never) | ('rowSelectionFeature' extends keyof TFeatures ? TableOptions_RowSelection : never) | ('rowSortingFeature' extends keyof TFeatures ? TableOptions_RowSorting : never) > & ExtractFeatureTypes<'TableOptions', TFeatures> & TableOptions_Plugins & DebugOptions // export type TableOptions< // TFeatures extends TableFeatures, // TData extends RowData, // > = TableOptions_Core & // ExtractFeatureTypes<'TableOptions', TFeatures> & // TableOptions_Plugins export type TableOptions_All< TFeatures extends TableFeatures, TData extends RowData, > = TableOptions_Core & Partial< TableOptions_ColumnFiltering & TableOptions_ColumnGrouping & TableOptions_ColumnOrdering & TableOptions_ColumnPinning & TableOptions_ColumnResizing & TableOptions_ColumnSizing & TableOptions_ColumnVisibility & TableOptions_GlobalFiltering & TableOptions_RowExpanding & TableOptions_RowPagination & TableOptions_RowPinning & TableOptions_RowSelection & TableOptions_RowSorting > ================================================ FILE: packages/table-core/src/types/TableState.ts ================================================ import type { UnionToIntersection } from './type-utils' import type { TableState_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' import type { TableState_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { TableState_ColumnOrdering } from '../features/column-ordering/columnOrderingFeature.types' import type { TableState_ColumnPinning } from '../features/column-pinning/columnPinningFeature.types' import type { TableState_ColumnResizing } from '../features/column-resizing/columnResizingFeature.types' import type { TableState_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { TableState_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { TableState_GlobalFiltering } from '../features/global-filtering/globalFilteringFeature.types' import type { TableState_RowExpanding } from '../features/row-expanding/rowExpandingFeature.types' import type { TableState_RowPagination } from '../features/row-pagination/rowPaginationFeature.types' import type { TableState_RowPinning } from '../features/row-pinning/rowPinningFeature.types' import type { TableState_RowSelection } from '../features/row-selection/rowSelectionFeature.types' import type { TableState_RowSorting } from '../features/row-sorting/rowSortingFeature.types' import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' /** * Use this interface as a target for declaration merging to add your own state properties. * Note: This will affect the types of all tables in your project. */ export interface TableState_Plugins {} export type TableState = UnionToIntersection< | ('columnFilteringFeature' extends keyof TFeatures ? TableState_ColumnFiltering : never) | ('columnGroupingFeature' extends keyof TFeatures ? TableState_ColumnGrouping : never) | ('columnOrderingFeature' extends keyof TFeatures ? TableState_ColumnOrdering : never) | ('columnPinningFeature' extends keyof TFeatures ? TableState_ColumnPinning : never) | ('columnResizingFeature' extends keyof TFeatures ? TableState_ColumnResizing : never) | ('columnSizingFeature' extends keyof TFeatures ? TableState_ColumnSizing : never) | ('columnVisibilityFeature' extends keyof TFeatures ? TableState_ColumnVisibility : never) | ('globalFilteringFeature' extends keyof TFeatures ? TableState_GlobalFiltering : never) | ('rowExpandingFeature' extends keyof TFeatures ? TableState_RowExpanding : never) | ('rowPaginationFeature' extends keyof TFeatures ? TableState_RowPagination : never) | ('rowPinningFeature' extends keyof TFeatures ? TableState_RowPinning : never) | ('rowSelectionFeature' extends keyof TFeatures ? TableState_RowSelection : never) | ('rowSortingFeature' extends keyof TFeatures ? TableState_RowSorting : never) > & ExtractFeatureTypes<'TableState', TFeatures> & TableState_Plugins // export type TableState = ExtractFeatureTypes< // export type TableState = ExtractFeatureTypes< // 'TableState', // TFeatures // > & // TableState_Plugins export type TableState_All = Partial< TableState_ColumnFiltering & TableState_ColumnGrouping & TableState_ColumnOrdering & TableState_ColumnPinning & TableState_ColumnResizing & TableState_ColumnSizing & TableState_ColumnVisibility & TableState_GlobalFiltering & TableState_RowExpanding & TableState_RowPagination & TableState_RowPinning & TableState_RowSelection & TableState_RowSorting > ================================================ FILE: packages/table-core/src/types/type-utils.ts ================================================ export type Updater = T | ((old: T) => T) export type OnChangeFn = (updaterOrValue: Updater) => void export type RowData = Record | Array export type CellData = unknown export type PartialKeys = Omit & Partial> export type RequiredKeys = Omit & Required> export type UnionToIntersection = ( T extends any ? (x: T) => any : never ) extends (x: infer R) => any ? R : never type ComputeRange< N extends number, Result extends Array = [], > = Result['length'] extends N ? Result : ComputeRange type Index40 = ComputeRange<40>[number] // Is this type a tuple? type IsTuple = T extends ReadonlyArray & { length: infer Length } ? Length extends Index40 ? T : never : never // If this type is a tuple, what indices are allowed? type AllowedIndexes< Tuple extends ReadonlyArray, Keys extends number = never, > = Tuple extends readonly [] ? Keys : Tuple extends readonly [infer _, ...infer Tail] ? AllowedIndexes : Keys export type DeepKeys< T, TDepth extends Array = [], > = TDepth['length'] extends 5 ? never : unknown extends T ? string : T extends ReadonlyArray & IsTuple ? AllowedIndexes | DeepKeysPrefix, TDepth> : T extends Array ? DeepKeys : T extends Date ? never : T extends object ? (keyof T & string) | DeepKeysPrefix : never type DeepKeysPrefix< T, TPrefix, TDepth extends Array, > = TPrefix extends keyof T & (number | string) ? `${TPrefix}.${DeepKeys & string}` : never export type DeepValue = T extends Record ? TProp extends `${infer TBranch}.${infer TDeepProp}` ? DeepValue : T[TProp & string] : never export type NoInfer = [T][T extends any ? 0 : never] export type Getter = () => NoInfer export type Prettify = { [K in keyof T]: T[K] } & unknown ================================================ FILE: packages/table-core/src/utils.ts ================================================ import type { Table, Table_Internal } from './types/Table' import type { NoInfer, RowData, Updater } from './types/type-utils' import type { TableFeatures } from './types/TableFeatures' import type { TableState, TableState_All } from './types/TableState' export function functionalUpdate(updater: Updater, input: T): T { return typeof updater === 'function' ? (updater as (i: T) => T)(input) : updater } export function noop() {} export function makeStateUpdater< TFeatures extends TableFeatures, K extends (string & {}) | keyof TableState_All | keyof TableState, >(key: K, instance: Table) { return (updater: Updater[K & keyof TableState]>) => { instance.baseStore.setState( (old: TTableState) => { return { ...old, [key]: functionalUpdate(updater, (old as any)[key]), } }, ) } } type AnyFunction = (...args: any) => any export function isFunction(d: any): d is T { return d instanceof Function } export function isNumberArray(d: any): d is Array { return Array.isArray(d) && d.every((val) => typeof val === 'number') } export function flattenBy( arr: Array, getChildren: (item: TNode) => Array, ) { const flat: Array = [] const recurse = (subArr: Array) => { subArr.forEach((item) => { flat.push(item) const children = getChildren(item) if (children.length) { recurse(children) } }) } recurse(arr) return flat } export const $internalMemoFnMeta = Symbol('memoFnMeta') export type MemoFnMeta = { originalArgsLength?: number } /** * @internal */ function setMemoFnMeta(fn: Function, meta: MemoFnMeta) { Object.defineProperty(fn, $internalMemoFnMeta, { value: meta }) } /** * @internal */ export function getMemoFnMeta(fn: any): MemoFnMeta | null { return (typeof fn === 'function' && fn[$internalMemoFnMeta]) ?? null } interface MemoOptions, TDepArgs, TResult> { fn: (...args: NoInfer) => TResult memoDeps?: (depArgs?: TDepArgs) => [...TDeps] | undefined onAfterCompare?: (depsChanged: boolean) => void onAfterUpdate?: (result: TResult) => void onBeforeCompare?: () => void onBeforeUpdate?: () => void } export const memo = , TDepArgs, TResult>({ fn, memoDeps, onAfterCompare, onAfterUpdate, onBeforeCompare, onBeforeUpdate, }: MemoOptions): (( depArgs?: TDepArgs, ) => TResult) => { let deps: Array | undefined = [] let result: TResult | undefined const memoizedFn = (depArgs?: TDepArgs): TResult => { onBeforeCompare?.() const newDeps = memoDeps?.(depArgs) const depsChanged = !newDeps || newDeps.length !== deps?.length || newDeps.some((dep: any, index: number) => deps?.[index] !== dep) onAfterCompare?.(depsChanged) if (!depsChanged) { return result! } deps = newDeps onBeforeUpdate?.() result = fn(...(newDeps ?? ([] as any))) onAfterUpdate?.(result) return result } setMemoFnMeta(memoizedFn, { originalArgsLength: fn.length }) return memoizedFn } interface TableMemoOptions< TFeatures extends TableFeatures, TDeps extends ReadonlyArray, TDepArgs, TResult, > extends MemoOptions { feature?: keyof TFeatures & string fnName: string objectId?: string onAfterUpdate?: () => void table: Table_Internal } const pad = (str: number | string, num: number) => { str = String(str) while (str.length < num) { str = ' ' + str } return str } export function tableMemo< TFeatures extends TableFeatures, TDeps extends ReadonlyArray, TDepArgs, TResult, >({ feature, fnName, objectId, onAfterUpdate, table, ...memoOptions }: TableMemoOptions) { let beforeCompareTime: number let afterCompareTime: number let startCalcTime: number let endCalcTime: number let runCount = 0 let debug: boolean | undefined let debugCache: boolean | undefined if (process.env.NODE_ENV === 'development') { const { debugCache: _debugCache, debugAll } = table.options debugCache = _debugCache const { parentName } = getFunctionNameInfo(fnName, '.') const debugByParent = // @ts-expect-error table.options[ `debug${(parentName != 'table' ? parentName + 's' : parentName).replace( parentName, parentName.charAt(0).toUpperCase() + parentName.slice(1), )}` ] const debugByFeature = feature ? // @ts-expect-error table.options[ `debug${feature.charAt(0).toUpperCase() + feature.slice(1)}` ] : false debug = debugAll || debugByParent || debugByFeature } function logTime(time: number, depsChanged: boolean) { const runType = runCount === 0 ? '(1st run)' : depsChanged ? '(rerun #' + runCount + ')' : '(cache)' runCount++ console.groupCollapsed( `%c⏱ ${pad(`${time.toFixed(1)} ms`, 12)} %c${runType}%c ${fnName}%c ${objectId ? `(${fnName.split('.')[0]}Id: ${objectId})` : ''}`, `font-size: .6rem; font-weight: bold; ${ depsChanged ? `color: hsl( ${Math.max(0, Math.min(120 - Math.log10(time) * 60, 120))}deg 100% 31%);` : '' } `, `color: ${runCount < 2 ? '#FF00FF' : '#FF1493'}`, 'color: #666', 'color: #87CEEB', ) console.info({ feature, state: table.store.state, deps: memoOptions.memoDeps?.toString(), }) console.trace() console.groupEnd() } const debugOptions = process.env.NODE_ENV === 'development' ? { onBeforeCompare: () => { if (debugCache) { beforeCompareTime = performance.now() } }, onAfterCompare: (depsChanged: boolean) => { if (debugCache) { afterCompareTime = performance.now() const compareTime = Math.round((afterCompareTime - beforeCompareTime) * 100) / 100 if (!depsChanged) { logTime(compareTime, depsChanged) } } }, onBeforeUpdate: () => { if (debug) { startCalcTime = performance.now() } }, onAfterUpdate: () => { if (debug) { endCalcTime = performance.now() const executionTime = Math.round((endCalcTime - startCalcTime) * 100) / 100 logTime(executionTime, true) } queueMicrotask(() => onAfterUpdate?.()) }, } : { onAfterUpdate: () => { queueMicrotask(() => onAfterUpdate?.()) }, } return memo({ ...memoOptions, ...debugOptions, }) } export interface API, TDepArgs> { fn: (...args: any) => any memoDeps?: (depArgs?: any) => [...any] | undefined } export type APIObject, TDepArgs> = Record< string, API > /** * Assumes that a function name is in the format of `parentName_fnKey` and returns the `fnKey` and `fnName` in the format of `parentName.fnKey`. */ export function getFunctionNameInfo( staticFnName: string, splitBy: '_' | '.' = '_', ) { const [parentName, fnKey] = staticFnName.split(splitBy) const fnName = `${parentName}.${fnKey}` return { fnKey, fnName, parentName } as { fnKey: string fnName: string parentName: string } } /** * Assigns Table API methods directly to the table instance. * Unlike row/cell/column/header, the table is a singleton so methods are assigned directly. */ export function assignTableAPIs< TFeatures extends TableFeatures, TData extends RowData, TDeps extends ReadonlyArray, TDepArgs, >( feature: keyof TFeatures & string, table: Table_Internal, apis: APIObject>, ): void { for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) { const { fnKey, fnName } = getFunctionNameInfo(staticFnName) ;(table as Record)[fnKey] = memoDeps ? tableMemo({ memoDeps, fn, fnName, table, feature, }) : fn } } export interface PrototypeAPI, TDepArgs> { fn: (self: any, ...args: any) => any memoDeps?: (self: any, depArgs?: any) => [...any] | undefined } export type PrototypeAPIObject< TDeps extends ReadonlyArray, TDepArgs, > = Record> /** * Assigns API methods to a prototype object for memory-efficient method sharing. * All instances created with this prototype will share the same method references. * * For memoized methods, the memo state is lazily created and stored on each instance. * This provides the best of both worlds: shared method code + per-instance caching. */ export function assignPrototypeAPIs< TFeatures extends TableFeatures, TData extends RowData, TDeps extends ReadonlyArray, TDepArgs, >( feature: keyof TFeatures & string, prototype: Record, table: Table_Internal, apis: PrototypeAPIObject>, ): void { for (const [staticFnName, { fn, memoDeps }] of Object.entries(apis)) { const { fnKey, fnName } = getFunctionNameInfo(staticFnName) if (memoDeps) { // For memoized methods, create a function that lazily initializes // the memo on first access and stores it on the instance const memoKey = `_memo_${fnKey}` prototype[fnKey] = function (this: any, ...args: Array) { // Lazily create memo on first access for this instance if (!this[memoKey]) { const self = this this[memoKey] = tableMemo({ memoDeps: () => memoDeps(self), fn: (...deps) => fn(self, ...deps), fnName, objectId: self.id, table, feature, }) } return this[memoKey](...args) } } else { // Non-memoized methods just call the static function with `this` prototype[fnKey] = function (this: any, ...args: Array) { return fn(this, ...args) } } setMemoFnMeta(prototype[fnKey], { originalArgsLength: fn.length }) } } /** * Looks to run the memoized function with the builder pattern on the object if it exists, otherwise fallback to the static method passed in. */ export function callMemoOrStaticFn< TObject extends Record, TStaticFn extends AnyFunction, >( obj: TObject, fnKey: string, staticFn: TStaticFn, ...args: Parameters extends [any, ...infer Rest] ? Rest : never ): ReturnType { return ( (obj[fnKey] as Function | undefined)?.(...args) ?? staticFn(obj, ...args) ) } ================================================ FILE: packages/table-core/tests/fixtures/data/generateTestColumnDefs.ts ================================================ import { createColumnHelper } from '../../../src' import type { Person, PersonColumn, PersonKeys } from './types' import type { RowData, TableFeatures } from '../../../src' export function generateTestColumnDefs< TFeatures extends TableFeatures, TData extends RowData = Person, >(people: Array): Array> { const columnHelper = createColumnHelper() const person = people[0] if (!person) { return [] } return Object.keys(person).map((key) => { const typedKey = key as PersonKeys return columnHelper.accessor(typedKey as any, { id: typedKey } as any) }) } ================================================ FILE: packages/table-core/tests/fixtures/data/generateTestData.ts ================================================ import { faker } from '@faker-js/faker' import { createArrayOfNumbers } from '../../helpers/testUtils' import type { Person } from './types' function createPerson(): Person { return { id: faker.string.uuid(), firstName: faker.person.firstName(), lastName: faker.person.lastName(), age: faker.number.int(40), visits: faker.number.int(1000), progress: faker.number.int(100), status: faker.helpers.arrayElement([ 'relationship', 'complicated', 'single', ]), } } /** * Creates a nested array of test Person objects * @param lengths - An array of numbers where each number determines the length of Person arrays at that depth. * e.g. makeData(3, 2) creates 3 parent rows with 2 sub-rows each * @returns An array of Person objects with optional nested subRows based on the provided lengths */ export function generateTestData(...lengths: Array) { const makeDataLevel = (depth = 0): Array => { const len = lengths[depth] if (!len) return [] return createArrayOfNumbers(len).map(() => { return { ...createPerson(), subRows: lengths[depth + 1] ? makeDataLevel(depth + 1) : undefined, } }) } return makeDataLevel() } export function getStaticTestData() { return [ { id: '1', firstName: 'John', lastName: 'Doe', age: 30, visits: 100, progress: 50, status: 'relationship', }, { id: '2', firstName: 'Jane', lastName: 'Smith', age: 25, visits: 200, progress: 75, status: 'complicated', }, { id: '3', firstName: 'Alice', lastName: 'Johnson', age: 35, visits: 150, progress: 60, status: 'single', }, ] as const satisfies Array } ================================================ FILE: packages/table-core/tests/fixtures/data/types.ts ================================================ import type { ColumnDef, RowData, TableFeatures } from '../../../src' export type PersonKeys = keyof Person export type PersonColumn< TFeatures extends TableFeatures, TData extends RowData = Person, > = ColumnDef export type Person = { id: string firstName: string lastName: string age: number visits: number progress: number status: 'relationship' | 'complicated' | 'single' subRows?: Array } ================================================ FILE: packages/table-core/tests/fixtures/setup/test-setup.ts ================================================ import '@testing-library/jest-dom/vitest' ================================================ FILE: packages/table-core/tests/helpers/generateTestRows.ts ================================================ import { generateTestTableFromData, generateTestTableWithData, generateTestTableWithDataAndState, generateTestTableWithStateFromData, } from './generateTestTable' import type { Row, TableFeatures, TableOptions } from '../../src' import type { Person } from '../fixtures/data/types' export function generateTestRowsWithData( lengths: Array | number = 10, options?: Omit< TableOptions, 'data' | 'columns' | '_features' > & { _features?: TFeatures }, ): Array> { const testTable = generateTestTableWithData(lengths, options) return testTable.getRowModel().rows } export function generateTestRowsFromData( data: Array, options?: Omit, 'data' | 'columns'> & { _features?: TFeatures }, ): Array> { const testTable = generateTestTableFromData(data, options) return testTable.getRowModel().rows } export function generateTestRowsWithState( lengths: Array | number = 10, options?: Omit< TableOptions, 'data' | 'columns' | 'onStateChange' > & { _features?: TFeatures }, ): Array> { const testTable = generateTestTableWithDataAndState(lengths, options) return testTable.getRowModel().rows } export function generateTestRowsWithStateFromData< TFeatures extends TableFeatures, >( data: Array, options?: Omit< TableOptions, 'data' | 'columns' | 'onStateChange' > & { _features?: TFeatures }, ): Array> { const testTable = generateTestTableWithStateFromData(data, options) return testTable.getRowModel().rows } ================================================ FILE: packages/table-core/tests/helpers/generateTestTable.ts ================================================ import { constructTable, coreFeatures } from '../../src' import { generateTestColumnDefs } from '../fixtures/data/generateTestColumnDefs' import { generateTestData } from '../fixtures/data/generateTestData' import type { Row, Table, TableFeatures, TableOptions, TableState, } from '../../src' import type { Person } from '../fixtures/data/types' export function generateTestTableWithData( lengths: Array | number = 10, options?: Omit< TableOptions, 'data' | 'columns' | '_features' > & { _features?: TableFeatures }, ): Table { const lengthsArray = Array.isArray(lengths) ? lengths : [lengths] const data = generateTestData(...lengthsArray) const columns = generateTestColumnDefs(data) return constructTable({ data, columns, getSubRows: (row: Row) => row.subRows, ...options, _features: { ...coreFeatures, ...options?._features, }, } as any) } export function generateTestTableFromData( data: Array, options?: Omit, 'data' | 'columns'>, ): Table { const columns = generateTestColumnDefs(data) return constructTable({ data, columns, ...options, _features: { ...coreFeatures, ...options?._features, }, } as any) } export function generateTestTableWithDataAndState< TFeatures extends TableFeatures, >( lengths: Array | number = 10, options?: Omit< TableOptions, 'data' | 'columns' | 'onStateChange' >, ): Table { const lengthsArray = Array.isArray(lengths) ? lengths : [lengths] const data = generateTestData(...lengthsArray) const columns = generateTestColumnDefs(data) let state = { ...options?.initialState } as TableState const table = generateTestTableWithData(lengths, { data, columns, ...options, _features: { ...options?._features, }, state, onStateChange: (updater: any) => { if (typeof updater === 'function') { state = updater(state) } else { state = updater } table.options.state = state }, } as any) return table } export function generateTestTableWithStateFromData< TFeatures extends TableFeatures, >( data: Array, options?: Omit< TableOptions, 'data' | 'columns' | 'onStateChange' >, ): Table { const columns = generateTestColumnDefs(data) let state = { ...options?.initialState } as TableState const table = generateTestTableFromData(data, { columns, ...options, _features: { ...options?._features, }, state, onStateChange: (updater: any) => { if (typeof updater === 'function') { state = updater(state) } else { state = updater } }, } as any) return table } ================================================ FILE: packages/table-core/tests/helpers/rowPinningHelpers.ts ================================================ import { vi } from 'vitest' import { getDefaultRowPinningState } from '../../src/features/row-pinning/rowPinningFeature.utils' import { constructTable, createColumnHelper, coreFeatures, rowPinningFeature, } from '../../src' import { generateTestData } from '../fixtures/data/generateTestData' import { generateTestTableWithData } from './generateTestTable' import type { ColumnDef, RowPinningState, TableOptions } from '../../src' import type { Person } from '../fixtures/data/types' // Define feature set with proper typing const _features = { ...coreFeatures, rowPinningFeature, } as any type personKeys = keyof Person type PersonColumn = ColumnDef function generateColumnDefs(people: Array): Array { const columnHelper = createColumnHelper() const person = people[0] if (!person) { return [] } return Object.keys(person).map((key) => { const typedKey = key as personKeys return columnHelper.accessor(typedKey, { id: typedKey }) }) } export function createTableWithPinningState( rowCount = 10, pinningState?: RowPinningState, ) { const table = generateTestTableWithData(rowCount, { initialState: { rowPinning: pinningState ?? getDefaultRowPinningState(), }, _features: { rowPinning: rowPinningFeature, }, } as any) return table } export function createTableWithMockOnPinningChange(rowCount = 10): { table: ReturnType onRowPinningChangeMock: ReturnType } { const onRowPinningChangeMock = vi.fn() const table = generateTestTableWithData(rowCount, { _features: { rowPinning: rowPinningFeature, }, } as any) table.options.onRowPinningChange = onRowPinningChangeMock return { table, onRowPinningChangeMock } } export function createRowPinningTable( options?: Omit< TableOptions, 'data' | 'columns' | '_features' >, lengths: Array | number = 10, ): any { const lengthsArray = Array.isArray(lengths) ? lengths : [lengths] const data = generateTestData(...lengthsArray) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, data, columns, getSubRows: (row: any) => row.subRows, enableRowPinning: true, renderFallbackValue: '', initialState: { rowPinning: { top: [], bottom: [], }, ...options?.initialState, }, ...options, }) return table } ================================================ FILE: packages/table-core/tests/helpers/testUtils.ts ================================================ import type { vi } from 'vitest' import type { Person } from '../fixtures/data/types' export const createArrayOfNumbers = (length: number) => { return Array.from({ length }, (_, i) => i) } export const getPeopleIds = ( people: Array, usePersonId: boolean = false, ) => { return people.map((person, index) => (usePersonId ? person.id : `${index}`)) } export function getUpdaterResult(mock: ReturnType, input: any) { const updaterFn = mock.mock.calls[0]?.[0] return updaterFn?.(input) } ================================================ FILE: packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts ================================================ import { describe, expect, it } from 'vitest' import { constructTable, coreFeatures, createColumnHelper, createPaginatedRowModel, rowPaginationFeature, rowPinningFeature, } from '../../../../src' import { createRowPinningTable, createTableWithMockOnPinningChange, } from '../../../helpers/rowPinningHelpers' import { generateTestData } from '../../../fixtures/data/generateTestData' import type { ColumnDef, Row } from '../../../../src' import type { Person } from '../../../fixtures/data/types' // Define feature set with proper typing const _features = { ...coreFeatures, rowPinningFeature, } type personKeys = keyof Person type PersonColumn = ColumnDef function generateColumnDefs(people: Array): Array { const columnHelper = createColumnHelper() const person = people[0] if (!person) { return [] } return Object.keys(person).map((key) => { const typedKey = key as personKeys return columnHelper.accessor(typedKey, { id: typedKey }) }) } const ROW = { 0: '0', 1: '1', 2: '2', } as const const SUB_ROW = { 0: '0.0', 1: '0.1', } const EMPTY_PINNING_STATE = { top: [], bottom: [], } describe('table methods', () => { describe('setRowPinning', () => { it('should call onRowPinningChange when invoked', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const newState = { top: [ROW[0]], bottom: [ROW[1]], } table.setRowPinning(newState) expect(onRowPinningChangeMock).toHaveBeenCalledWith(newState) }) }) describe('resetRowPinning', () => { it('should reset to default state when defaultState is true', () => { const table = createRowPinningTable() table.setRowPinning({ top: [ROW[0]], bottom: [ROW[1]], }) table.resetRowPinning(true) expect(table.store.state.rowPinning).toEqual(EMPTY_PINNING_STATE) }) it('should reset to initial state when defaultState is false', () => { const initialState = { top: [ROW[0]], bottom: [ROW[1]], } const table = createRowPinningTable({ initialState: { rowPinning: initialState, }, }) table.setRowPinning({ top: [ROW[2]], bottom: [], }) table.resetRowPinning(false) expect(table.store.state.rowPinning).toEqual(initialState) }) }) describe('getIsSomeRowsPinned', () => { it('should return false when no rows are pinned', () => { const table = createRowPinningTable() expect(table.getIsSomeRowsPinned()).toBe(false) expect(table.getIsSomeRowsPinned('top')).toBe(false) expect(table.getIsSomeRowsPinned('bottom')).toBe(false) }) it('should return true when rows are pinned', () => { const table = createRowPinningTable({ initialState: { rowPinning: { top: [ROW[0]], bottom: [ROW[1]], }, }, }) expect(table.getIsSomeRowsPinned()).toBe(true) expect(table.getIsSomeRowsPinned('top')).toBe(true) expect(table.getIsSomeRowsPinned('bottom')).toBe(true) }) }) describe('getTopRows/getBottomRows/getCenterRows', () => { it('should return correct rows for each section', () => { const table = createRowPinningTable({ initialState: { rowPinning: { top: [ROW[0]], bottom: [ROW[2]], }, }, }) const topRows = table.getTopRows() const bottomRows = table.getBottomRows() const centerRows = table.getCenterRows() expect(topRows).toHaveLength(1) expect(topRows[0]?.id).toBe(ROW[0]) expect(bottomRows).toHaveLength(1) expect(bottomRows[0]?.id).toBe(ROW[2]) expect(centerRows).toHaveLength(8) expect( centerRows.every( (row: (typeof centerRows)[number]) => row.id !== ROW[0] && row.id !== ROW[2], ), ).toBe(true) }) it('should handle keepPinnedRows - false', () => { const data = generateTestData(10) const columns = generateColumnDefs(data) const _featuresWithPagination = { ...coreFeatures, rowPinningFeature, rowPaginationFeature, } const table = constructTable({ _features: _featuresWithPagination, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, data, columns, getSubRows: (row) => row.subRows, enableRowPinning: true, renderFallbackValue: '', initialState: { // Make first 2 rows visible pagination: { pageSize: 2, pageIndex: 0, }, rowPinning: { top: [ROW[0]], bottom: [ROW[2]], }, }, keepPinnedRows: false, }) expect(table.getTopRows()).toHaveLength(1) expect(table.getBottomRows()).toHaveLength(0) // Row 2 is not in visible rows }) }) it('should handle keepPinnedRows - true', () => { const data = generateTestData(10) const columns = generateColumnDefs(data) const _featuresWithPagination = { ...coreFeatures, rowPinningFeature, rowPaginationFeature, } const table = constructTable({ _features: _featuresWithPagination, _rowModels: { paginatedRowModel: createPaginatedRowModel(), }, data, columns, getSubRows: (row) => row.subRows, enableRowPinning: true, renderFallbackValue: '', initialState: { // Make first 2 rows visible pagination: { pageSize: 2, pageIndex: 0, }, rowPinning: { top: [ROW[0]], bottom: [ROW[2]], }, }, keepPinnedRows: true, }) expect(table.getTopRows()).toHaveLength(1) expect(table.getBottomRows()).toHaveLength(1) }) }) describe('row methods', () => { describe('getCanPin', () => { it('should return true by default', () => { const table = createRowPinningTable() const row = table.getRow(ROW[0]) expect(row.getCanPin()).toBe(true) }) it('should return false when enableRowPinning is false', () => { const table = createRowPinningTable({ enableRowPinning: false, }) const row = table.getRow(ROW[0]) expect(row.getCanPin()).toBe(false) }) it('should use enableRowPinning function when provided', () => { const table = createRowPinningTable({ enableRowPinning: (row: Row) => row.id === ROW[1], }) expect(table.getRow(ROW[0]).getCanPin()).toBe(false) expect(table.getRow(ROW[1]).getCanPin()).toBe(true) }) }) describe('getIsPinned', () => { it('should return false when row is not pinned', () => { const table = createRowPinningTable() const row = table.getRow(ROW[0]) expect(row.getIsPinned()).toBe(false) }) it('should return correct position when row is pinned', () => { const table = createRowPinningTable({ initialState: { rowPinning: { top: [ROW[0]], bottom: [ROW[1]], }, }, }) expect(table.getRow(ROW[0]).getIsPinned()).toBe('top') expect(table.getRow(ROW[1]).getIsPinned()).toBe('bottom') }) }) describe('getPinnedIndex', () => { it('should return -1 when row is not pinned', () => { const table = createRowPinningTable() const row = table.getRow(ROW[0]) expect(row.getPinnedIndex()).toBe(-1) }) it('should return correct index for pinned rows', () => { const table = createRowPinningTable({ initialState: { rowPinning: { top: [ROW[0], ROW[1]], bottom: [ROW[2]], }, }, }) expect(table.getRow(ROW[0]).getPinnedIndex()).toBe(0) expect(table.getRow(ROW[1]).getPinnedIndex()).toBe(1) expect(table.getRow(ROW[2]).getPinnedIndex()).toBe(0) }) }) describe('pin', () => { it('should call onRowPinningChange when pinning row', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const row = table.getRow(ROW[0]) row.pin('top') expect(onRowPinningChangeMock).toHaveBeenCalled() // The exact call pattern would depend on row.pin implementation // This test verifies the callback mechanism works }) it('should call onRowPinningChange when unpinning row', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() // Set up initial state with a pinned row table.baseStore.setState((old: any) => ({ ...old, rowPinning: { top: [ROW[0]], bottom: [], }, })) const row = table.getRow(ROW[0]) row.pin(false) expect(onRowPinningChangeMock).toHaveBeenCalled() }) it('should call onRowPinningChange when including leaf rows', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange(10) const row = table.getRow(ROW[0]) row.pin('top', true) expect(onRowPinningChangeMock).toHaveBeenCalled() // The callback should be invoked when pinning with leaf rows }) it('should call onRowPinningChange when including parent rows', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange(10) const row = table.getRow(ROW[0]) row.pin('top', false, true) expect(onRowPinningChangeMock).toHaveBeenCalled() // The callback should be invoked when pinning with parent rows }) }) }) ================================================ FILE: packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts ================================================ import { describe, expect, it } from 'vitest' import { constructTable, createColumnHelper, rowSelectionFeature, } from '../../../../src' import * as RowSelectionUtils from '../../../../src/features/row-selection/rowSelectionFeature.utils' import { generateTestData } from '../../../fixtures/data/generateTestData' import type { Person } from '../../../fixtures/data/types' import type { ColumnDef } from '../../../../src' // TODO: bring up to new test structure const _features = { rowSelectionFeature, } type personKeys = keyof Person type PersonColumn = ColumnDef function generateColumnDefs(people: Array): Array { const columnHelper = createColumnHelper() const person = people[0] if (!person) { return [] } return Object.keys(person).map((key) => { const typedKey = key as personKeys return columnHelper.accessor(typedKey, { id: typedKey }) }) } describe('rowSelectionFeature', () => { describe('selectRowsFn', () => { it('should only return rows that are selected', () => { const data = generateTestData(5) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: { '0': true, '2': true, }, }, columns, }) const rowModel = table.getCoreRowModel() const result = RowSelectionUtils.selectRowsFn(rowModel) expect(result.rows.length).toBe(2) expect(result.flatRows.length).toBe(2) expect(result.rowsById).toHaveProperty('0') expect(result.rowsById).toHaveProperty('2') }) it('should recurse into subRows and only return selected subRows', () => { const data = generateTestData(3, 2) // assuming 3 parent rows with 2 sub-rows each const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: { '0': true, '0.0': true, }, }, columns, }) const rowModel = table.getCoreRowModel() const result = RowSelectionUtils.selectRowsFn(rowModel) expect(result.rows[0]?.subRows?.length).toBe(1) expect(result.flatRows.length).toBe(2) expect(result.rowsById).toHaveProperty('0') expect(result.rowsById).toHaveProperty('0.0') }) it('should return an empty list if no rows are selected', () => { const data = generateTestData(5) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: {}, }, columns, }) const rowModel = table.getCoreRowModel() const result = RowSelectionUtils.selectRowsFn(rowModel) expect(result.rows.length).toBe(0) expect(result.flatRows.length).toBe(0) expect(result.rowsById).toEqual({}) }) }) describe('isRowSelected', () => { it('should return true if the row id exists in selection and is set to true', () => { const data = generateTestData(3) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, initialState: { rowSelection: { '123': true, '456': false, }, }, columns, }) const row = { id: '123', data: {}, table } as any const result = RowSelectionUtils.isRowSelected(row) expect(result).toEqual(true) }) it('should return false if the row id exists in selection and is set to false', () => { const data = generateTestData(3) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, initialState: { rowSelection: { '123': true, '456': false, }, }, columns, }) const row = { id: '456', data: {}, table } as any const result = RowSelectionUtils.isRowSelected(row) expect(result).toEqual(false) }) it('should return false if the row id does not exist in selection', () => { const data = generateTestData(3) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, initialState: { rowSelection: { '123': true, '456': false, }, }, columns, }) const row = { id: '789', data: {}, table } as any const result = RowSelectionUtils.isRowSelected(row) expect(result).toEqual(false) }) it('should return false if selection is an empty object', () => { const data = generateTestData(3) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, initialState: {}, columns, }) const row = { id: '789', data: {}, table } as any const result = RowSelectionUtils.isRowSelected(row) expect(result).toEqual(false) }) }) describe('isSubRowSelected', () => { it('should return false if there are no sub-rows', () => { const data = generateTestData(3) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, initialState: {}, columns, }) const firstRow = table.getCoreRowModel().rows[0]! const result = RowSelectionUtils.isSubRowSelected(firstRow) expect(result).toEqual(false) }) it('should return false if no sub-rows are selected', () => { const data = generateTestData(3, 2) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: {}, }, columns, }) const firstRow = table.getCoreRowModel().rows[0]! const result = RowSelectionUtils.isSubRowSelected(firstRow) expect(result).toEqual(false) }) it('should return some if some sub-rows are selected', () => { const data = generateTestData(3, 2) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: { '0.0': true, }, }, columns, }) const firstRow = table.getCoreRowModel().rows[0]! const result = RowSelectionUtils.isSubRowSelected(firstRow) expect(result).toEqual('some') }) it('should return all if all sub-rows are selected', () => { const data = generateTestData(3, 2) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: { '0.0': true, '0.1': true, }, }, columns, }) const firstRow = table.getCoreRowModel().rows[0]! const result = RowSelectionUtils.isSubRowSelected(firstRow) expect(result).toEqual('all') }) it('should return all if all selectable sub-rows are selected', () => { const data = generateTestData(3, 2) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: (row) => row.index === 0, // only first row is selectable (of 2 sub-rows) renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: { '0.0': true, // first sub-row }, }, columns, }) const firstRow = table.getCoreRowModel().rows[0]! const result = RowSelectionUtils.isSubRowSelected(firstRow) expect(result).toEqual('all') }) it('should return some when some nested sub-rows are selected', () => { const data = generateTestData(3, 2, 2) const columns = generateColumnDefs(data) const table = constructTable({ _features, _rowModels: {}, enableRowSelection: true, renderFallbackValue: '', data, getSubRows: (row) => row.subRows, initialState: { rowSelection: { '0.0.0': true, // first nested sub-row }, }, columns, }) const firstRow = table.getCoreRowModel().rows[0]! const result = RowSelectionUtils.isSubRowSelected(firstRow) expect(result).toEqual('some') }) }) }) ================================================ FILE: packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts ================================================ import { describe, expect, it } from 'vitest' import { aggregationFns, columnGroupingFeature, constructTable, coreFeatures, createGroupedRowModel, } from '../../../../src' import { createColumnHelper } from '../../../../src/helpers/columnHelper' import { generateTestData } from '../../../fixtures/data/generateTestData' import type { Person } from '../../../fixtures/data/types' import type { ColumnDef } from '../../../../src' // TODO: bring up to new test structure type personKeys = keyof Person type PersonColumn = ColumnDef function generateColumns(people: Array): Array { const columnHelper = createColumnHelper() const person = people[0] if (!person) { return [] } return Object.keys(person).map((key) => { const typedKey = key as personKeys return columnHelper.accessor(typedKey, { id: typedKey }) }) } describe('#getGroupedRowModel', () => { it('groups 50k rows and 3 grouped columns with clustered data in less than 5 seconds', () => { const data = generateTestData(50000) const columns = generateColumns(data) const grouping = ['firstName', 'lastName', 'age'] const start = new Date() data.forEach((p) => (p.firstName = 'Fixed')) data.forEach((p) => (p.lastName = 'Name')) data.forEach((p) => (p.age = 123)) const table = constructTable({ _features: { columnGroupingFeature, ...coreFeatures }, _rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns), }, onStateChange() {}, renderFallbackValue: '', data, initialState: { grouping }, columns, }) const groupedById = table.getGroupedRowModel().rowsById const end = new Date() expect(groupedById['firstName:Fixed']?.getLeafRows().length).toEqual(50002) expect( groupedById['firstName:Fixed>lastName:Name']?.getLeafRows().length, ).toEqual(50001) expect( groupedById['firstName:Fixed>lastName:Name>age:123']?.getLeafRows() .length, ).toEqual(50000) expect(end.valueOf() - start.valueOf()).toBeLessThan(5000) }) }) ================================================ FILE: packages/table-core/tests/unit/core/cells/constructCell.test.ts ================================================ import { describe, expect, it } from 'vitest' import { constructCell } from '../../../../src/core/cells/constructCell' import { coreCellsFeature } from '../../../../src/core/cells/coreCellsFeature' import type { Row } from '../../../../src/types/Row' import type { Column } from '../../../../src/types/Column' import type { Table } from '../../../../src/types/Table' describe('constructCell', () => { it('should populate the cell with all core cell APIs and properties', () => { const column = { id: 'test-column' } as Column const row = { id: 'test-row' } as Row const table = { _features: { coreCellsFeature }, options: {} } as Table< any, any > const coreCell = constructCell(column, row, table) expect(coreCell).toBeDefined() expect(coreCell).toHaveProperty('column') expect(coreCell).toHaveProperty('id') expect(coreCell).toHaveProperty('row') expect(coreCell).toHaveProperty('getContext') expect(coreCell).toHaveProperty('getValue') expect(coreCell).toHaveProperty('renderValue') expect(coreCell.id).toBe(`${row.id}_${column.id}`) expect(coreCell.column).toBe(column) expect(coreCell.row).toBe(row) }) }) ================================================ FILE: packages/table-core/tests/unit/core/columns/constructColumn.test.ts ================================================ import { describe, expect, it } from 'vitest' import { coreColumnsFeature } from '../../../../src/core/columns/coreColumnsFeature' import { constructColumn } from '../../../../src/core/columns/constructColumn' import { constructTable } from '../../../../src' import type { ColumnDef } from '../../../../src/types/ColumnDef' describe('constructColumn', () => { it('should create a column with all core column APIs and properties', () => { const table = constructTable({ _features: { coreColumnsFeature }, columns: [] as Array, data: [] as Array, }) const columnDef = { id: 'test-column', accessorKey: 'test-accessor-key', } as ColumnDef const depth = 0 const parent = undefined const column = constructColumn(table as any, columnDef, depth, parent) expect(column).toBeDefined() expect(column).toHaveProperty('accessorFn') expect(column).toHaveProperty('columnDef') expect(column).toHaveProperty('columns') expect(column).toHaveProperty('depth') expect(column).toHaveProperty('id') expect(column).toHaveProperty('parent') expect(column).toHaveProperty('getFlatColumns') expect(column).toHaveProperty('getLeafColumns') expect(column.id).toBe(columnDef.id) expect(column.depth).toBe(depth) expect(column.parent).toBe(parent) }) }) ================================================ FILE: packages/table-core/tests/unit/core/headers/constructHeader.test.ts ================================================ import { describe, expect, it } from 'vitest' import { coreHeadersFeature } from '../../../../src/core/headers/coreHeadersFeature' import { constructHeader } from '../../../../src/core/headers/constructHeader' import type { Column } from '../../../../src/types/Column' import type { Table } from '../../../../src/types/Table' describe('constructHeader', () => { it('should create a column with all core column APIs and properties', () => { const table = { _features: { coreHeadersFeature }, options: {} } as Table< any, any > const column = { id: 'test-column', columnDef: { id: 'test-column-def' }, } as Column const index = 0 const depth = 0 const header = constructHeader(table, column, { index, depth, }) expect(header).toBeDefined() expect(header).toHaveProperty('colSpan') expect(header).toHaveProperty('column') expect(header).toHaveProperty('depth') expect(header).toHaveProperty('headerGroup') expect(header).toHaveProperty('id') expect(header).toHaveProperty('index') expect(header).toHaveProperty('isPlaceholder') expect(header).toHaveProperty('placeholderId') expect(header).toHaveProperty('rowSpan') expect(header).toHaveProperty('subHeaders') expect(header).toHaveProperty('getContext') expect(header).toHaveProperty('getLeafHeaders') expect(header.id).toBe(column.id) }) }) ================================================ FILE: packages/table-core/tests/unit/core/rows/constructRow.test.ts ================================================ import { describe, expect, it } from 'vitest' import { coreRowsFeature } from '../../../../src/core/rows/coreRowsFeature' import { constructRow } from '../../../../src/core/rows/constructRow' import type { Table } from '../../../../src/types/Table' import type { Row } from '../../../../src/types/Row' interface Person { firstName: string } describe('constructRow', () => { it('should create a row with all core row APIs and properties', () => { const table = { _features: { coreRowsFeature }, options: {} } as Table< any, Person > const id = 'test-row' const original = { firstName: 'Tanner' } as Person const rowIndex = 0 const depth = 0 const subRows = [] as Array> const parentId = 'parent-id' const row = constructRow( table, id, original, rowIndex, depth, subRows, parentId, ) expect(row).toBeDefined() expect(row).toHaveProperty('_uniqueValuesCache') expect(row).toHaveProperty('_valuesCache') expect(row).toHaveProperty('depth') expect(row).toHaveProperty('id') expect(row).toHaveProperty('index') expect(row).toHaveProperty('original') expect(row).toHaveProperty('parentId') expect(row).toHaveProperty('subRows') expect(row).toHaveProperty('getAllCellsByColumnId') expect(row).toHaveProperty('getAllCells') expect(row).toHaveProperty('getLeafRows') expect(row).toHaveProperty('getParentRow') expect(row).toHaveProperty('getParentRows') expect(row).toHaveProperty('getUniqueValues') expect(row).toHaveProperty('getValue') expect(row).toHaveProperty('renderValue') expect(row.id).toBe(id) expect(row.original).toBe(original) expect(row.index).toBe(rowIndex) expect(row.depth).toBe(depth) expect(row.subRows).toBe(subRows) expect(row.parentId).toBe(parentId) }) }) ================================================ FILE: packages/table-core/tests/unit/core/table/constructTable.test.ts ================================================ import { describe, expect, it } from 'vitest' import { constructTable, coreFeatures } from '../../../../src' describe('constructTable', () => { it('should create a table with all core table APIs and properties', () => { const table = constructTable({ _features: { ...coreFeatures, }, columns: [], data: [], }) expect(table).toBeDefined() // core table properties expect(table).toHaveProperty('_features') expect(table).toHaveProperty('_rowModelFns') expect(table).toHaveProperty('_rowModels') expect(table).toHaveProperty('initialState') expect(table).toHaveProperty('options') // column related table APIs expect(table).toHaveProperty('getAllFlatColumnsById') expect(table).toHaveProperty('getDefaultColumnDef') expect(table).toHaveProperty('getAllColumns') expect(table).toHaveProperty('getAllFlatColumns') expect(table).toHaveProperty('getAllLeafColumns') expect(table).toHaveProperty('getColumn') // header related table APIs expect(table).toHaveProperty('getHeaderGroups') expect(table).toHaveProperty('getFooterGroups') expect(table).toHaveProperty('getFlatHeaders') expect(table).toHaveProperty('getLeafHeaders') // row related table APIs expect(table).toHaveProperty('getRowId') expect(table).toHaveProperty('getRow') // table APIs expect(table).toHaveProperty('getCoreRowModel') expect(table).toHaveProperty('getRowModel') expect(table).toHaveProperty('reset') expect(table).toHaveProperty('setOptions') expect(table).toHaveProperty('store') // state is managed via store in v9 }) }) ================================================ FILE: packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts ================================================ import { describe, expect, it, vi } from 'vitest' import { generateTestTableWithData } from '../../../helpers/generateTestTable' import { column_getIndex, column_getIsFirstColumn, column_getIsLastColumn, getDefaultColumnOrderState, orderColumns, table_getOrderColumnsFn, table_resetColumnOrder, table_setColumnOrder, } from '../../../../src/features/column-ordering/columnOrderingFeature.utils' import type { TableFeatures } from '../../../../src' describe('getDefaultColumnOrderState', () => { it('should return an empty array', () => { expect(getDefaultColumnOrderState()).toEqual([]) }) }) describe('column_getIndex', () => { it('should return correct index for a column', () => { const table = generateTestTableWithData(3) const column = table.getAllLeafColumns()[1]! expect(column_getIndex(column)).toBe(1) }) it('should return -1 for non-existent column', () => { const table = generateTestTableWithData(3) const column = { ...table.getAllLeafColumns()[0], id: 'non-existent', table, } expect(column_getIndex(column)).toBe(-1) }) }) describe('column_getIsFirstColumn', () => { it('should return true for first column', () => { const table = generateTestTableWithData(3) const firstColumn = table.getAllLeafColumns()[0]! expect(column_getIsFirstColumn(firstColumn)).toBe(true) }) it('should return false for non-first column', () => { const table = generateTestTableWithData(3) const secondColumn = table.getAllLeafColumns()[1]! expect(column_getIsFirstColumn(secondColumn)).toBe(false) }) }) describe('column_getIsLastColumn', () => { it('should return true for last column', () => { const table = generateTestTableWithData(3) const columns = table.getAllLeafColumns() const lastColumn = columns[columns.length - 1]! expect(column_getIsLastColumn(lastColumn)).toBe(true) }) it('should return false for non-last column', () => { const table = generateTestTableWithData(3) const firstColumn = table.getAllLeafColumns()[0]! expect(column_getIsLastColumn(firstColumn)).toBe(false) }) }) describe('table_setColumnOrder', () => { it('should call onColumnOrderChange with updater', () => { const onColumnOrderChange = vi.fn() const table = generateTestTableWithData(3, { onColumnOrderChange, }) const newOrder = ['col1', 'col2'] table_setColumnOrder(table, newOrder) expect(onColumnOrderChange).toHaveBeenCalledWith(newOrder) }) }) describe('table_resetColumnOrder', () => { it('should reset to empty array when defaultState is true', () => { const onColumnOrderChange = vi.fn() const table = generateTestTableWithData(3, { onColumnOrderChange, }) table_resetColumnOrder(table, true) expect(onColumnOrderChange).toHaveBeenCalledWith([]) }) it('should reset to initialState when defaultState is false', () => { const initialColumnOrder = ['col1', 'col2'] const onColumnOrderChange = vi.fn() const table = generateTestTableWithData(3, { onColumnOrderChange, initialState: { columnOrder: initialColumnOrder }, }) table_resetColumnOrder(table, false) expect(onColumnOrderChange).toHaveBeenCalledWith(initialColumnOrder) }) }) describe('table_getOrderColumnsFn', () => { it('should return original columns when no column order is specified', () => { const table = generateTestTableWithData(3) const columns = table.getAllLeafColumns() const orderFn = table_getOrderColumnsFn(table) expect(orderFn(columns)).toEqual(columns) }) it('should reorder columns according to columnOrder', () => { const table = generateTestTableWithData(3, { initialState: { columnOrder: ['lastName', 'firstName'], }, }) const columns = table.getAllLeafColumns() const orderFn = table_getOrderColumnsFn(table) const orderedColumns = orderFn(columns) expect(orderedColumns[0]?.id).toBe('lastName') expect(orderedColumns[1]?.id).toBe('firstName') }) }) describe('orderColumns', () => { it('should return original columns when no grouping is present', () => { const table = generateTestTableWithData(3) const columns = table.getAllLeafColumns() expect(orderColumns(table, columns)).toEqual(columns) }) it('should remove grouped columns when groupedColumnMode is "remove"', () => { const table = generateTestTableWithData(3, { initialState: { grouping: ['firstName'], }, groupedColumnMode: 'remove', }) const columns = table.getAllLeafColumns() const orderedColumns = orderColumns(table, columns) expect(orderedColumns.find((col) => col.id === 'firstName')).toBeUndefined() }) it('should move grouped columns to start when groupedColumnMode is "reorder"', () => { const table = generateTestTableWithData(3, { initialState: { grouping: ['lastName'], }, groupedColumnMode: 'reorder', }) const columns = table.getAllLeafColumns() const orderedColumns = orderColumns(table, columns) expect(orderedColumns[0]?.id).toBe('lastName') }) }) ================================================ FILE: packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts ================================================ import { describe, expect, it, vi } from 'vitest' import { column_getCanPin, column_getIsPinned, column_getPinnedIndex, column_pin, getDefaultColumnPinningState, row_getCenterVisibleCells, row_getLeftVisibleCells, row_getRightVisibleCells, table_getCenterFlatHeaders, table_getCenterFooterGroups, table_getCenterHeaderGroups, table_getCenterLeafColumns, table_getIsSomeColumnsPinned, table_getLeftFlatHeaders, table_getLeftFooterGroups, table_getLeftHeaderGroups, table_getLeftLeafColumns, table_getPinnedLeafColumns, table_getPinnedVisibleLeafColumns, table_getRightFlatHeaders, table_getRightFooterGroups, table_getRightHeaderGroups, table_getRightLeafColumns, table_getVisibleLeafColumns, table_resetColumnPinning, table_setColumnPinning, } from '../../../../src' import { generateTestTableWithData } from '../../../helpers/generateTestTable' import { getUpdaterResult } from '../../../helpers/testUtils' import type { Header } from '../../../../src' describe('getDefaultColumnPinningState', () => { it('should return default column pinning state', () => { const result = getDefaultColumnPinningState() expect(result).toEqual({ left: [], right: [], }) }) }) describe('column_pin', () => { it('should pin column to the left', () => { const onColumnPinningChange = vi.fn() const table = generateTestTableWithData(1, { onColumnPinningChange, initialState: { columnPinning: { left: [], right: [], }, }, }) const column = table.getAllColumns()[0]! column_pin(column, 'left') const result = getUpdaterResult(onColumnPinningChange, { left: [], right: [], }) expect(result).toEqual({ left: [column.id], right: [], }) }) it('should pin column to the right', () => { const onColumnPinningChange = vi.fn() const table = generateTestTableWithData(1, { onColumnPinningChange, initialState: { columnPinning: { left: [], right: [], }, }, }) const column = table.getAllColumns()[0]! column_pin(column, 'right') const result = getUpdaterResult(onColumnPinningChange, { left: [], right: [], }) expect(result).toEqual({ left: [], right: [column.id], }) }) it('should unpin column when false is passed', () => { const onColumnPinningChange = vi.fn() const table = generateTestTableWithData(1, { onColumnPinningChange, initialState: { columnPinning: { left: ['id'], right: [], }, }, }) const column = table.getColumn('id')! column_pin(column, false) const result = getUpdaterResult(onColumnPinningChange, { left: ['id'], right: [], }) expect(result).toEqual({ left: [], right: [], }) }) }) describe('column_getCanPin', () => { it('should return true when column pinning is enabled', () => { const table = generateTestTableWithData(1) const column = table.getAllColumns()[0] const result = column_getCanPin(column) expect(result).toBe(true) }) it('should return false when column pinning is disabled globally', () => { const table = generateTestTableWithData(1, { enableColumnPinning: false, }) const column = table.getAllColumns()[0] const result = column_getCanPin(column) expect(result).toBe(false) }) it('should return false when column pinning is disabled for specific column', () => { const table = generateTestTableWithData(1) const column = { ...table.getAllColumns()[0], columnDef: { enablePinning: false }, table: table, getLeafColumns: () => [ { ...table.getAllColumns()[0], columnDef: { enablePinning: false }, }, ], } const result = column_getCanPin(column) expect(result).toBe(false) }) }) describe('column_getIsPinned', () => { it('should return left when column is pinned left', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const column = table.getColumn('firstName')! const result = column_getIsPinned(column) expect(result).toBe('left') }) it('should return right when column is pinned right', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['firstName'], }, }, }) const column = table.getColumn('firstName')! const result = column_getIsPinned(column) expect(result).toBe('right') }) it('should return false when column is not pinned', () => { const table = generateTestTableWithData(1) const column = table.getColumn('firstName')! const result = column_getIsPinned(column) expect(result).toBe(false) }) }) describe('table_setColumnPinning', () => { it('should call onColumnPinningChange with updater', () => { const onColumnPinningChange = vi.fn() const table = generateTestTableWithData(1, { onColumnPinningChange, }) table_setColumnPinning(table, { left: ['firstName'], right: [], }) expect(onColumnPinningChange).toHaveBeenCalledWith({ left: ['firstName'], right: [], }) }) }) describe('table_resetColumnPinning', () => { it('should reset to default state when defaultState is true', () => { const onColumnPinningChange = vi.fn() const table = generateTestTableWithData(1, { onColumnPinningChange, }) table_resetColumnPinning(table, true) expect(onColumnPinningChange).toHaveBeenCalledWith({ left: [], right: [], }) }) it('should reset to initial state when defaultState is false', () => { const onColumnPinningChange = vi.fn() const initialState = { columnPinning: { left: ['firstName'], right: [], }, } const table = generateTestTableWithData(1, { onColumnPinningChange, initialState, }) table_resetColumnPinning(table, false) expect(onColumnPinningChange).toHaveBeenCalledWith({ left: ['firstName'], right: [], }) }) }) describe('table_getIsSomeColumnsPinned', () => { it('should return true when columns are pinned left', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const result = table_getIsSomeColumnsPinned(table) expect(result).toBe(true) }) it('should return true when columns are pinned right', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['firstName'], }, }, }) const result = table_getIsSomeColumnsPinned(table) expect(result).toBe(true) }) it('should return false when no columns are pinned', () => { const table = generateTestTableWithData(1) const result = table_getIsSomeColumnsPinned(table) expect(result).toBe(false) }) it('should check specific position when position parameter is provided', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) expect(table_getIsSomeColumnsPinned(table, 'left')).toBe(true) expect(table_getIsSomeColumnsPinned(table, 'right')).toBe(false) }) }) describe('column_getPinnedIndex', () => { it('should return index of pinned column', () => { const table = generateTestTableWithData(2, { initialState: { columnPinning: { left: ['firstName', 'lastName'], right: [], }, }, }) const column = table.getColumn('lastName')! const result = column_getPinnedIndex(column) expect(result).toBe(1) }) it('should return 0 when column is not pinned', () => { const table = generateTestTableWithData(1) const column = table.getColumn('firstName')! const result = column_getPinnedIndex(column) expect(result).toBe(0) }) }) describe('row_getCenterVisibleCells', () => { it('should return only unpinned visible cells', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const row = table.getRowModel().rows[0]! const centerCells = row_getCenterVisibleCells(row) expect(centerCells.map((cell) => cell.column.id)).not.toContain('firstName') expect(centerCells.map((cell) => cell.column.id)).not.toContain('lastName') expect(centerCells.length).toBeGreaterThan(0) }) }) describe('row_getLeftVisibleCells', () => { it('should return only left pinned cells', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const row = table.getRowModel().rows[0]! const leftCells = row_getLeftVisibleCells(row) expect(leftCells).toHaveLength(1) expect(leftCells[0]?.column.id).toBe('firstName') }) it('should return empty array when no columns are pinned left', () => { const table = generateTestTableWithData(1) const row = table.getRowModel().rows[0]! const leftCells = row_getLeftVisibleCells(row) expect(leftCells).toHaveLength(0) }) }) describe('row_getRightVisibleCells', () => { it('should return only right pinned cells', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const row = table.getRowModel().rows[0]! const rightCells = row_getRightVisibleCells(row) expect(rightCells).toHaveLength(1) expect(rightCells[0]?.column.id).toBe('lastName') }) it('should return empty array when no columns are pinned right', () => { const table = generateTestTableWithData(1) const row = table.getRowModel().rows[0]! const rightCells = row_getRightVisibleCells(row) expect(rightCells).toHaveLength(0) }) }) describe('table_getLeftHeaderGroups', () => { it('should return header groups for left pinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const headerGroups = table_getLeftHeaderGroups(table) expect(headerGroups[0]?.headers[0]?.column.id).toBe('firstName') }) }) describe('table_getRightHeaderGroups', () => { it('should return header groups for right pinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['lastName'], }, }, }) const headerGroups = table_getRightHeaderGroups(table) expect(headerGroups[0]?.headers[0]?.column.id).toBe('lastName') }) }) describe('table_getCenterHeaderGroups', () => { it('should return header groups for unpinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const headerGroups = table_getCenterHeaderGroups(table) const centerColumnIds = headerGroups[0]?.headers.map( (header: Header) => header.column.id, ) expect(centerColumnIds).not.toContain('firstName') expect(centerColumnIds).not.toContain('lastName') expect(headerGroups[0]?.headers.length).toBeGreaterThan(0) }) }) describe('table_getLeftLeafColumns', () => { it('should return left pinned leaf columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const leafColumns = table_getLeftLeafColumns(table) expect(leafColumns).toHaveLength(1) expect(leafColumns[0]?.id).toBe('firstName') }) }) describe('table_getRightLeafColumns', () => { it('should return right pinned leaf columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['lastName'], }, }, }) const leafColumns = table_getRightLeafColumns(table) expect(leafColumns).toHaveLength(1) expect(leafColumns[0]?.id).toBe('lastName') }) }) describe('table_getCenterLeafColumns', () => { it('should return unpinned leaf columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const leafColumns = table_getCenterLeafColumns(table) const centerColumnIds = leafColumns.map((col) => col.id) expect(centerColumnIds).not.toContain('firstName') expect(centerColumnIds).not.toContain('lastName') expect(leafColumns.length).toBeGreaterThan(0) }) }) describe('table_getPinnedLeafColumns', () => { it('should return left pinned leaf columns when position is left', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const leafColumns = table_getPinnedLeafColumns(table, 'left') expect(leafColumns).toHaveLength(1) expect(leafColumns[0]?.id).toBe('firstName') }) it('should return right pinned leaf columns when position is right', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['lastName'], }, }, }) const leafColumns = table_getPinnedLeafColumns(table, 'right') expect(leafColumns).toHaveLength(1) expect(leafColumns[0]?.id).toBe('lastName') }) it('should return center leaf columns when position is center', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const leafColumns = table_getPinnedLeafColumns(table, 'center') expect(leafColumns.length).toBeGreaterThan(0) expect(leafColumns.map((col) => col.id)).not.toContain('firstName') expect(leafColumns.map((col) => col.id)).not.toContain('lastName') }) }) describe('table_getPinnedVisibleLeafColumns', () => { it('should return visible leaf columns for specified position', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, columnVisibility: { age: false, }, }, }) const leftColumns = table_getPinnedVisibleLeafColumns(table, 'left') const rightColumns = table_getPinnedVisibleLeafColumns(table, 'right') const centerColumns = table_getPinnedVisibleLeafColumns(table, 'center') expect(leftColumns[0]?.id).toBe('firstName') expect(rightColumns[0]?.id).toBe('lastName') expect(centerColumns.map((col) => col.id)).not.toContain('age') }) it('should return all visible leaf columns when no position specified', () => { const table = generateTestTableWithData(1, { initialState: { columnVisibility: { age: false, }, }, }) const leafColumns = table_getPinnedVisibleLeafColumns(table) expect(leafColumns.map((col) => col.id)).not.toContain('age') expect(leafColumns.length).toBe(table_getVisibleLeafColumns(table).length) }) }) describe('table_getFooterGroups', () => { it('should return footer groups for left pinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const footerGroups = table_getLeftFooterGroups(table) expect(footerGroups[0]?.headers[0]?.column.id).toBe('firstName') }) it('should return footer groups for right pinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['lastName'], }, }, }) const footerGroups = table_getRightFooterGroups(table) expect(footerGroups[0]?.headers[0]?.column.id).toBe('lastName') }) it('should return footer groups for center columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const footerGroups = table_getCenterFooterGroups(table) const centerColumnIds = footerGroups[0]?.headers.map( (header: Header) => header.column.id, ) expect(centerColumnIds).not.toContain('firstName') expect(centerColumnIds).not.toContain('lastName') expect(footerGroups[0]?.headers.length).toBeGreaterThan(0) }) }) describe('table_getFlatHeaders', () => { it('should return flat headers for left pinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: [], }, }, }) const flatHeaders = table_getLeftFlatHeaders(table) expect(flatHeaders).toHaveLength(1) expect(flatHeaders[0]?.column.id).toBe('firstName') }) it('should return flat headers for right pinned columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: [], right: ['lastName'], }, }, }) const flatHeaders = table_getRightFlatHeaders(table) expect(flatHeaders).toHaveLength(1) expect(flatHeaders[0]?.column.id).toBe('lastName') }) it('should return flat headers for center columns', () => { const table = generateTestTableWithData(1, { initialState: { columnPinning: { left: ['firstName'], right: ['lastName'], }, }, }) const flatHeaders = table_getCenterFlatHeaders(table) const centerColumnIds = flatHeaders.map((header) => header.column.id) expect(centerColumnIds).not.toContain('firstName') expect(centerColumnIds).not.toContain('lastName') expect(flatHeaders.length).toBeGreaterThan(0) }) }) ================================================ FILE: packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts ================================================ import { beforeEach, describe, expect, it, vi } from 'vitest' import { column_getCanResize, column_getIsResizing, getDefaultColumnResizingState, header_getResizeHandler, isTouchStartEvent, passiveEventSupported, table_resetHeaderSizeInfo, table_setColumnResizing, } from '../../../../src' import { generateTestTableWithData } from '../../../helpers/generateTestTable' // Add type for the features we need type TestFeatures = { columnResizingFeature: {} columnSizingFeature: {} } // Helper function to create a properly structured test header function createTestResizeHeader(table: any, overrides = {}) { const baseColumn = { ...table.getAllColumns()[0], id: 'firstName', columnDef: { enableResizing: true, }, table, getLeafColumns: () => [ { ...table.getAllColumns()[0], id: 'firstName', columnDef: { enableResizing: true, }, }, ], } return { column: baseColumn, getLeafHeaders: () => [ { column: baseColumn, getSize: () => 100, subHeaders: [], }, ], subHeaders: [], getSize: () => 100, ...overrides, } } describe('getDefaultColumnResizingState', () => { it('should return default column resizing state', () => { const result = getDefaultColumnResizingState() expect(result).toEqual({ startOffset: null, startSize: null, deltaOffset: null, deltaPercentage: null, isResizingColumn: false, columnSizingStart: [], }) }) }) describe('column_getCanResize', () => { it('should return true when column resizing is enabled', () => { const table = generateTestTableWithData(1) const column = { ...table.getAllColumns()[0], columnDef: {}, table, } const result = column_getCanResize(column) expect(result).toBe(true) }) it('should return false when column resizing is disabled globally', () => { const table = generateTestTableWithData(1, { enableColumnResizing: false, }) const column = { ...table.getAllColumns()[0], columnDef: {}, table, } const result = column_getCanResize(column) expect(result).toBe(false) }) it('should return false when column resizing is disabled for specific column', () => { const table = generateTestTableWithData(1) const column = { ...table.getAllColumns()[0], columnDef: { enableResizing: false }, table, } const result = column_getCanResize(column) expect(result).toBe(false) }) }) describe('column_getIsResizing', () => { it('should return true when column is being resized', () => { const table = generateTestTableWithData(1, { initialState: { columnResizing: { isResizingColumn: 'firstName', columnSizingStart: [], deltaOffset: null, deltaPercentage: null, startOffset: null, startSize: null, }, }, }) const column = { ...table.getAllColumns()[0], id: 'firstName', table, } const result = column_getIsResizing(column) expect(result).toBe(true) }) it('should return false when column is not being resized', () => { const table = generateTestTableWithData(1) const column = { ...table.getAllColumns()[0], table, } const result = column_getIsResizing(column) expect(result).toBe(false) }) }) describe('table_setColumnResizing', () => { it('should call onColumnResizingChange with updater', () => { const onColumnResizingChange = vi.fn() const table = generateTestTableWithData(1, { onColumnResizingChange, }) const newState = { startOffset: 100, startSize: 200, deltaOffset: 50, deltaPercentage: 0.25, isResizingColumn: 'firstName', columnSizingStart: [], } table_setColumnResizing(table, newState) expect(onColumnResizingChange).toHaveBeenCalledWith(newState) }) }) describe('table_resetHeaderSizeInfo', () => { it('should reset to default state when defaultState is true', () => { const onColumnResizingChange = vi.fn() const table = generateTestTableWithData(1, { onColumnResizingChange, }) table_resetHeaderSizeInfo(table, true) expect(onColumnResizingChange).toHaveBeenCalledWith( getDefaultColumnResizingState(), ) }) it('should reset to initial state when defaultState is false', () => { const initialState = { columnResizing: { startOffset: 100, startSize: 200, deltaOffset: 50, deltaPercentage: 0.25, isResizingColumn: 'firstName', columnSizingStart: [], }, } const onColumnResizingChange = vi.fn() const table = generateTestTableWithData(1, { onColumnResizingChange, initialState, }) table_resetHeaderSizeInfo(table, false) expect(onColumnResizingChange).toHaveBeenCalledWith( initialState.columnResizing, ) }) }) describe('isTouchStartEvent', () => { it('should return true for touch start events', () => { const event = { type: 'touchstart' } const result = isTouchStartEvent(event) expect(result).toBe(true) }) it('should return false for non-touch start events', () => { const event = { type: 'mousedown' } const result = isTouchStartEvent(event) expect(result).toBe(false) }) }) describe('header_getResizeHandler', () => { beforeEach(() => { vi.restoreAllMocks() }) it('should return a function', () => { const table = generateTestTableWithData(1, { initialState: { columnSizing: {}, }, }) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) expect(typeof handler).toBe('function') }) it('should not resize when column resizing is disabled', () => { const table = generateTestTableWithData(1, { enableColumnResizing: false, }) const onColumnResizingChange = vi.fn() table.options.onColumnResizingChange = onColumnResizingChange const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) handler({ type: 'mousedown', clientX: 100 }) expect(onColumnResizingChange).not.toHaveBeenCalled() }) it('should ignore multi-touch events', () => { const table = generateTestTableWithData(1) const onColumnResizingChange = vi.fn() table.options.onColumnResizingChange = onColumnResizingChange const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) handler({ type: 'touchstart', touches: [{ clientX: 100 }, { clientX: 200 }], }) expect(onColumnResizingChange).not.toHaveBeenCalled() }) it('should update immediately in onChange mode', () => { const table = generateTestTableWithData(1, { columnResizeMode: 'onChange', }) const onColumnSizingChange = vi.fn() table.options.onColumnSizingChange = onColumnSizingChange const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any) handler({ type: 'mousedown', clientX: 100 }) // Simulate mouse move const moveEvent = new MouseEvent('mousemove', { clientX: 150 }) document.dispatchEvent(moveEvent) expect(onColumnSizingChange).toHaveBeenCalled() }) it('should cleanup event listeners on mouse up', () => { const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener') const table = generateTestTableWithData(1) const header = createTestResizeHeader(table) const handler = header_getResizeHandler(header as any, document) handler({ type: 'mousedown', clientX: 100 }) // Clear the spy calls from setup removeEventListenerSpy.mockClear() // Simulate mouse up const upEvent = new MouseEvent('mouseup', { clientX: 150 }) document.dispatchEvent(upEvent) // Should remove mousemove and mouseup listeners expect(removeEventListenerSpy).toHaveBeenCalledTimes(4) expect(removeEventListenerSpy).toHaveBeenCalledWith( 'mousemove', expect.any(Function), ) expect(removeEventListenerSpy).toHaveBeenCalledWith( 'mouseup', expect.any(Function), ) removeEventListenerSpy.mockRestore() }) }) describe('passiveEventSupported', () => { it('should return boolean indicating passive event support', () => { const result = passiveEventSupported() expect(typeof result).toBe('boolean') }) it('should cache the result of passive support check', () => { const firstResult = passiveEventSupported() const secondResult = passiveEventSupported() expect(firstResult).toBe(secondResult) }) it('should handle errors during support check', () => { const addEventListenerSpy = vi.spyOn(window, 'addEventListener') addEventListenerSpy.mockImplementation(() => { throw new Error('Test error') }) const result = passiveEventSupported() expect(result).toBe(false) addEventListenerSpy.mockRestore() }) }) ================================================ FILE: packages/table-core/tests/unit/features/column-visibility/columnVisibilityFeature.utils.test.ts ================================================ import { describe, expect, it, vi } from 'vitest' import { columnVisibilityFeature, column_getCanHide, column_getIsVisible, column_getToggleVisibilityHandler, column_toggleVisibility, coreFeatures, getDefaultColumnVisibilityState, row_getAllVisibleCells, row_getVisibleCells, tableFeatures, table_getIsAllColumnsVisible, table_getIsSomeColumnsVisible, table_getToggleAllColumnsVisibilityHandler, table_getVisibleFlatColumns, table_getVisibleLeafColumns, table_resetColumnVisibility, table_setColumnVisibility, table_toggleAllColumnsVisible, } from '../../../../src' import { generateTestTableWithData } from '../../../helpers/generateTestTable' import { getUpdaterResult } from '../../../helpers/testUtils' import type { Column } from '../../../../src' const _features = tableFeatures({ ...coreFeatures, columnVisibilityFeature, }) describe('columnVisibilityFeature.utils', () => { describe('getDefaultColumnVisibilityState', () => { it('should return empty object', () => { const result = getDefaultColumnVisibilityState() expect(result).toEqual({}) }) }) describe('column_getIsVisible', () => { it('should return true by default', () => { const table = generateTestTableWithData(1, { _features }) const column = table.getAllColumns()[0]! const result = column_getIsVisible(column) expect(result).toBe(true) }) it('should return false when column is hidden', () => { const table = generateTestTableWithData(1, { _features, initialState: { columnVisibility: { firstName: false, }, }, }) const column = { ...table.getAllColumns()[0]!, id: 'firstName', table, } const result = column_getIsVisible(column) expect(result).toBe(false) }) it('should return true if any child column is visible', () => { const table = generateTestTableWithData(1, { _features }) const baseColumn = table.getAllColumns()[0]! const parentColumn = { ...baseColumn, columns: [ { ...baseColumn, id: 'child1', columns: [], table }, { ...table.getAllColumns()[1]!, id: 'child2', columns: [], table }, ], } const result = column_getIsVisible(parentColumn) expect(result).toBe(true) }) }) describe('column_getCanHide', () => { it('should return true by default', () => { const table = generateTestTableWithData(1, { _features }) const column = table.getAllColumns()[0]! const result = column_getCanHide(column) expect(result).toBe(true) }) it('should return false when hiding is disabled globally', () => { const table = generateTestTableWithData(1, { enableHiding: false, _features, }) const column = table.getAllColumns()[0]! const result = column_getCanHide(column) expect(result).toBe(false) }) it('should return false when hiding is disabled for column', () => { const table = generateTestTableWithData(1, { _features }) const column = { ...table.getAllColumns()[0]!, columnDef: { enableHiding: false }, } const result = column_getCanHide(column) expect(result).toBe(false) }) }) describe('column_toggleVisibility', () => { it('should toggle column visibility', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) const column = { ...table.getAllColumns()[0]!, id: 'firstName', table, } column_toggleVisibility(column) const result = getUpdaterResult(onColumnVisibilityChange, {}) expect(result).toEqual({ firstName: false }) }) it('should set specific visibility when provided', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) const column = { ...table.getAllColumns()[0]!, id: 'firstName', table, } column_toggleVisibility(column, true) const result = getUpdaterResult(onColumnVisibilityChange, {}) expect(result).toEqual({ firstName: true }) }) it('should not toggle when column cannot be hidden', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { enableHiding: false, _features, onColumnVisibilityChange, }) const column = { ...table.getAllColumns()[0]!, id: 'firstName', table, } column_toggleVisibility(column) expect(onColumnVisibilityChange).not.toHaveBeenCalled() }) }) describe('column_getToggleVisibilityHandler', () => { it('should return handler that toggles visibility based on checkbox state', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) const column = { ...table.getAllColumns()[0]!, id: 'firstName', table, } const handler = column_getToggleVisibilityHandler(column) handler({ target: { checked: true } } as any) const result = getUpdaterResult(onColumnVisibilityChange, {}) expect(result).toEqual({ firstName: true }) }) }) describe('row_getAllVisibleCells', () => { it('should return only visible cells', () => { const table = generateTestTableWithData(1, { _features, initialState: { columnVisibility: { firstName: false, }, }, }) const row = table.getRowModel().rows[0]! const visibleCells = row_getAllVisibleCells(row) const visibleColumnIds = visibleCells.map((cell) => cell.column.id) expect(visibleColumnIds).not.toContain('firstName') expect(visibleCells.length).toBe(row.getAllCells().length - 1) }) }) describe('row_getVisibleCells', () => { it('should combine left, center and right cells', () => { const leftCells = [{ id: 'left' }] const centerCells = [{ id: 'center' }] const rightCells = [{ id: 'right' }] const result = row_getVisibleCells( leftCells as any, centerCells as any, rightCells as any, ) expect(result).toEqual([...leftCells, ...centerCells, ...rightCells]) }) }) describe('table_getVisibleFlatColumns', () => { it('should return only visible flat columns', () => { const table = generateTestTableWithData(1, { _features, initialState: { columnVisibility: { firstName: false, }, }, }) const visibleColumns = table_getVisibleFlatColumns(table) const visibleColumnIds = visibleColumns.map((col) => col.id) expect(visibleColumnIds).not.toContain('firstName') expect(visibleColumns.length).toBe(table.getAllFlatColumns().length - 1) }) }) describe('table_getVisibleLeafColumns', () => { it('should return only visible leaf columns', () => { const table = generateTestTableWithData(1, { _features, initialState: { columnVisibility: { firstName: false, }, }, }) const visibleColumns = table_getVisibleLeafColumns(table) const visibleColumnIds = visibleColumns.map((col) => col.id) expect(visibleColumnIds).not.toContain('firstName') expect(visibleColumns.length).toBe(table.getAllLeafColumns().length - 1) }) }) describe('table_setColumnVisibility', () => { it('should call onColumnVisibilityChange with updater', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) table_setColumnVisibility(table, { firstName: false }) expect(onColumnVisibilityChange).toHaveBeenCalledWith({ firstName: false, }) }) }) describe('table_resetColumnVisibility', () => { it('should reset to empty state when defaultState is true', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) table_resetColumnVisibility(table, true) expect(onColumnVisibilityChange).toHaveBeenCalledWith({}) }) it('should reset to initial state when defaultState is false', () => { const initialState = { columnVisibility: { firstName: false } } const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, initialState, onColumnVisibilityChange, }) table_resetColumnVisibility(table, false) expect(onColumnVisibilityChange).toHaveBeenCalledWith({ firstName: false, }) }) }) describe('table_toggleAllColumnsVisible', () => { it('should show all columns when value is true', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) table_toggleAllColumnsVisible(table, true) expect(onColumnVisibilityChange).toHaveBeenCalled() const result = onColumnVisibilityChange.mock.calls[0]?.[0] const allColumnIds = table .getAllLeafColumns() .map((col: Column) => col.id) expect(Object.entries(result)).toEqual( allColumnIds.map((id: string) => [id, true]), ) }) it('should hide all columns that can be hidden when value is false', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) table_toggleAllColumnsVisible(table, false) expect(onColumnVisibilityChange).toHaveBeenCalled() const result = onColumnVisibilityChange.mock.calls[0]?.[0] const allColumnIds = table .getAllLeafColumns() .map((col: Column) => col.id) expect(Object.entries(result)).toEqual( allColumnIds.map((id: string) => [id, false]), ) }) }) describe('table_getIsAllColumnsVisible', () => { it('should return true when all columns are visible', () => { const table = generateTestTableWithData(1, { _features }) const result = table_getIsAllColumnsVisible(table) expect(result).toBe(true) }) it('should return false when some columns are hidden', () => { const table = generateTestTableWithData(1, { initialState: { columnVisibility: { firstName: false, }, }, }) const result = table_getIsAllColumnsVisible(table) expect(result).toBe(false) }) }) describe('table_getIsSomeColumnsVisible', () => { it('should return true when some columns are visible', () => { const table = generateTestTableWithData(1, { _features, initialState: { columnVisibility: { firstName: false, }, }, }) const result = table_getIsSomeColumnsVisible(table) expect(result).toBe(true) }) it('should return false when no columns are visible', () => { const table = generateTestTableWithData(1, { _features }) const allColumnIds = table .getAllLeafColumns() .map((col: Column) => col.id) const hideAllColumns = Object.fromEntries( allColumnIds.map((id: string) => [id, false]), ) const tableWithHiddenColumns = generateTestTableWithData(1, { _features, initialState: { columnVisibility: hideAllColumns, }, }) const result = table_getIsSomeColumnsVisible(tableWithHiddenColumns) expect(result).toBe(false) }) }) describe('table_getToggleAllColumnsVisibilityHandler', () => { it('should return handler that toggles all columns visibility based on checkbox state', () => { const onColumnVisibilityChange = vi.fn() const table = generateTestTableWithData(1, { _features, onColumnVisibilityChange, }) const handler = table_getToggleAllColumnsVisibilityHandler(table) handler({ target: { checked: true } } as any) expect(onColumnVisibilityChange).toHaveBeenCalled() const result = onColumnVisibilityChange.mock.calls[0]?.[0] const allColumnIds = table .getAllLeafColumns() .map((col: Column) => col.id) expect(Object.entries(result)).toEqual( allColumnIds.map((id: string) => [id, true]), ) }) }) }) ================================================ FILE: packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts ================================================ import { describe, expect, it, vi } from 'vitest' import { getDefaultRowPinningState, row_getCanPin, row_getIsPinned, row_getPinnedIndex, row_pin, table_getBottomRows, table_getCenterRows, table_getIsSomeRowsPinned, table_getTopRows, table_resetRowPinning, table_setRowPinning, } from '../../../../src/features/row-pinning/rowPinningFeature.utils' import { generateTestTableWithData } from '../../../helpers/generateTestTable' import { getUpdaterResult } from '../../../helpers/testUtils' import { createTableWithMockOnPinningChange, createTableWithPinningState, } from '../../../helpers/rowPinningHelpers' import type { Row } from '../../../../src' import type { Person } from '../../../fixtures/data/types' const DEFAULT_ROW_COUNT = 10 const ROW = { 0: '0', 1: '1', 2: '2', 8: '8', 9: '9', } as const const LEAF = { 1: 'leaf1', 2: 'leaf2', } as const const PARENT = { 1: 'parent1', 2: 'parent2', } as const const EMPTY_PINNING_STATE = { top: [], bottom: [], } describe('getDefaultRowPinningState', () => { it('should return default row pinning state with empty top and bottom arrays', () => { const defaultState = getDefaultRowPinningState() expect(defaultState).toEqual({ top: [], bottom: [], }) // Ensure we get a new object instance each time const secondState = getDefaultRowPinningState() expect(secondState).toEqual(defaultState) expect(secondState).not.toBe(defaultState) }) }) describe('table_setRowPinning', () => { it('should call onRowPinningChange with the updater function', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const newState = { top: [ROW[1]], bottom: [ROW[2]], } table_setRowPinning(table, newState) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect(onRowPinningChangeMock).toHaveBeenCalledWith(newState) }) it('should handle undefined onRowPinningChange without error', () => { const table = generateTestTableWithData(DEFAULT_ROW_COUNT) expect(() => { table_setRowPinning(table, EMPTY_PINNING_STATE) }).not.toThrow() }) }) describe('table_resetRowPinning', () => { it('should reset to default state when defaultState is true', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() table_resetRowPinning(table, true) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect(onRowPinningChangeMock).toHaveBeenCalledWith( getDefaultRowPinningState(), ) }) it('should reset to initial state when defaultState is false', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const initialState = { top: [ROW[1]], bottom: [ROW[2]], } table.initialState.rowPinning = initialState table_resetRowPinning(table, false) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect(onRowPinningChangeMock).toHaveBeenCalledWith(initialState) }) it('should reset to default state when no initial state exists', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() table_resetRowPinning(table, false) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect(onRowPinningChangeMock).toHaveBeenCalledWith( getDefaultRowPinningState(), ) }) }) describe('table_getIsSomeRowsPinned', () => { it('should return false when no rows are pinned', () => { const table = createTableWithPinningState() expect(table_getIsSomeRowsPinned(table)).toBe(false) expect(table_getIsSomeRowsPinned(table, 'top')).toBe(false) expect(table_getIsSomeRowsPinned(table, 'bottom')).toBe(false) }) it('should return true when rows are pinned to top', () => { const table = createTableWithPinningState(10, { top: [ROW[0]], bottom: [], }) expect(table_getIsSomeRowsPinned(table)).toBe(true) expect(table_getIsSomeRowsPinned(table, 'top')).toBe(true) expect(table_getIsSomeRowsPinned(table, 'bottom')).toBe(false) }) it('should return true when rows are pinned to bottom', () => { const table = createTableWithPinningState(10, { top: [], bottom: [ROW[0]], }) expect(table_getIsSomeRowsPinned(table)).toBe(true) expect(table_getIsSomeRowsPinned(table, 'top')).toBe(false) expect(table_getIsSomeRowsPinned(table, 'bottom')).toBe(true) }) it('should handle undefined state', () => { const table = generateTestTableWithData(10) expect(table_getIsSomeRowsPinned(table)).toBe(false) expect(table_getIsSomeRowsPinned(table, 'top')).toBe(false) expect(table_getIsSomeRowsPinned(table, 'bottom')).toBe(false) }) }) describe('table_getTopRows and table_getBottomRows', () => { it('should return empty arrays when no rows are pinned', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: getDefaultRowPinningState(), }, }) expect(table_getTopRows(table)).toEqual([]) expect(table_getBottomRows(table)).toEqual([]) }) it('should return pinned rows with position property', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: { top: [ROW[0]], bottom: [ROW[1]], }, }, }) const row0 = table.getRow('0', true) const row1 = table.getRow('1', true) const topRows = table_getTopRows(table) const bottomRows = table_getBottomRows(table) expect(topRows).toHaveLength(1) expect(topRows[0]).toEqual({ ...row0, position: 'top' }) expect(bottomRows).toHaveLength(1) expect(bottomRows[0]).toEqual({ ...row1, position: 'bottom' }) }) it('should handle keepPinnedRows=false by only returning visible rows', () => { const table = generateTestTableWithData(10, { keepPinnedRows: false, initialState: { rowPinning: { top: [ROW[0], ROW[8]], // '0' is visible, '8' is not bottom: [ROW[1], ROW[9]], // '1' is visible, '9' is not }, }, }) // Setup a row model with only some rows visible const visibleRows = table.getRowModel().rows.slice(0, 5) vi.spyOn(table, 'getRowModel').mockReturnValue({ rows: visibleRows, flatRows: [], rowsById: {}, }) const topRows = table_getTopRows(table) const bottomRows = table_getBottomRows(table) expect(topRows).toHaveLength(1) expect(topRows[0]?.id).toBe(ROW[0]) expect(bottomRows).toHaveLength(1) expect(bottomRows[0]?.id).toBe(ROW[1]) }) it('should handle keepPinnedRows=true by returning all pinned rows regardless of visibility', () => { const table = generateTestTableWithData(10, { keepPinnedRows: true, initialState: { rowPinning: { top: [ROW[0], ROW[8]], // '0' is visible, '8' is not bottom: [ROW[1], ROW[9]], // '1' is visible, '9' is not }, }, }) // Setup a row model with only some rows visible const visibleRows = table.getRowModel().rows.slice(0, 5) vi.spyOn(table, 'getRowModel').mockReturnValue({ rows: visibleRows, flatRows: [], rowsById: {}, }) const topRows = table_getTopRows(table) const bottomRows = table_getBottomRows(table) expect(topRows).toHaveLength(2) expect(topRows.map((r) => r.id)).toEqual([ROW[0], ROW[8]]) expect(bottomRows).toHaveLength(2) expect(bottomRows.map((r) => r.id)).toEqual([ROW[1], ROW[9]]) }) it('should handle undefined state', () => { const table = generateTestTableWithData(10) expect(table_getTopRows(table)).toEqual([]) expect(table_getBottomRows(table)).toEqual([]) }) }) describe('table_getCenterRows', () => { it('should return all rows when no rows are pinned', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: getDefaultRowPinningState(), }, }) const allRows = table.getRowModel().rows const centerRows = table_getCenterRows(table) expect(centerRows).toEqual(allRows) }) it('should return only unpinned rows when some rows are pinned', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: { top: [ROW[0], ROW[1]], bottom: [ROW[8], ROW[9]], }, }, }) const allRows = table.getRowModel().rows const centerRows = table_getCenterRows(table) expect(centerRows).toEqual(allRows.slice(2, 8)) const rowIds = [ROW[0], ROW[1], ROW[8], ROW[9]] as Array expect(centerRows.every((row) => !rowIds.includes(row.id))).toBe(true) }) it('should handle undefined state', () => { const table = generateTestTableWithData(10) const allRows = table.getRowModel().rows const centerRows = table_getCenterRows(table) expect(centerRows).toEqual(allRows) }) }) describe('row_getCanPin', () => { it('should return true when enableRowPinning is undefined', () => { const table = generateTestTableWithData(10) const row = table.getRow('0') expect(row_getCanPin(row)).toBe(true) }) it('should return false when enableRowPinning is false', () => { const table = generateTestTableWithData(10) table.options.enableRowPinning = false const row = table.getRow('0') expect(row_getCanPin(row)).toBe(false) }) it('should return true when enableRowPinning is true', () => { const table = generateTestTableWithData(10) table.options.enableRowPinning = true const row = table.getRow('0') expect(row_getCanPin(row)).toBe(true) }) it('should use enableRowPinning function when provided', () => { const enableRowPinning = vi.fn((row) => row.id === '1') const table = generateTestTableWithData(10) table.options.enableRowPinning = enableRowPinning const row0 = table.getRow('0') const row1 = table.getRow('1') expect(row_getCanPin(row0)).toBe(false) expect(row_getCanPin(row1)).toBe(true) expect(enableRowPinning).toHaveBeenCalledTimes(2) }) }) describe('row_getIsPinned', () => { it('should return false when no rows are pinned', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: getDefaultRowPinningState(), }, }) const row = table.getRow('0') expect(row_getIsPinned(row)).toBe(false) }) it('should return "top" when row is pinned to top', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: { top: [ROW[0]], bottom: [], }, }, }) const row = table.getRow('0') expect(row_getIsPinned(row)).toBe('top') }) it('should return "bottom" when row is pinned to bottom', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: { top: [], bottom: [ROW[0]], }, }, }) const row = table.getRow('0') expect(row_getIsPinned(row)).toBe('bottom') }) it('should handle undefined state', () => { const table = generateTestTableWithData(10) const row = table.getRow('0') expect(row_getIsPinned(row)).toBe(false) }) }) describe('row_getPinnedIndex', () => { it('should return -1 when row is not pinned', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: getDefaultRowPinningState(), }, }) const row = table.getRow('0') expect(row_getPinnedIndex(row)).toBe(-1) }) it('should return correct index for top pinned rows', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: { top: [ROW[0], ROW[1], ROW[2]], bottom: [], }, }, }) expect(row_getPinnedIndex(table.getRow('0'))).toBe(0) expect(row_getPinnedIndex(table.getRow('1'))).toBe(1) expect(row_getPinnedIndex(table.getRow('2'))).toBe(2) }) it('should return correct index for bottom pinned rows', () => { const table = generateTestTableWithData(10, { initialState: { rowPinning: { top: [], bottom: [ROW[0], ROW[1], ROW[2]], }, }, }) expect(row_getPinnedIndex(table.getRow('0'))).toBe(0) expect(row_getPinnedIndex(table.getRow('1'))).toBe(1) expect(row_getPinnedIndex(table.getRow('2'))).toBe(2) }) it('should handle undefined state', () => { const table = generateTestTableWithData(10) const row = table.getRow('0') expect(row_getPinnedIndex(row)).toBe(-1) }) }) describe('row_pin', () => { it('should pin a row to top', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const row = table.getRow('0') row_pin(row, 'top') expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [], bottom: [] }), ).toEqual({ top: [ROW[0]], bottom: [], }) }) it('should pin a row to bottom', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const row = table.getRow('0') row_pin(row, 'bottom') expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [], bottom: [] }), ).toEqual({ top: [], bottom: [ROW[0]], }) }) it('should unpin a row when position is false', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() table.baseStore.setState(() => ({ rowPinning: { top: [ROW[0]], bottom: [], }, })) const row = table.getRow('0') row_pin(row, false) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [ROW[0]], bottom: [] }), ).toEqual({ top: [], bottom: [], }) }) it('should include leaf rows when includeLeafRows is true', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const row = table.getRow('0') const leafRows = [{ id: LEAF[1] }, { id: LEAF[2] }] vi.spyOn(row, 'getLeafRows').mockReturnValue( leafRows as unknown as Array>, ) row_pin(row, 'top', true) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [], bottom: [] }), ).toEqual({ top: [ROW[0], LEAF[1], LEAF[2]], bottom: [], }) }) it('should include parent rows when includeParentRows is true', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() const row = table.getRow('0') const parentRows = [{ id: PARENT[1] }, { id: PARENT[2] }] vi.spyOn(row, 'getParentRows').mockReturnValue( parentRows as unknown as Array>, ) row_pin(row, 'top', false, true) expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [], bottom: [] }), ).toEqual({ top: [PARENT[1], PARENT[2], ROW[0]], bottom: [], }) }) it('should maintain existing pinned rows when pinning additional rows', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() table.baseStore.setState(() => ({ rowPinning: { top: [ROW[1]], bottom: [ROW[2]], }, })) const row = table.getRow('0') row_pin(row, 'top') expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [ROW[1]], bottom: [ROW[2]], }), ).toEqual({ top: [ROW[1], ROW[0]], bottom: [ROW[2]], }) }) it('should remove row from other position when moving between top and bottom', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() table.baseStore.setState(() => ({ rowPinning: { top: [ROW[0]], bottom: [], }, })) const row = table.getRow('0') row_pin(row, 'bottom') expect(onRowPinningChangeMock).toHaveBeenCalledTimes(1) expect( getUpdaterResult(onRowPinningChangeMock, { top: [ROW[0]], bottom: [] }), ).toEqual({ top: [], bottom: [ROW[0]], }) }) }) ================================================ FILE: packages/table-core/tests/unit/fns/filterFns.test.ts ================================================ import { describe, expect, it } from 'vitest' import { generateTestRowsWithStateFromData } from '../../helpers/generateTestRows' import { columnFilteringFeature, filterFn_equals, filterFn_equalsString, filterFn_equalsStringSensitive, filterFn_greaterThan, filterFn_greaterThanOrEqualTo, filterFn_includesString, filterFn_includesStringSensitive, filterFn_lessThan, filterFn_lessThanOrEqualTo, filterFn_weakEquals, } from '../../../src' import { getStaticTestData } from '../../fixtures/data/generateTestData' // TODO - fix _features not being inferred correctly const mockRows = generateTestRowsWithStateFromData(getStaticTestData(), { _features: { columnFilteringFeature, }, }) describe('Filter Functions', () => { describe('Basic Filters', () => { describe('filterFn_equals', () => { it('should match exact values', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'John' const result = filterFn_equals(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match values with type coercion (e.g., "1" == 1)', () => { const row = mockRows[0]! const columnId = 'id' const filterValue = 1 // number instead of string const result = filterFn_equals(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should handle null/undefined values', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = null const result = filterFn_equals(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should correctly identify non-matches', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'Jane' const result = filterFn_equals(row as any, columnId, filterValue) expect(result).toBe(false) }) }) describe('filterFn_weakEquals', () => { it('should match exact values', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'John' const result = filterFn_weakEquals(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should match values with type coercion (e.g., "1" == 1)', () => { const row = mockRows[0]! const columnId = 'id' const filterValue = 1 // number instead of string const result = filterFn_weakEquals(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should handle null/undefined values', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = null const result = filterFn_weakEquals(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should correctly identify non-matches', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'Jane' const result = filterFn_weakEquals(row as any, columnId, filterValue) expect(result).toBe(false) }) }) }) describe('String Filters', () => { describe('filterFn_includesStringSensitive', () => { it('should match case-sensitive substrings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'John' const result = filterFn_includesStringSensitive( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match different case substrings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'john' // lowercase const result = filterFn_includesStringSensitive( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should handle partial matches', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'ohn' const result = filterFn_includesStringSensitive( row as any, columnId, filterValue, ) expect(result).toBe(true) }) }) describe('filterFn_includesString', () => { it('should match case-insensitive substrings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'John' const result = filterFn_includesString( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should match different case substrings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'john' // lowercase const result = filterFn_includesString( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should handle partial matches', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'ohn' const result = filterFn_includesString( row as any, columnId, filterValue, ) expect(result).toBe(true) }) }) describe('filterFn_equalsString', () => { it('should match exact strings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'John' const result = filterFn_equalsString(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should match case-insensitive exact strings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'john' // lowercase const result = filterFn_equalsString(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match partial strings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'ohn' const result = filterFn_equalsString(row as any, columnId, filterValue) expect(result).toBe(false) }) }) describe('filterFn_equalsStringSensitive', () => { it('should match case-sensitive exact strings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'John' const result = filterFn_equalsStringSensitive( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match case-insensitive exact strings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'john' const result = filterFn_equalsStringSensitive( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should not match partial strings', () => { const row = mockRows[0]! const columnId = 'firstName' const filterValue = 'ohn' const result = filterFn_equalsStringSensitive( row as any, columnId, filterValue, ) expect(result).toBe(false) }) }) }) describe('Number Filters', () => { describe('filterFn_greaterThan', () => { it('should match greater than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 29 const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match equal values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 30 const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should not match less than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 31 const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should match strings greater than numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '29' const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match strings less than numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '31' const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should match strings greater than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'a' const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match strings less than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'z' const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should not match strings equal to other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'John' const result = filterFn_greaterThan(row as any, columnId, filterValue) expect(result).toBe(false) }) }) describe('filterFn_greaterThanOrEqualTo', () => { it('should match greater than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 29 const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should match equal values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 30 const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match less than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 31 const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should match strings greater than to numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '29' const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match strings less than numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '31' const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should match strings greater than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'a' const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match strings less than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'z' const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should match strings equal to other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'John' const result = filterFn_greaterThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) }) describe('filterFn_lessThan', () => { it('should match less than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 31 const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match equal values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 30 const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should not match greater than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 29 const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should match strings less than numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '31' const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should match strings less than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'z' const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(true) }) it('should not match strings equal to other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'John' const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(false) }) it('should not match strings greater than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'a' const result = filterFn_lessThan(row as any, columnId, filterValue) expect(result).toBe(false) }) }) describe('filterFn_lessThanOrEqualTo', () => { it('should match less than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 31 const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should match equal values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 30 const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match greater than values', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = 29 const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should match strings less than to numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '31' const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match strings greater than numbers', () => { const row = mockRows[0]! const columnId = 'age' // number value 30 const filterValue = '29' const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should match strings less than to other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'z' const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) it('should not match strings greater than other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'a' const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(false) }) it('should match strings equal to other strings', () => { const row = mockRows[0]! const columnId = 'firstName' // 'John' const filterValue = 'John' const result = filterFn_lessThanOrEqualTo( row as any, columnId, filterValue, ) expect(result).toBe(true) }) }) }) }) ================================================ FILE: packages/table-core/tests/unit/utils.test.ts ================================================ import { describe, expect, it } from 'vitest' import { getFunctionNameInfo } from '../../src/utils' // TODO: add unit tests for rest of utils describe('utils', () => { describe('getFunctionNameInfo', () => { it('should correctly parse a function name with underscore separator', () => { const result = getFunctionNameInfo('table_getRowModel') expect(result).toEqual({ parentName: 'table', fnKey: 'getRowModel', fnName: 'table.getRowModel', }) }) it('should handle different parent names', () => { const result = getFunctionNameInfo('column_getWidth') expect(result).toEqual({ parentName: 'column', fnKey: 'getWidth', fnName: 'column.getWidth', }) }) }) }) ================================================ FILE: packages/table-core/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "include": ["src", "eslint.config.js", "vite.config.ts", "tests"] } ================================================ FILE: packages/table-core/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ test: { name: packageJson.name, dir: './', watch: false, environment: 'jsdom', setupFiles: ['./tests/fixtures/setup/test-setup.ts'], globals: true, }, }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: './src/index.ts', srcDir: './src', }), ) ================================================ FILE: packages/table-devtools/eslint.config.js ================================================ // @ts-check import rootConfig from '../../eslint.config.js' /** @type {any} */ const config = [ ...rootConfig, { rules: {}, }, ] export default config ================================================ FILE: packages/table-devtools/package.json ================================================ { "name": "@tanstack/table-devtools", "version": "9.0.0-alpha.11", "description": "Devtools for TanStack Table.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/table-devtools" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "tanstack", "table", "devtools" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "lint:fix": "eslint ./src --fix", "test:eslint": "eslint ./src", "test:lib": "vitest --passWithNoTests", "test:lib:dev": "pnpm test:lib --watch", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "type": "module", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./production": { "import": { "types": "./dist/esm/production.d.ts", "default": "./dist/esm/production.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "dependencies": { "@tanstack/devtools-ui": "^0.5.0", "@tanstack/devtools-utils": "^0.3.2", "@tanstack/solid-store": "^0.9.2", "goober": "^2.1.18", "solid-js": "^1.9.11" }, "peerDependencies": { "@tanstack/table-core": "workspace:*" }, "devDependencies": { "vite-plugin-solid": "^2.11.10" } } ================================================ FILE: packages/table-devtools/src/TableContextProvider.tsx ================================================ import { createContext, createEffect, createSignal, onCleanup, useContext, } from 'solid-js' import { getTableDevtoolsTarget, subscribeTableDevtoolsTarget, } from './tableTarget' import type { Accessor, ParentComponent, Setter } from 'solid-js' import type { RowData, Table, stockFeatures } from '@tanstack/table-core' type TableDevtoolsTabId = 'features' | 'state' | 'options' | 'rows' | 'columns' type AnyTable = Table interface TableDevtoolsContextValue { table: Accessor activeTab: Accessor setActiveTab: Setter } const TableDevtoolsContext = createContext< TableDevtoolsContextValue | undefined >(undefined) export const TableContextProvider: ParentComponent = (props) => { const [table, setTable] = createSignal( getTableDevtoolsTarget(), ) const [activeTab, setActiveTab] = createSignal('features') createEffect(() => { const unsubscribe = subscribeTableDevtoolsTarget((nextTable) => { setTable(nextTable) }) onCleanup(unsubscribe) }) return ( {props.children} ) } export function useTableDevtoolsContext() { const context = useContext(TableDevtoolsContext) if (!context) { throw new Error( 'useTableDevtoolsContext must be used within TableContextProvider', ) } return context } ================================================ FILE: packages/table-devtools/src/TableDevtools.tsx ================================================ import { TableContextProvider } from './TableContextProvider' import { Shell } from './components/Shell' export default function TableDevtools() { return ( ) } ================================================ FILE: packages/table-devtools/src/components/ColumnsPanel.tsx ================================================ import { For } from 'solid-js' import { useTableDevtoolsContext } from '../TableContextProvider' import { useTableStore } from '../useTableStore' import { useStyles } from '../styles/use-styles' import type { Column, RowData, TableFeatures } from '@tanstack/table-core' type AnyColumn = Column function getColumnDefSummary(column: AnyColumn): string { const def = column.columnDef as Record const header = def.header const accessorKey = def.accessorKey const accessorFn = def.accessorFn const parts: Array = [] if (typeof accessorKey === 'string') parts.push(`key: ${accessorKey}`) if (typeof accessorFn === 'function') parts.push('accessorFn') if (header !== undefined) { const headerStr = typeof header === 'string' ? header : typeof header === 'function' ? '[fn]' : String(header) parts.push(`header: ${headerStr}`) } return parts.length > 0 ? parts.join(', ') : '-' } export function ColumnsPanel() { const styles = useStyles() const { table } = useTableDevtoolsContext() const tableInstance = table() const tableState = useTableStore( tableInstance ? tableInstance.store : undefined, (state) => state, ) const getColumns = (): Array => { tableState?.() if (!tableInstance) return [] const tableWithColumnFns = tableInstance as unknown as { getAllFlatColumns?: () => Array getAllLeafColumns?: () => Array } return ( tableWithColumnFns.getAllFlatColumns?.() ?? tableWithColumnFns.getAllLeafColumns?.() ?? [] ) } const columns = getColumns() if (!tableInstance) { return (
Columns
No table instance is connected. Pass a table instance to TableDevtoolsPanel.
) } return (
Columns ({columns.length})
{(column, index) => ( )}
# id depth accessor columnDef
{index() + 1} {column.id} {column.depth} {column.accessorFn ? '✓' : '○'} {getColumnDefSummary(column)}
) } ================================================ FILE: packages/table-devtools/src/components/FeaturesPanel.tsx ================================================ import { For } from 'solid-js' import { coreFeatures, stockFeatures } from '@tanstack/table-core' import { useTableDevtoolsContext } from '../TableContextProvider' import { useTableStore } from '../useTableStore' import { useStyles } from '../styles/use-styles' import { ResizableSplit } from './ResizableSplit' type FnBuckets = Partial< Record<'filterFns' | 'sortFns' | 'aggregationFns', Record> > function toFnBuckets(value: unknown): FnBuckets { return typeof value === 'object' && value != null ? (value as FnBuckets) : {} } const CORE_FEATURE_NAMES: Array = Object.keys(coreFeatures) const STOCK_FEATURE_NAMES: Array = Object.keys(stockFeatures) const ROW_MODEL_TO_FN_KIND: Record< string, 'filterFns' | 'sortFns' | 'aggregationFns' | null > = { filteredRowModel: 'filterFns', preFilteredRowModel: 'filterFns', sortedRowModel: 'sortFns', preSortedRowModel: 'sortFns', groupedRowModel: 'aggregationFns', preGroupedRowModel: 'aggregationFns', } const EXECUTION_ORDER_GETTERS = [ 'getCoreRowModel', 'getFilteredRowModel', 'getGroupedRowModel', 'getSortedRowModel', 'getExpandedRowModel', 'getPaginatedRowModel', 'getRowModel', ] as const function getterToRowModelKey(getter: string): string | null { if (getter === 'getRowModel') return 'paginatedRowModel' const withoutGet = getter.slice(3) return withoutGet.charAt(0).toLowerCase() + withoutGet.slice(1) } const ROW_MODEL_TO_GETTER: Record< string, (typeof EXECUTION_ORDER_GETTERS)[number] > = { coreRowModel: 'getCoreRowModel', filteredRowModel: 'getFilteredRowModel', preFilteredRowModel: 'getFilteredRowModel', groupedRowModel: 'getGroupedRowModel', preGroupedRowModel: 'getGroupedRowModel', sortedRowModel: 'getSortedRowModel', preSortedRowModel: 'getSortedRowModel', expandedRowModel: 'getExpandedRowModel', paginatedRowModel: 'getRowModel', } function getRowCountForModel( tableInstance: { [key: string]: unknown } | undefined, rowModelName: string, ): number { const getter = ROW_MODEL_TO_GETTER[rowModelName] if (!getter || typeof tableInstance?.[getter] !== 'function') return 0 const result = (tableInstance[getter] as () => { rows?: Array })() return result?.rows?.length ?? 0 } export function FeaturesPanel() { const styles = useStyles() const { table } = useTableDevtoolsContext() const tableInstance = table() const tableState = useTableStore( tableInstance ? tableInstance.store : undefined, (state) => state, ) const getTableFeatures = (): Set => { tableState?.() return new Set(Object.keys(tableInstance?._features ?? {})) } const getRowModelNames = (): Array => { tableState?.() return Object.keys(tableInstance?.options._rowModels ?? {}) } const getFnNames = ( kind: 'filterFns' | 'sortFns' | 'aggregationFns', ): Array => { tableState?.() const rowModelFns = toFnBuckets(tableInstance?._rowModelFns) const optionFns = toFnBuckets(tableInstance?.options) return Object.keys(rowModelFns[kind] ?? optionFns[kind] ?? {}) } const getAdditionalPlugins = (): Array => { const tableFeatures = getTableFeatures() const knownFeatures = new Set([ ...CORE_FEATURE_NAMES, ...STOCK_FEATURE_NAMES, ]) return [...tableFeatures].filter((f) => !knownFeatures.has(f)).sort() } const getRowModelFunctions = (rowModelName: string): Array => { const fnKind = ROW_MODEL_TO_FN_KIND[rowModelName] if (!fnKind) return [] return getFnNames(fnKind) } const tableFeatures = getTableFeatures() const rowModelNames = getRowModelNames() return (
Features
Core Features
{(name) => (
{tableFeatures.has(name) ? '✓' : '○'} {name}
)}
Stock Features
{(name) => (
{tableFeatures.has(name) ? '✓' : '○'} {name}
)}
{getAdditionalPlugins().length > 0 && (
Additional Plugins
{(name) => (
{name}
)}
)} } right={ <>
Client Side Row Models and Fns
{(rowModelName) => { const fns = getRowModelFunctions(rowModelName) return (
{rowModelName}
{(fnName) => (
{fnName}
)}
) }}
{rowModelNames.length === 0 && (
No row models configured
)}
Execution Order
{(getter, index) => { const rowModelKey = getterToRowModelKey(getter) const isPresent = rowModelKey !== null && rowModelNames.includes(rowModelKey) return ( <> {index() > 0 && ' → '} {getter} ) }}
} />
) } ================================================ FILE: packages/table-devtools/src/components/OptionsPanel.tsx ================================================ import { JsonTree } from '@tanstack/devtools-ui' import { useStore } from '@tanstack/solid-store' import { useTableDevtoolsContext } from '../TableContextProvider' import { useStyles } from '../styles/use-styles' import { ResizableSplit } from './ResizableSplit' export function OptionsPanel() { const styles = useStyles() const { table } = useTableDevtoolsContext() const tableInstance = table() const tableState = tableInstance ? useStore( tableInstance.optionsStore, ({ state, data, _features, _rowModels, ...options }) => options, ) : undefined const getState = (): unknown => { tableState?.() if (!tableInstance) { return undefined } return tableState?.() } return (
Options
} right={<>} />
) } ================================================ FILE: packages/table-devtools/src/components/ResizableSplit.tsx ================================================ import { createSignal } from 'solid-js' import { useStyles } from '../styles/use-styles' import type { JSX } from 'solid-js' const DEFAULT_LEFT_PERCENT = 50 const MIN_PANEL_PERCENT = 15 const MAX_PANEL_PERCENT = 85 interface ResizableSplitProps { left: JSX.Element right: JSX.Element } export function ResizableSplit(props: ResizableSplitProps) { const styles = useStyles() const [leftPercent, setLeftPercent] = createSignal(DEFAULT_LEFT_PERCENT) const handleMouseDown = (e: MouseEvent) => { e.preventDefault() const onMouseMove = (moveEvent: MouseEvent) => { const container = (e.target as HTMLElement).parentElement if (!container) return const rect = container.getBoundingClientRect() const x = moveEvent.clientX - rect.left const percent = Math.max( MIN_PANEL_PERCENT, Math.min(MAX_PANEL_PERCENT, (x / rect.width) * 100), ) setLeftPercent(percent) } const onMouseUp = () => { document.removeEventListener('mousemove', onMouseMove) document.removeEventListener('mouseup', onMouseUp) document.body.style.cursor = '' document.body.style.userSelect = '' } document.addEventListener('mousemove', onMouseMove) document.addEventListener('mouseup', onMouseUp) document.body.style.cursor = 'col-resize' document.body.style.userSelect = 'none' } return (
{props.left}
) } ================================================ FILE: packages/table-devtools/src/components/RowsPanel.tsx ================================================ import { For, createSignal } from 'solid-js' import { JsonTree } from '@tanstack/devtools-ui' import { useTableDevtoolsContext } from '../TableContextProvider' import { useTableStore } from '../useTableStore' import { useStyles } from '../styles/use-styles' import { ResizableSplit } from './ResizableSplit' import type { Cell, Column, Row, RowData, TableFeatures, } from '@tanstack/table-core' type AnyRow = Row type AnyCell = Cell type AnyColumn = Column const ROW_LIMIT = 100 const ROW_MODEL_GETTERS = [ 'getRowModel', 'getCoreRowModel', 'getFilteredRowModel', 'getGroupedRowModel', 'getSortedRowModel', 'getExpandedRowModel', 'getPaginatedRowModel', ] as const function stringifyValue(value: unknown): string { if (value == null) return '' if (typeof value === 'string') return value if (typeof value === 'number' || typeof value === 'boolean') return String(value) if (value instanceof Date) return value.toISOString() try { return JSON.stringify(value) } catch { return String(value) } } export function RowsPanel() { const styles = useStyles() const { table } = useTableDevtoolsContext() const tableInstance = table() const tableState = useTableStore( tableInstance ? tableInstance.store : undefined, (state) => state, ) const [selectedRowModel, setSelectedRowModel] = createSignal<(typeof ROW_MODEL_GETTERS)[number]>('getRowModel') const getRawData = (): unknown => { tableState?.() if (!tableInstance) { return { message: 'No table instance is connected. Pass a table instance to TableDevtoolsPanel.', } } const data = tableInstance.options.data as ReadonlyArray if (!Array.isArray(data)) return data if (data.length <= ROW_LIMIT) return data as unknown return data.slice(0, ROW_LIMIT) as unknown } const getRawDataTotalCount = (): number => { tableState?.() if (!tableInstance) return 0 const data = tableInstance.options.data as ReadonlyArray return Array.isArray(data) ? data.length : 0 } const getColumns = (): Array => { tableState?.() if (!tableInstance) return [] const tableWithColumnFns = tableInstance as unknown as { getVisibleLeafColumns?: () => Array getAllLeafColumns?: () => Array } return ( tableWithColumnFns.getVisibleLeafColumns?.() ?? tableWithColumnFns.getAllLeafColumns?.() ?? [] ) } const getAllRows = (): Array => { tableState?.() selectedRowModel() const getter = tableInstance?.[selectedRowModel()] as | (() => { rows: Array }) | undefined return getter?.().rows ?? [] } const getRows = (): Array => { const rows = getAllRows() return rows.length <= ROW_LIMIT ? rows : rows.slice(0, ROW_LIMIT) } const getRowsTotalCount = (): number => getAllRows().length const getCells = (row: AnyRow): Array => { tableState?.() const rowWithMaybeVisibleCells = row as unknown as { getVisibleCells?: () => Array } return rowWithMaybeVisibleCells.getVisibleCells?.() ?? row.getAllCells() } const getAvailableGetters = (): Array<(typeof ROW_MODEL_GETTERS)[number]> => { if (!tableInstance) return [] return ROW_MODEL_GETTERS.filter( (name) => typeof tableInstance[name] === 'function', ) } return (
Raw Data {getRawDataTotalCount() > ROW_LIMIT && ( {' '} (First {ROW_LIMIT} rows) )}
} right={ <>
Rows ({getRows().length} {getRowsTotalCount() > ROW_LIMIT && ` of ${getRowsTotalCount()}`}) {getRowsTotalCount() > ROW_LIMIT && ( {' '} — First {ROW_LIMIT} rows )}
{(column) => ( )} {(row) => ( {(cell) => ( )} )}
# {column.id}
{row.id} {stringifyValue(cell.getValue())}
} />
) } ================================================ FILE: packages/table-devtools/src/components/Shell.tsx ================================================ import { Match, Switch } from 'solid-js' import { Header, HeaderLogo, MainPanel } from '@tanstack/devtools-ui' import { useTableDevtoolsContext } from '../TableContextProvider' import { useStyles } from '../styles/use-styles' import { ColumnsPanel } from './ColumnsPanel' import { FeaturesPanel } from './FeaturesPanel' import { RowsPanel } from './RowsPanel' import { StatePanel } from './StatePanel' import { OptionsPanel } from './OptionsPanel' const tabs = [ { id: 'features', label: 'Features' }, { id: 'state', label: 'State' }, { id: 'options', label: 'Options' }, { id: 'rows', label: 'Rows' }, { id: 'columns', label: 'Columns' }, ] as const export function Shell() { const styles = useStyles() const { activeTab, setActiveTab } = useTableDevtoolsContext() return (
{ window.open('https://tanstack.com/table', '_blank') }} > TanStack Table
{tabs.map((tab) => ( ))}
) } ================================================ FILE: packages/table-devtools/src/components/StatePanel.tsx ================================================ import { For, createSignal } from 'solid-js' import { JsonTree } from '@tanstack/devtools-ui' import { useTableDevtoolsContext } from '../TableContextProvider' import { useTableStore } from '../useTableStore' import { useStyles } from '../styles/use-styles' import { ResizableSplit } from './ResizableSplit' export function StatePanel() { const styles = useStyles() const { table } = useTableDevtoolsContext() const [initialStateCopied, setInitialStateCopied] = createSignal(false) const [stateCopied, setStateCopied] = createSignal(false) const [pasteError, setPasteError] = createSignal(null) const tableInstance = table() const tableState = useTableStore( tableInstance ? tableInstance.store : undefined, (state) => state, ) const getInitialState = (): unknown => { tableState?.() if (!tableInstance) { return { message: 'No table instance is connected. Pass a table instance to TableDevtoolsPanel.', } } return tableInstance.initialState as unknown } const getState = (): unknown => { tableState?.() if (!tableInstance) { return undefined } return tableInstance.store.state as unknown } const copyToClipboard = async ( value: unknown, setCopied: (v: boolean) => void, ) => { try { await navigator.clipboard.writeText(JSON.stringify(value, null, 2)) setCopied(true) setTimeout(() => setCopied(false), 1500) } catch { // Clipboard API may fail in some contexts } } const handlePaste = async () => { if (!tableInstance) return setPasteError(null) try { const text = await navigator.clipboard.readText() const parsed = JSON.parse(text) if ( typeof parsed !== 'object' || parsed === null || Array.isArray(parsed) ) { setPasteError('Invalid state: must be a JSON object') return } tableInstance.baseStore.setState(() => ({ ...tableInstance.store.state, ...parsed, })) } catch (e) { setPasteError( e instanceof Error ? e.message : 'Failed to parse clipboard', ) } } const handleReset = () => { tableInstance?.reset() } const getStateSummaries = (): Array<{ key: string; summary: string }> => { const state = getState() as Record | undefined if (!state || typeof state !== 'object') return [] const summaries: Array<{ key: string; summary: string }> = [] if (Array.isArray(state.sorting) && state.sorting.length > 0) { const parts = (state.sorting as Array<{ id: string; desc: boolean }>).map( (s) => `${s.id} (${s.desc ? 'desc' : 'asc'})`, ) summaries.push({ key: 'sorting', summary: `${state.sorting.length} column(s) sorted: ${parts.join(', ')}`, }) } if (Array.isArray(state.columnFilters) && state.columnFilters.length > 0) { const parts = ( state.columnFilters as Array<{ id: string; value: unknown }> ).map((f) => `${f.id}=${JSON.stringify(f.value)}`) summaries.push({ key: 'columnFilters', summary: `${state.columnFilters.length} filter(s): ${parts.join(', ')}`, }) } if ( state.rowSelection && typeof state.rowSelection === 'object' && !Array.isArray(state.rowSelection) ) { const count = Object.keys( state.rowSelection as Record, ).filter((k) => (state.rowSelection as Record)[k]).length summaries.push({ key: 'rowSelection', summary: `${count} row(s) selected`, }) } if ( state.pagination && typeof state.pagination === 'object' && !Array.isArray(state.pagination) ) { const p = state.pagination as { pageIndex?: number; pageSize?: number } summaries.push({ key: 'pagination', summary: `Page ${(p.pageIndex ?? 0) + 1}, size ${p.pageSize ?? 10}`, }) } if (Array.isArray(state.grouping) && state.grouping.length > 0) { summaries.push({ key: 'grouping', summary: `Grouped by: ${(state.grouping as Array).join(', ')}`, }) } if ( state.columnPinning && typeof state.columnPinning === 'object' && !Array.isArray(state.columnPinning) ) { const p = state.columnPinning as { left?: Array right?: Array } const left = p.left?.length ?? 0 const right = p.right?.length ?? 0 summaries.push({ key: 'columnPinning', summary: `${left} left, ${right} right pinned`, }) } if (state.expanded !== undefined && state.expanded !== null) { if (state.expanded === true) { summaries.push({ key: 'expanded', summary: 'All expanded' }) } else if ( typeof state.expanded === 'object' && !Array.isArray(state.expanded) ) { const count = Object.keys( state.expanded as Record, ).filter((k) => (state.expanded as Record)[k]).length summaries.push({ key: 'expanded', summary: `${count} row(s) expanded`, }) } } if ('globalFilter' in state) { const val = state.globalFilter const str = val === undefined || val === null ? 'Not set' : typeof val === 'string' ? val ? `"${val}"` : '(empty)' : JSON.stringify(val) summaries.push({ key: 'globalFilter', summary: str }) } if ( state.columnVisibility && typeof state.columnVisibility === 'object' && !Array.isArray(state.columnVisibility) ) { const hidden = Object.entries( state.columnVisibility as Record, ).filter(([, v]) => v === false).length if (hidden > 0) { summaries.push({ key: 'columnVisibility', summary: `${hidden} column(s) hidden`, }) } } if (Array.isArray(state.columnOrder) && state.columnOrder.length > 0) { summaries.push({ key: 'columnOrder', summary: `Custom order (${state.columnOrder.length} columns)`, }) } return summaries } const stateSummaries = getStateSummaries() return (
initialState
} right={ <>
State
{pasteError() && (
{pasteError()}
)} {stateSummaries.length > 0 && (
State Summary {(item) => (
{item.key}: {item.summary}
)}
)} } />
) } ================================================ FILE: packages/table-devtools/src/core.tsx ================================================ import { constructCoreClass } from '@tanstack/devtools-utils/solid' import { lazy } from 'solid-js' const Component = lazy(() => import('./TableDevtools')) export interface TableDevtoolsInit {} const [TableDevtoolsCore, TableDevtoolsCoreNoOp] = constructCoreClass( Component.preload, ) export { TableDevtoolsCore, TableDevtoolsCoreNoOp } ================================================ FILE: packages/table-devtools/src/index.ts ================================================ 'use client' import * as Devtools from './core' export const TableDevtoolsCore = process.env.NODE_ENV !== 'development' ? Devtools.TableDevtoolsCoreNoOp : Devtools.TableDevtoolsCore export type { TableDevtoolsInit } from './core' export { setTableDevtoolsTarget } from './tableTarget' ================================================ FILE: packages/table-devtools/src/production.ts ================================================ 'use client' export { TableDevtoolsCore } from './core' export type { TableDevtoolsInit } from './core' export { setTableDevtoolsTarget } from './tableTarget' ================================================ FILE: packages/table-devtools/src/styles/tokens.ts ================================================ export const tokens = { colors: { white: '#ffffff', black: '#000000', gray: { 100: '#f8fafc', 200: '#e2e8f0', 300: '#cbd5e1', 500: '#64748b', 700: '#334155', 900: '#0f172a', }, darkGray: { 600: '#475569', 700: '#334155', 800: '#1e293b', 900: '#0f172a', }, red: { 300: '#fca5a5', 500: '#ef4444', 700: '#b91c1c', }, blue: { 300: '#93c5fd', 500: '#3b82f6', 700: '#1d4ed8', }, }, alpha: { 20: '33', }, size: { 1: '4px', 2: '8px', 3: '12px', 4: '16px', }, border: { radius: { sm: '4px', md: '6px', lg: '8px', }, }, font: { size: { xs: '11px', sm: '12px', md: '14px', }, weight: { normal: 400, semibold: 600, bold: 700, }, family: { sans: 'ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif', mono: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace', }, }, } ================================================ FILE: packages/table-devtools/src/styles/use-styles.ts ================================================ import * as goober from 'goober' import { createEffect, createSignal } from 'solid-js' import { useTheme } from '@tanstack/devtools-ui' import { tokens } from './tokens' const stylesFactory = (theme: 'light' | 'dark') => { const { colors, size, border, font, alpha } = tokens const css = goober.css const t = (light: string, dark: string) => (theme === 'light' ? light : dark) return { mainContainer: css` display: flex; flex: 1; min-height: 0; flex-direction: column; overflow: hidden; padding: ${size[2]}; gap: ${size[2]}; font-family: ${font.family.sans}; `, tabBar: css` display: flex; gap: ${size[2]}; align-items: center; flex-wrap: wrap; `, tabButton: css` border: 1px solid ${t(colors.gray[300], colors.darkGray[600])}; border-radius: ${border.radius.md}; background: ${t(colors.gray[100], colors.darkGray[800])}; color: ${t(colors.gray[700], colors.gray[200])}; font-size: ${font.size.sm}; font-weight: ${font.weight.semibold}; padding: ${size[2]} ${size[3]}; cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease; &:hover { background: ${t(colors.gray[200], colors.darkGray[700])}; } `, tabButtonActive: css` background: ${t( colors.red[500] + alpha[20], colors.red[700] + alpha[20], )}; border-color: ${t(colors.red[500], colors.red[300])}; color: ${t(colors.red[700], colors.red[300])}; `, contentArea: css` flex: 1; min-height: 0; border: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; border-radius: ${border.radius.lg}; background: ${t(colors.gray[100], colors.darkGray[800])}; overflow: hidden; `, panelScroll: css` height: 100%; overflow: auto; padding: ${size[3]}; display: flex; flex-direction: column; gap: ${size[3]}; `, section: css` border: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; border-radius: ${border.radius.md}; background: ${t(colors.white, colors.darkGray[900])}; padding: ${size[3]}; `, sectionTitle: css` font-size: ${font.size.md}; font-weight: ${font.weight.bold}; margin-bottom: ${size[2]}; color: ${t(colors.gray[900], colors.gray[100])}; `, tableWrapper: css` overflow: auto; border: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; border-radius: ${border.radius.sm}; `, rowsTable: css` width: 100%; border-collapse: collapse; font-size: ${font.size.sm}; `, headerCell: css` text-align: left; padding: ${size[2]}; border-bottom: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; border-right: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; white-space: nowrap; background: ${t(colors.gray[100], colors.darkGray[800])}; color: ${t(colors.gray[900], colors.gray[100])}; font-weight: ${font.weight.semibold}; `, bodyCell: css` padding: ${size[2]}; border-bottom: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; border-right: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; color: ${t(colors.gray[900], colors.gray[100])}; vertical-align: top; min-width: 120px; white-space: pre-wrap; word-break: break-word; `, bodyCellMono: css` padding: ${size[2]}; border-bottom: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; border-right: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; color: ${t(colors.gray[700], colors.gray[300])}; font-family: ${font.family.mono}; vertical-align: top; white-space: nowrap; `, featuresSplitContainer: css` display: flex; flex-direction: row; flex: 1; min-height: 0; overflow: hidden; gap: ${size[3]}; `, resizableSplitContainer: css` display: flex; flex-direction: row; flex: 1; min-height: 0; overflow: hidden; `, resizeHandle: css` flex: 0 0 6px; min-width: 6px; cursor: col-resize; background: ${t(colors.gray[200], colors.darkGray[700])}; transition: background 0.15s ease; &:hover { background: ${t(colors.gray[300], colors.darkGray[600])}; } &:active { background: ${t(colors.blue[500], colors.blue[500])}; } `, featuresSection: css` flex: 1; min-width: 0; min-height: 0; overflow: auto; `, featureSubsection: css` margin-bottom: ${size[3]}; `, featureSubsectionTitle: css` font-size: ${font.size.sm}; font-weight: ${font.weight.semibold}; margin-bottom: ${size[2]}; color: ${t(colors.gray[700], colors.gray[300])}; `, featureListItem: css` display: flex; align-items: center; gap: ${size[2]}; padding: ${size[1]} 0; font-size: ${font.size.sm}; font-family: ${font.family.mono}; color: ${t(colors.gray[700], colors.gray[200])}; `, featureCheck: css` color: ${t('#16a34a', '#4ade80')}; flex-shrink: 0; `, featureUncheck: css` color: ${t(colors.gray[500], colors.darkGray[600])}; flex-shrink: 0; `, rowModelItem: css` padding: ${size[1]} 0; font-size: ${font.size.sm}; font-family: ${font.family.mono}; color: ${t(colors.gray[700], colors.gray[200])}; `, rowModelFnItem: css` padding: ${size[1]} 0 ${size[1]} ${size[4]}; font-size: ${font.size.sm}; font-family: ${font.family.mono}; color: ${t(colors.gray[500], colors.gray[300])}; `, rowModelExecutionOrder: css` margin-top: ${size[3]}; padding-top: ${size[3]}; border-top: 1px solid ${t(colors.gray[200], colors.darkGray[700])}; font-size: ${font.size.xs}; font-family: ${font.family.mono}; color: ${t(colors.gray[500], colors.darkGray[600])}; line-height: 1.5; `, rowModelExecutionOrderBold: css` font-weight: ${font.weight.bold}; color: ${t(colors.gray[700], colors.gray[200])}; `, rowModelSelectRow: css` display: flex; align-items: center; gap: ${size[2]}; margin-bottom: ${size[2]}; `, rowModelSelect: css` border: 1px solid ${t(colors.gray[300], colors.darkGray[600])}; border-radius: ${border.radius.md}; background: ${t(colors.gray[100], colors.darkGray[800])}; color: ${t(colors.gray[700], colors.gray[200])}; font-size: ${font.size.sm}; font-family: ${font.family.mono}; padding: ${size[2]} ${size[3]}; cursor: pointer; `, rowLimitNote: css` font-weight: ${font.weight.normal}; color: ${t(colors.gray[500], colors.darkGray[600])}; font-size: ${font.size.sm}; `, buttonRow: css` display: flex; gap: ${size[2]}; margin-bottom: ${size[2]}; flex-wrap: wrap; `, copyButton: css` border: 1px solid ${t(colors.gray[300], colors.darkGray[600])}; border-radius: ${border.radius.md}; background: ${t(colors.gray[100], colors.darkGray[800])}; color: ${t(colors.gray[700], colors.gray[200])}; font-size: ${font.size.sm}; padding: ${size[1]} ${size[2]}; cursor: pointer; &:hover { background: ${t(colors.gray[200], colors.darkGray[700])}; } `, pasteButton: css` border: 1px solid ${t(colors.gray[300], colors.darkGray[600])}; border-radius: ${border.radius.md}; background: ${t(colors.gray[100], colors.darkGray[800])}; color: ${t(colors.gray[700], colors.gray[200])}; font-size: ${font.size.sm}; padding: ${size[1]} ${size[2]}; cursor: pointer; &:hover { background: ${t(colors.gray[200], colors.darkGray[700])}; } `, resetButton: css` border: 1px solid ${t(colors.red[300], colors.red[700])}; border-radius: ${border.radius.md}; background: ${t(colors.gray[100], colors.darkGray[800])}; color: ${t(colors.red[700], colors.red[300])}; font-size: ${font.size.sm}; padding: ${size[1]} ${size[2]}; cursor: pointer; &:hover { background: ${t(colors.gray[200], colors.darkGray[700])}; } `, summarySection: css` margin-bottom: ${size[3]}; `, summaryItem: css` font-size: ${font.size.sm}; color: ${t(colors.gray[700], colors.gray[200])}; margin-bottom: ${size[1]}; `, pasteError: css` font-size: ${font.size.sm}; color: ${t(colors.red[700], colors.red[300])}; margin-top: ${size[2]}; `, } } export function useStyles() { const { theme } = useTheme() const [styles, setStyles] = createSignal(stylesFactory(theme())) createEffect(() => { setStyles(stylesFactory(theme())) }) return styles } ================================================ FILE: packages/table-devtools/src/tableTarget.ts ================================================ import type { RowData, Table, TableFeatures } from '@tanstack/table-core' type AnyTable = Table type Listener = (table: AnyTable | undefined) => void let currentTable: AnyTable | undefined const listeners = new Set() export function setTableDevtoolsTarget(table: Table | undefined) { currentTable = table for (const listener of listeners) { listener(currentTable) } } export function getTableDevtoolsTarget() { return currentTable } export function subscribeTableDevtoolsTarget(listener: Listener) { listeners.add(listener) return () => { listeners.delete(listener) } } ================================================ FILE: packages/table-devtools/src/useTableStore.ts ================================================ import { createSignal, onCleanup } from 'solid-js' /** * Subscribes to a table store and returns a reactive signal. * Handles both subscribe APIs: function return (store 0.8.x) and * { unsubscribe } object return (store 0.9.x). */ export function useTableStore( store: | { state: T; subscribe: (listener: () => void) => unknown } | null | undefined, selector: (state: T) => U = (s) => s as unknown as U, ): (() => U) | undefined { if (!store) return undefined const [signal, setSignal] = createSignal(selector(store.state)) const result = store.subscribe(() => { setSignal(() => selector(store.state)) }) onCleanup(() => { if (typeof result === 'function') { ;(result as () => void)() } else if ( result && typeof (result as { unsubscribe?: () => void }).unsubscribe === 'function' ) { ;(result as { unsubscribe: () => void }).unsubscribe() } }) return signal } ================================================ FILE: packages/table-devtools/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "preserve", "jsxImportSource": "solid-js" }, "include": ["src", "eslint.config.js", "vite.config.ts", "tests"] } ================================================ FILE: packages/table-devtools/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import solid from 'vite-plugin-solid' import packageJson from './package.json' const config = defineConfig({ plugins: [solid()], test: { name: packageJson.name, dir: './tests', watch: false, environment: 'jsdom', globals: true, }, }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: ['./src/index.ts', './src/production.ts'], srcDir: './src', }), ) ================================================ FILE: packages/vue-table/eslint.config.js ================================================ // @ts-check import pluginVue from 'eslint-plugin-vue' import rootConfig from '../../eslint.config.js' export default [...rootConfig, ...pluginVue.configs['flat/base']] ================================================ FILE: packages/vue-table/package.json ================================================ { "name": "@tanstack/vue-table", "version": "9.0.0-alpha.10", "description": "Headless UI for building powerful tables & datagrids for Vue.", "author": "Tanner Linsley", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/TanStack/table.git", "directory": "packages/vue-table" }, "homepage": "https://tanstack.com/table", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "keywords": [ "vue", "table", "vue-table", "datagrid" ], "type": "module", "types": "dist/esm/index.d.ts", "main": "dist/esm/index.js", "module": "dist/esm/index.js", "exports": { ".": { "import": { "types": "./dist/esm/index.d.ts", "default": "./dist/esm/index.js" } }, "./package.json": "./package.json" }, "sideEffects": false, "engines": { "node": ">=16" }, "files": [ "dist", "src" ], "scripts": { "clean": "rimraf ./build && rimraf ./dist", "test:eslint": "eslint ./src", "test:types": "tsc", "test:build": "publint --strict", "build": "vite build" }, "dependencies": { "@tanstack/table-core": "workspace:*", "@tanstack/vue-store": "^0.9.2" }, "devDependencies": { "@vitejs/plugin-vue": "^6.0.3", "eslint-plugin-vue": "^10.7.0", "vue": "^3.5.27" }, "peerDependencies": { "vue": ">=3.2" } } ================================================ FILE: packages/vue-table/src/FlexRender.ts ================================================ import { defineComponent, h } from 'vue' export const FlexRender = defineComponent({ props: ['render', 'props'], setup: (props: { render: any; props: any }) => { return () => { if ( typeof props.render === 'function' || typeof props.render === 'object' ) { return h(props.render, props.props) } return props.render } }, }) ================================================ FILE: packages/vue-table/src/createTableHelper.ts ================================================ import { constructTableHelper } from '@tanstack/table-core' import { useTable } from './useTable' import type { TableOptionsWithReactiveData, VueTable } from './useTable' import type { RowData, TableFeatures, TableHelperOptions, TableHelper_Core, TableState, } from '@tanstack/table-core' export type TableHelper< TFeatures extends TableFeatures, TData extends RowData = any, > = Omit, 'tableCreator'> & { useTable: ( tableOptions: Omit< TableOptionsWithReactiveData, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ) => VueTable } export function createTableHelper< TFeatures extends TableFeatures, TData extends RowData, >( tableHelperOptions: TableHelperOptions, ): TableHelper { const tableHelper = constructTableHelper(useTable as any, tableHelperOptions) return { ...tableHelper, useTable: ( tableOptions: Omit< TableOptionsWithReactiveData, '_features' | '_rowModels' >, selector?: (state: TableState) => TSelected, ) => { return useTable( { ...tableHelper.options, ...tableOptions, } as TableOptionsWithReactiveData, selector, ) }, } } // test // type Person = { // firstName: string // lastName: string // age: number // } // const tableHelper = createTableHelper({ // _features: { rowSelectionFeature: {} }, // TData: {} as Person, // }) // const columns = [ // tableHelper.columnHelper.accessor('firstName', { header: 'First Name' }), // tableHelper.columnHelper.accessor('lastName', { header: 'Last Name' }), // tableHelper.columnHelper.accessor('age', { header: 'Age' }), // tableHelper.columnHelper.display({ header: 'Actions', id: 'actions' }), // ] as Array> // const data: Array = [] // tableHelper.useTable({ // columns, // data, // }) ================================================ FILE: packages/vue-table/src/index.ts ================================================ export * from './FlexRender' export * from './useTable' export * from './createTableHelper' export * from '@tanstack/table-core' ================================================ FILE: packages/vue-table/src/merge-proxy.ts ================================================ function trueFn() { return true } const $PROXY = Symbol('merge-proxy') // https://github.com/solidjs/solid/blob/c20ca4fd8c36bc0522fedb2c7f38a110b7ee2663/packages/solid/src/render/component.ts#L51-L118 const propTraps: ProxyHandler<{ get: (k: string | number | symbol) => any has: (k: string | number | symbol) => boolean keys: () => Array }> = { get(_, property, receiver) { if (property === $PROXY) return receiver return _.get(property) }, has(_, property) { return _.has(property) }, set: trueFn, deleteProperty: trueFn, getOwnPropertyDescriptor(_, property) { return { configurable: true, enumerable: true, get() { return _.get(property) }, set: trueFn, deleteProperty: trueFn, } }, ownKeys(_) { return _.keys() }, } type UnboxLazy = T extends () => infer U ? U : T type BoxedTupleTypes> = { [P in keyof T]: [UnboxLazy] }[Exclude>] type UnionToIntersection = (T extends any ? (k: T) => void : never) extends ( k: infer I, ) => void ? I : never type UnboxIntersection = T extends { 0: infer U } ? U : never type MergeProxy> = UnboxIntersection< UnionToIntersection> > function resolveSource(s: any) { return 'value' in s ? s.value : s } export function mergeProxy>(...sources: T): MergeProxy export function mergeProxy(...sources: any): any { return new Proxy( { get(property: string | number | symbol) { for (let i = sources.length - 1; i >= 0; i--) { const v = resolveSource(sources[i])[property] if (v !== undefined) return v } }, has(property: string | number | symbol) { for (let i = sources.length - 1; i >= 0; i--) { if (property in resolveSource(sources[i])) return true } return false }, keys() { const keys = [] for (const source of sources) keys.push(...Object.keys(resolveSource(source))) return [...Array.from(new Set(keys))] }, }, propTraps, ) } ================================================ FILE: packages/vue-table/src/useTable.ts ================================================ import { isRef, ref, unref, watch, watchEffect } from 'vue' import { constructReactivityFeature, constructTable, } from '@tanstack/table-core' import { useStore } from '@tanstack/vue-store' import { mergeProxy } from './merge-proxy' import type { NoInfer, RowData, Table, TableFeatures, TableOptions, TableState, } from '@tanstack/table-core' import type { MaybeRef, VNode } from 'vue' export type TableOptionsWithReactiveData< TFeatures extends TableFeatures, TData extends RowData, > = Omit, 'data'> & { data: MaybeRef> } function getOptionsWithReactiveData< TFeatures extends TableFeatures, TData extends RowData, >(options: TableOptionsWithReactiveData) { return mergeProxy(options, { data: unref(options.data), }) } export type VueTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, > = Table & { /** * A Vue component that allows you to subscribe to the table state. * * This is useful for opting into state subscriptions for specific parts of the table state. * * @example * ({ rowSelection: state.rowSelection })}> * {(state) => ( * * // render the row * * )} * */ Subscribe: (props: { selector: (state: NoInfer>) => TSelected children: | ((state: Readonly) => VNode | Array) | VNode | Array }) => VNode | Array /** * The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `useTable`. * * @example * const table = useTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state * * console.log(table.state.globalFilter) */ readonly state: Readonly } export function useTable< TFeatures extends TableFeatures, TData extends RowData, TSelected = {}, >( tableOptions: TableOptionsWithReactiveData, selector: (state: TableState) => TSelected = () => ({}) as TSelected, ): VueTable { const notifier = ref(0) const vueReactivityFeature = constructReactivityFeature({ stateNotifier: () => notifier.value, optionsNotifier: () => notifier.value, }) const IS_REACTIVE = isRef(tableOptions.data) const mergedOptions = { ...tableOptions, _features: { ...tableOptions._features, vueReactivityFeature, }, } const resolvedOptions = mergeProxy( IS_REACTIVE ? getOptionsWithReactiveData( mergedOptions as TableOptions, ) : mergedOptions, { // Remove state and onStateChange - store handles it internally mergeOptions: ( defaultOptions: TableOptions, newOptions: Partial>, ) => { return mergeProxy(defaultOptions, newOptions) }, }, ) as TableOptions const table = constructTable(resolvedOptions) as VueTable< TFeatures, TData, TSelected > const allState = useStore(table.store, (state) => state) const allOptions = useStore(table.optionsStore, (state) => state) watchEffect(() => { allState.value allOptions.value notifier.value++ }) watch( () => [ IS_REACTIVE ? unref(tableOptions.data) : tableOptions.data, tableOptions, ] as const, () => { table.setOptions((prev) => { return mergeProxy( prev, IS_REACTIVE ? getOptionsWithReactiveData( tableOptions as TableOptions, ) : tableOptions, ) as TableOptions }) }, { immediate: true }, ) table.Subscribe = function Subscribe(props: { selector: (state: TableState) => TSelected children: | ((state: Readonly) => VNode | Array) | VNode | Array }): VNode | Array { const selected = useStore(table.store, props.selector) if (typeof props.children === 'function') { return props.children(selected.value) } return props.children } const stateStore = useStore(table.store, selector) return { ...table, get state() { return stateStore.value }, } as VueTable } ================================================ FILE: packages/vue-table/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "jsx": "preserve", "jsxImportSource": "vue", "moduleResolution": "Bundler", "types": ["vue/jsx"], "paths": { "@tanstack/form-core": ["../form-core/src"] } }, "include": ["src", "vite.config.ts", "eslint.config.js"] } ================================================ FILE: packages/vue-table/vite.config.ts ================================================ import { defineConfig, mergeConfig } from 'vitest/config' import { tanstackViteConfig } from '@tanstack/vite-config' import vue from '@vitejs/plugin-vue' const config = defineConfig({ plugins: [vue()], }) export default mergeConfig( config, tanstackViteConfig({ cjs: false, entry: './src/index.ts', srcDir: './src', exclude: ['./src/tests'], }), ) ================================================ FILE: pnpm-workspace.yaml ================================================ packages: - examples/**/* - packages/* cleanupUnusedCatalogs: true linkWorkspacePackages: true preferWorkspacePackages: true ================================================ FILE: prettier.config.js ================================================ // @ts-check /** @type {import('prettier').Config} */ const config = { semi: false, singleQuote: true, trailingComma: 'all', plugins: ['prettier-plugin-svelte'], overrides: [ { files: '*.svelte', options: { parser: 'svelte' } }, { files: ['examples/angular/**/*.html'], options: { printWidth: 100, parser: 'angular', }, }, ], } export default config ================================================ FILE: scripts/config.js ================================================ // @ts-check import { resolve } from 'node:path' import { fileURLToPath } from 'node:url' /** * List your npm packages here. The first package will be used as the versioner. * @type {import('./types').Package[]} */ export const packages = [ { name: '@tanstack/table-core', packageDir: 'packages/table-core', }, // { // name: '@tanstack/table-devtools', // packageDir: 'packages/table-devtools', // }, { name: '@tanstack/angular-table', packageDir: 'packages/angular-table', }, // { // name: '@tanstack/lit-table', // packageDir: 'packages/lit-table', // }, { name: '@tanstack/preact-table', packageDir: 'packages/preact-table', }, { name: '@tanstack/react-table', packageDir: 'packages/react-table', }, // { // name: '@tanstack/react-table-devtools', // packageDir: 'packages/react-table-devtools', // }, // { // name: '@tanstack/solid-table', // packageDir: 'packages/solid-table', // }, // { // name: '@tanstack/svelte-table', // packageDir: 'packages/svelte-table', // }, // { // name: '@tanstack/vue-table', // packageDir: 'packages/vue-table', // }, // { // name: '@tanstack/match-sorter-utils', // packageDir: 'packages/match-sorter-utils', // }, ] /** * Contains config for publishable branches. * @type {Record} */ export const branchConfigs = { main: { prerelease: false, }, alpha: { prerelease: true, }, beta: { prerelease: true, }, rc: { prerelease: true, }, } const __dirname = fileURLToPath(new URL('.', import.meta.url)) export const rootDir = resolve(__dirname, '..') ================================================ FILE: scripts/generateDocs.js ================================================ import { resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { generateReferenceDocs } from '@tanstack/typedoc-config' const __dirname = fileURLToPath(new URL('.', import.meta.url)) await generateReferenceDocs({ packages: [ { name: 'table-core', entryPoints: [resolve(__dirname, '../packages/table-core/src/index.ts')], tsconfig: resolve(__dirname, '../packages/table-core/tsconfig.json'), outputDir: resolve(__dirname, '../docs/reference'), }, { name: 'react-table', entryPoints: [ resolve(__dirname, '../packages/react-table/src/index.ts'), resolve(__dirname, '../packages/react-table/src/legacy.ts'), ], tsconfig: resolve(__dirname, '../packages/react-table/tsconfig.json'), outputDir: resolve(__dirname, '../docs/framework/react/reference'), exclude: ['packages/table-core/**/*'], }, { name: 'angular-table', entryPoints: [ resolve(__dirname, '../packages/angular-table/src/index.ts'), ], tsconfig: resolve(__dirname, '../packages/angular-table/tsconfig.json'), outputDir: resolve(__dirname, '../docs/framework/angular/reference'), exclude: ['packages/table-core/**/*'], }, ], }) console.log('\n✅ All markdown files have been processed!') process.exit(0) ================================================ FILE: scripts/publish.js ================================================ // @ts-check import { publish } from '@tanstack/publish-config' import { branchConfigs, packages, rootDir } from './config.js' await publish({ branchConfigs, packages, rootDir, branch: process.env.BRANCH, tag: process.env.TAG, ghToken: process.env.GH_TOKEN, }) process.exit(0) ================================================ FILE: scripts/types.d.ts ================================================ export type Package = { name: string packageDir: string } export type BranchConfig = { prerelease: boolean previousVersion?: boolean } ================================================ FILE: scripts/verify-links.ts ================================================ import { existsSync, readFileSync, statSync } from 'node:fs' import { extname, resolve } from 'node:path' import { glob } from 'tinyglobby' // @ts-ignore Could not find a declaration file for module 'markdown-link-extractor'. import markdownLinkExtractor from 'markdown-link-extractor' const errors: Array<{ file: string link: string resolvedPath: string reason: string }> = [] function isRelativeLink(link: string) { return ( !link.startsWith('/') && !link.startsWith('http://') && !link.startsWith('https://') && !link.startsWith('//') && !link.startsWith('#') && !link.startsWith('mailto:') ) } /** Remove any trailing .md */ function stripExtension(p: string): string { return p.replace(`${extname(p)}`, '') } function relativeLinkExists(link: string, file: string): boolean { // Remove hash if present const linkWithoutHash = link.split('#')[0] // If the link is empty after removing hash, it's not a file if (!linkWithoutHash) return false // Strip the file/link extensions const filePath = stripExtension(file) const linkPath = stripExtension(linkWithoutHash) // Resolve the path relative to the markdown file's directory // Nav up a level to simulate how links are resolved on the web let absPath = resolve(filePath, '..', linkPath) // Ensure the resolved path is within /docs const docsRoot = resolve('docs') if (!absPath.startsWith(docsRoot)) { errors.push({ link, file, resolvedPath: absPath, reason: 'Path outside /docs', }) return false } // Check if this is an example path const isExample = absPath.includes('/examples/') let exists = false if (isExample) { // Transform /docs/framework/{framework}/examples/ to /examples/{framework}/ absPath = absPath.replace( /\/docs\/framework\/([^/]+)\/examples\//, '/examples/$1/', ) // For examples, we want to check if the directory exists exists = existsSync(absPath) && statSync(absPath).isDirectory() } else { // For non-examples, we want to check if the .md file exists if (!absPath.endsWith('.md')) { absPath = `${absPath}.md` } exists = existsSync(absPath) } if (!exists) { errors.push({ link, file, resolvedPath: absPath, reason: 'Not found', }) } return exists } async function verifyMarkdownLinks() { // Find all markdown files in docs directory const markdownFiles = await glob('docs/**/*.md', { ignore: ['**/node_modules/**'], }) console.log(`Found ${markdownFiles.length} markdown files\n`) // Process each file for (const file of markdownFiles) { const content = readFileSync(file, 'utf-8') const links: Array = markdownLinkExtractor(content) const relativeLinks = links.filter((link: string) => { return isRelativeLink(link) }) if (relativeLinks.length > 0) { relativeLinks.forEach((link) => { relativeLinkExists(link, file) }) } } if (errors.length > 0) { console.log(`\n❌ Found ${errors.length} broken links:`) errors.forEach((err) => { console.log( `${err.file}\n link: ${err.link}\n resolved: ${err.resolvedPath}\n why: ${err.reason}\n`, ) }) process.exit(1) } else { console.log('\n✅ No broken links found!') } } verifyMarkdownLinks().catch(console.error) ================================================ FILE: tsconfig.json ================================================ { "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, "allowUnreachableCode": false, "allowUnusedLabels": false, "checkJs": true, "declaration": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "isolatedModules": true, "lib": ["DOM", "DOM.Iterable", "ES2022"], "module": "ESNext", "moduleResolution": "Bundler", "noEmit": true, "noImplicitReturns": false, // TODO enable "noUncheckedIndexedAccess": true, "noUnusedLocals": false, // TODO enable "noUnusedParameters": false, // TODO enable "resolveJsonModule": true, "skipLibCheck": true, "strict": true, "target": "ES2020", "noErrorTruncation": true }, "include": ["*.config.*", "scripts", "vitest.workspace.mjs"] } ================================================ FILE: vitest.workspace.mjs ================================================ export default [ './packages/angular-table/vite.config.ts', './packages/lit-table/vite.config.ts', './packages/match-sorter-utils/vite.config.ts', './packages/react-table/vite.config.ts', './packages/solid-table/vite.config.ts', './packages/svelte-table/vite.config.ts', './packages/table-core/vite.config.ts', './packages/vue-table/vite.config.ts', ]