diff --git a/docs/guide/custom-features.md b/docs/guide/custom-features.md index e8c1c875c3..4f6ba90442 100644 --- a/docs/guide/custom-features.md +++ b/docs/guide/custom-features.md @@ -43,16 +43,53 @@ TanStack Table's source code is arguably somewhat simple (at least we think so). 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 { - assignCellPrototype?: AssignCellPrototype - assignColumnPrototype?: AssignColumnPrototype - assignHeaderPrototype?: AssignHeaderPrototype - assignRowPrototype?: AssignRowPrototype - constructTableAPIs?: ConstructTableAPIs - getDefaultColumnDef?: GetDefaultColumnDef - getDefaultTableOptions?: GetDefaultTableOptions - getInitialState?: GetInitialState - initRowInstanceData?: InitRowInstanceData +export interface TableFeature { + assignCellPrototype?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + prototype: Record, + table: Table_Internal, + ) => void + assignColumnPrototype?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + prototype: Record, + table: Table_Internal, + ) => void + assignHeaderPrototype?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + prototype: Record, + table: Table_Internal, + ) => void + assignRowPrototype?: ( + prototype: Record, + table: Table_Internal, + ) => void + constructTableAPIs?: ( + table: Table_Internal, + ) => void + getDefaultColumnDef?: < + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + >() => ColumnDefBase_All + getDefaultTableOptions?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + table: Table_Internal, + ) => Partial> + getInitialState?: (initialState: Partial) => TableState_All + initRowInstanceData?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + row: Row, + ) => void } ``` @@ -140,22 +177,34 @@ export interface Table_Density { setDensity: (updater: Updater) => void toggleDensity: (value?: DensityState) => void } - -interface DensityPluginConstructors { - Table: Table_Density - TableOptions: TableOptions_Density - TableState: TableState_Density -} ``` -#### Step 2: Add the Feature to the TableFeatures Interface +#### Step 2: Add the Feature to TanStack Table's Feature Maps -TanStack Table uses the keys passed to `tableFeatures({ ... })` to infer which feature state, options, and APIs exist on a table. To make a custom feature key type-safe, add it to the exported `Plugins` interface with declaration merging. +TanStack Table uses the keys passed to `tableFeatures({ ... })` to infer which feature state, options, and APIs exist on a table. To make a custom feature key type-safe, add it to the exported `Plugins`, `TableState_FeatureMap`, `TableOptions_FeatureMap`, and `Table_FeatureMap` interfaces with declaration merging. ```ts declare module '@tanstack/react-table' { interface Plugins { - densityPlugin?: TableFeature + densityPlugin: TableFeature + } + + interface TableState_FeatureMap { + densityPlugin: TableState_Density + } + + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: TableOptions_Density + } + + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: Table_Density } } ``` @@ -169,7 +218,7 @@ With all of that TypeScript setup out of the way, we can now create the feature 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 densityPlugin: TableFeature = { +export const densityPlugin: TableFeature = { // define the new feature's initial state getInitialState: (initialState) => { return { @@ -190,19 +239,26 @@ export const densityPlugin: TableFeature = { // define the new feature's table instance methods constructTableAPIs: (table) => { - table.setDensity = (updater) => { - const safeUpdater: Updater = (old) => { - const newState = functionalUpdate(updater, old) - return newState - } - return table.options.onDensityChange?.(safeUpdater) - } - table.toggleDensity = (value) => { - table.setDensity?.((old) => { - if (value) return value - return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' - }) - } + assignTableAPIs('densityPlugin', table, { + table_setDensity: { + fn: (updater: Updater) => { + const safeUpdater: Updater = (old) => { + const newState = functionalUpdate(updater, old) + return newState + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + table_toggleDensity: { + fn: (value?: DensityState) => { + const safeUpdater: Updater = (old) => { + if (value) return value + return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + }) }, // if you need to add row instance APIs... diff --git a/examples/angular/custom-plugin/src/app/density/density-feature.ts b/examples/angular/custom-plugin/src/app/density/density-feature.ts index ac77f186ee..319fe5de03 100644 --- a/examples/angular/custom-plugin/src/app/density/density-feature.ts +++ b/examples/angular/custom-plugin/src/app/density/density-feature.ts @@ -1,6 +1,11 @@ -import { functionalUpdate, makeStateUpdater } from '@tanstack/angular-table' +import { + assignTableAPIs, + functionalUpdate, + makeStateUpdater, +} from '@tanstack/angular-table' import type { OnChangeFn, + RowData, TableFeature, TableFeatures, Updater, @@ -26,16 +31,32 @@ export interface Table_Density { toggleDensity: (value?: DensityState) => void } -interface DensityPluginConstructors { - Table: Table_Density - TableOptions: TableOptions_Density - TableState: TableState_Density +declare module '@tanstack/angular-table' { + interface Plugins { + densityPlugin: TableFeature + } + + interface TableState_FeatureMap { + densityPlugin: TableState_Density + } + + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: TableOptions_Density + } + + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: Table_Density + } } // Here is all of the actual javascript code for our new feature -export const densityPlugin: TableFeature< - DensityPluginConstructors -> = { +export const densityPlugin: TableFeature = { // define the new feature's initial state getInitialState: (initialState) => { return { @@ -56,31 +77,26 @@ export const densityPlugin: TableFeature< // define the new feature's table instance methods constructTableAPIs: (table) => { - table.setDensity = (updater) => { - const safeUpdater: Updater = (old) => { - const newState = functionalUpdate(updater, old) - return newState - } - return table.options.onDensityChange?.(safeUpdater) - } - table.toggleDensity = (value) => { - table.setDensity?.((old) => { - if (value) return value - return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options - }) - } + assignTableAPIs('densityPlugin', table, { + table_setDensity: { + fn: (updater: Updater) => { + const safeUpdater: Updater = (old) => { + const newState = functionalUpdate(updater, old) + return newState + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + table_toggleDensity: { + fn: (value?: DensityState) => { + const safeUpdater: Updater = (old) => { + if (value) return value + return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + }) }, - - // 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 diff --git a/examples/preact/custom-plugin/src/main.tsx b/examples/preact/custom-plugin/src/main.tsx index ce86937507..e71afe6841 100644 --- a/examples/preact/custom-plugin/src/main.tsx +++ b/examples/preact/custom-plugin/src/main.tsx @@ -2,6 +2,7 @@ import { useMemo, useState } from 'preact/hooks' import { render } from 'preact' import './index.css' import { + assignTableAPIs, columnFilteringFeature, createColumnHelper, createFilteredRowModel, @@ -21,7 +22,9 @@ import type { Column, OnChangeFn, PreactTable, + RowData, TableFeature, + TableFeatures, Updater, } from '@tanstack/preact-table' import type { Person } from './makeData' @@ -46,14 +49,32 @@ export interface Table_Density { toggleDensity: (value?: DensityState) => void } -interface DensityPluginConstructors { - Table: Table_Density - TableOptions: TableOptions_Density - TableState: TableState_Density +declare module '@tanstack/preact-table' { + interface Plugins { + densityPlugin: TableFeature + } + + interface TableState_FeatureMap { + densityPlugin: TableState_Density + } + + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: TableOptions_Density + } + + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: Table_Density + } } // Here is all of the actual javascript code for our new feature -export const densityPlugin: TableFeature = { +export const densityPlugin: TableFeature = { // define the new feature's initial state getInitialState: (initialState) => { return { @@ -74,32 +95,27 @@ export const densityPlugin: TableFeature = { // define the new feature's table instance methods constructTableAPIs: (table) => { - table.setDensity = (updater) => { - const safeUpdater: Updater = (old) => { - const newState = functionalUpdate(updater, old) - return newState - } - return table.options.onDensityChange?.(safeUpdater) - } - table.toggleDensity = (value) => { - table.setDensity?.((old) => { - if (value) return value - return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options - }) - } + assignTableAPIs('densityPlugin', table, { + table_setDensity: { + fn: (updater: Updater) => { + const safeUpdater: Updater = (old) => { + const newState = functionalUpdate(updater, old) + return newState + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + table_toggleDensity: { + fn: (value?: DensityState) => { + const safeUpdater: Updater = (old) => { + if (value) return value + return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + }) }, - - // 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 diff --git a/examples/react/custom-plugin/src/main.tsx b/examples/react/custom-plugin/src/main.tsx index 54afa7eb63..e987e3acc6 100644 --- a/examples/react/custom-plugin/src/main.tsx +++ b/examples/react/custom-plugin/src/main.tsx @@ -2,6 +2,7 @@ import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { + assignTableAPIs, columnFilteringFeature, createColumnHelper, createFilteredRowModel, @@ -22,7 +23,9 @@ import type { Column, OnChangeFn, ReactTable, + RowData, TableFeature, + TableFeatures, Updater, } from '@tanstack/react-table' import type { Person } from './makeData' @@ -47,14 +50,32 @@ export interface Table_Density { toggleDensity: (value?: DensityState) => void } -interface DensityPluginConstructors { - Table: Table_Density - TableOptions: TableOptions_Density - TableState: TableState_Density +declare module '@tanstack/react-table' { + interface Plugins { + densityPlugin: TableFeature + } + + interface TableState_FeatureMap { + densityPlugin: TableState_Density + } + + interface TableOptions_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: TableOptions_Density + } + + interface Table_FeatureMap< + TFeatures extends TableFeatures, + TData extends RowData, + > { + densityPlugin: Table_Density + } } // Here is all of the actual javascript code for our new feature -export const densityPlugin: TableFeature = { +export const densityPlugin: TableFeature = { // define the new feature's initial state getInitialState: (initialState) => { return { @@ -75,32 +96,27 @@ export const densityPlugin: TableFeature = { // define the new feature's table instance methods constructTableAPIs: (table) => { - table.setDensity = (updater) => { - const safeUpdater: Updater = (old) => { - const newState = functionalUpdate(updater, old) - return newState - } - return table.options.onDensityChange?.(safeUpdater) - } - table.toggleDensity = (value) => { - table.setDensity?.((old) => { - if (value) return value - return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options - }) - } + assignTableAPIs('densityPlugin', table, { + table_setDensity: { + fn: (updater: Updater) => { + const safeUpdater: Updater = (old) => { + const newState = functionalUpdate(updater, old) + return newState + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + table_toggleDensity: { + fn: (value?: DensityState) => { + const safeUpdater: Updater = (old) => { + if (value) return value + return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // cycle through the 3 options + } + return table.options.onDensityChange?.(safeUpdater) + }, + }, + }) }, - - // 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 diff --git a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-column-header.tsx b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-column-header.tsx index ec2c356c85..4586b08953 100644 --- a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-column-header.tsx +++ b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-column-header.tsx @@ -10,7 +10,8 @@ import { PinOff, Ungroup, } from 'lucide-react' -import type { Column, RowData, TableFeatures } from '@tanstack/react-table' +import type { CellData, Column, RowData } from '@tanstack/react-table' +import type { features } from '@/main' import { Button } from '@/components/ui/button' import { @@ -32,29 +33,18 @@ import { cn } from '@/lib/utils' * (https://ui.shadcn.com/docs/components/radix/data-table) but extended to * cover grouping and pinning since the kitchen-sink uses the full v9 surface. */ -/** - * Features the dropdown queries on the column. Mirrors the generic shape the - * other `data-table-*` components use (TFeatures extends TableFeatures, - * narrowed via Pick at the use site). - */ -type ColumnHeaderFeatureKeys = - | 'columnGroupingFeature' - | 'columnPinningFeature' - | 'columnVisibilityFeature' - | 'rowSortingFeature' - interface DataTableColumnHeaderProps< - TFeatures extends TableFeatures, TData extends RowData, + TValue extends CellData = CellData, > extends React.HTMLAttributes { - column: Column, TData> + column: Column title: string } export function DataTableColumnHeader< - TFeatures extends TableFeatures, TData extends RowData, ->({ column, title, className }: DataTableColumnHeaderProps) { + TValue extends CellData = CellData, +>({ column, title, className }: DataTableColumnHeaderProps) { const canSort = column.getCanSort() const canHide = column.getCanHide() const canPin = column.getCanPin() diff --git a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx index 25f80fd99d..bc37ce1154 100644 --- a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx +++ b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-filter-list.tsx @@ -9,18 +9,15 @@ import { ListFilter, Trash2, } from 'lucide-react' +import type { ExtendedColumnFilter, FilterOperator } from '@/types' import type { - ExtendedColumnFilter, - FilterOperator, - TableFilterFeatures, -} from '@/types' -import type { + CellData, Column, ColumnMeta, + ReactTable, RowData, - Table, - TableFeatures, } from '@tanstack/react-table' +import type { features } from '@/main' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' @@ -62,7 +59,7 @@ import { // TODO: column.getFacetedUniqueValues() is broken rn, remove this once it's fixed function createManualFacetedValues( - table: Table, TData>, + table: ReactTable, columnId: string, ): Map { const facetedValues = new Map() @@ -80,15 +77,12 @@ function createManualFacetedValues( return facetedValues } -function getColumnOptions< - TFeatures extends TableFeatures, - TData extends RowData, ->({ +function getColumnOptions({ column, table, }: { - column: Column, TData> - table: Table, TData> + column: Column + table: ReactTable }): Array<{ label: string; value: string; count?: number }> { const customOptions = column.columnDef.meta?.options @@ -112,23 +106,17 @@ function getColumnOptions< })) } -interface DataTableFilterListProps< - TFeatures extends TableFeatures, - TData extends RowData, -> { - table: Table, TData> +interface DataTableFilterListProps { + table: ReactTable columnFilters: Array onColumnFiltersChange: (filters: Array) => void } -export function DataTableFilterList< - TFeatures extends TableFeatures, - TData extends RowData, ->({ +export function DataTableFilterList({ table, columnFilters, onColumnFiltersChange, -}: DataTableFilterListProps) { +}: DataTableFilterListProps) { const id = React.useId() const labelId = React.useId() const descriptionId = React.useId() @@ -142,8 +130,8 @@ export function DataTableFilterList< const getColumnFilterVariant = React.useCallback( ( - column: Column, TData>, - ): ColumnMeta['variant'] => { + column: Column, + ): ColumnMeta['variant'] => { if (column.columnDef.meta?.variant) { return column.columnDef.meta.variant } @@ -273,7 +261,7 @@ export function DataTableFilterList< filterId, inputId, }: { - column: Column, TData> + column: Column operator: FilterOperator filterId: string inputId: string diff --git a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-pagination.tsx b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-pagination.tsx index 6545acadb9..1bda90c5e9 100644 --- a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-pagination.tsx +++ b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-pagination.tsx @@ -6,7 +6,8 @@ import { ChevronsLeft, ChevronsRight, } from 'lucide-react' -import type { RowData, Table, TableFeatures } from '@tanstack/react-table' +import type { ReactTable, RowData } from '@tanstack/react-table' +import type { features } from '@/main' import { Button } from '@/components/ui/button' import { @@ -17,15 +18,15 @@ import { SelectValue, } from '@/components/ui/select' -interface DataTablePaginationProps { - table: Table, RowData> +interface DataTablePaginationProps { + table: ReactTable pageSizeOptions?: Array } -export function DataTablePagination({ +export function DataTablePagination({ table, pageSizeOptions = [10, 20, 30, 40, 50], -}: DataTablePaginationProps) { +}: DataTablePaginationProps) { return (
diff --git a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-sort-list.tsx b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-sort-list.tsx index 12fec45020..b032bec4f5 100644 --- a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-sort-list.tsx +++ b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-sort-list.tsx @@ -10,12 +10,12 @@ import { } from 'lucide-react' import type { ColumnSort, + ReactTable, RowData, SortDirection, SortingState, - Table, - TableFeatures, } from '@tanstack/react-table' +import type { features } from '@/main' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' @@ -48,23 +48,17 @@ import { } from '@/components/ui/sortable' import { cn } from '@/lib/utils' -interface DataTableSortListProps< - TFeatures extends TableFeatures, - TData extends RowData, -> { - table: Table, TData> +interface DataTableSortListProps { + table: ReactTable sorting: SortingState onSortingChange: (sorting: SortingState) => void } -export function DataTableSortList< - TFeatures extends TableFeatures, - TData extends RowData, ->({ +export function DataTableSortList({ table, sorting, onSortingChange, -}: DataTableSortListProps) { +}: DataTableSortListProps) { const labelId = React.useId() const descriptionId = React.useId() const listId = React.useId() diff --git a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-view-options.tsx b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-view-options.tsx index 5c2598b34f..ba24a65fa4 100644 --- a/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-view-options.tsx +++ b/examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-view-options.tsx @@ -4,10 +4,10 @@ import * as React from 'react' import { Check, ChevronsUpDown, GripVertical, Settings2 } from 'lucide-react' import type { ColumnOrderState, + ReactTable, RowData, - Table, - TableFeatures, } from '@tanstack/react-table' +import type { features } from '@/main' import { Button } from '@/components/ui/button' import { @@ -33,23 +33,17 @@ import { SortableOverlay, } from '@/components/ui/sortable' -interface DataTableViewOptionsProps< - TFeatures extends TableFeatures, - TRowData extends RowData, -> { - table: Table, TRowData> +interface DataTableViewOptionsProps { + table: ReactTable columnOrder: ColumnOrderState onColumnOrderChange: (columnOrder: ColumnOrderState) => void } -export function DataTableViewOptions< - TFeatures extends TableFeatures, - TRowData extends RowData, ->({ +export function DataTableViewOptions({ table, columnOrder, onColumnOrderChange, -}: DataTableViewOptionsProps) { +}: DataTableViewOptionsProps) { const triggerRef = React.useRef(null) return ( diff --git a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-column-header.tsx b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-column-header.tsx index 9425d8679a..68cccd4303 100644 --- a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-column-header.tsx +++ b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-column-header.tsx @@ -10,7 +10,8 @@ import { PinOff, Ungroup, } from 'lucide-react' -import type { Column, RowData, TableFeatures } from '@tanstack/react-table' +import type { CellData, Column, RowData } from '@tanstack/react-table' +import type { features } from '@/main' import { Button } from '@/components/ui/button' import { @@ -32,29 +33,18 @@ import { cn } from '@/lib/utils' * (https://ui.shadcn.com/docs/components/radix/data-table) but extended to * cover grouping and pinning since the kitchen-sink uses the full v9 surface. */ -/** - * Features the dropdown queries on the column. Mirrors the generic shape the - * other `data-table-*` components use (TFeatures extends TableFeatures, - * narrowed via Pick at the use site). - */ -type ColumnHeaderFeatureKeys = - | 'columnGroupingFeature' - | 'columnPinningFeature' - | 'columnVisibilityFeature' - | 'rowSortingFeature' - interface DataTableColumnHeaderProps< - TFeatures extends TableFeatures, TData extends RowData, + TValue extends CellData = CellData, > extends React.HTMLAttributes { - column: Column, TData> + column: Column title: string } export function DataTableColumnHeader< - TFeatures extends TableFeatures, TData extends RowData, ->({ column, title, className }: DataTableColumnHeaderProps) { + TValue extends CellData = CellData, +>({ column, title, className }: DataTableColumnHeaderProps) { const canSort = column.getCanSort() const canHide = column.getCanHide() const canPin = column.getCanPin() diff --git a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-filter-list.tsx b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-filter-list.tsx index e1e2cbd566..a637361d2c 100644 --- a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-filter-list.tsx +++ b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-filter-list.tsx @@ -13,15 +13,15 @@ import type { ExtendedColumnFilter, FilterOperator, JoinOperator, - TableFilterFeatures, } from '@/types' import type { + CellData, Column, ColumnMeta, + ReactTable, RowData, - Table, - TableFeatures, } from '@tanstack/react-table' +import type { features } from '@/main' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' @@ -63,7 +63,7 @@ import { // TODO: column.getFacetedUniqueValues() is broken rn, remove this once it's fixed function createManualFacetedValues( - table: Table, TData>, + table: ReactTable, columnId: string, ): Map { const facetedValues = new Map() @@ -81,15 +81,12 @@ function createManualFacetedValues( return facetedValues } -function getColumnOptions< - TFeatures extends TableFeatures, - TData extends RowData, ->({ +function getColumnOptions({ column, table, }: { - column: Column, TData> - table: Table, TData> + column: Column + table: ReactTable }): Array<{ label: string; value: string; count?: number }> { const customOptions = column.columnDef.meta?.options @@ -113,23 +110,17 @@ function getColumnOptions< })) } -interface DataTableFilterListProps< - TFeatures extends TableFeatures, - TData extends RowData, -> { - table: Table, TData> +interface DataTableFilterListProps { + table: ReactTable columnFilters: Array onColumnFiltersChange: (filters: Array) => void } -export function DataTableFilterList< - TFeatures extends TableFeatures, - TData extends RowData, ->({ +export function DataTableFilterList({ table, columnFilters, onColumnFiltersChange, -}: DataTableFilterListProps) { +}: DataTableFilterListProps) { const id = React.useId() const labelId = React.useId() const descriptionId = React.useId() @@ -143,8 +134,8 @@ export function DataTableFilterList< const getColumnFilterVariant = React.useCallback( ( - column: Column, TData>, - ): ColumnMeta['variant'] => { + column: Column, + ): ColumnMeta['variant'] => { if (column.columnDef.meta?.variant) { return column.columnDef.meta.variant } @@ -274,7 +265,7 @@ export function DataTableFilterList< filterId, inputId, }: { - column: Column, TData> + column: Column operator: FilterOperator filterId: string inputId: string diff --git a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-pagination.tsx b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-pagination.tsx index 6545acadb9..1bda90c5e9 100644 --- a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-pagination.tsx +++ b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-pagination.tsx @@ -6,7 +6,8 @@ import { ChevronsLeft, ChevronsRight, } from 'lucide-react' -import type { RowData, Table, TableFeatures } from '@tanstack/react-table' +import type { ReactTable, RowData } from '@tanstack/react-table' +import type { features } from '@/main' import { Button } from '@/components/ui/button' import { @@ -17,15 +18,15 @@ import { SelectValue, } from '@/components/ui/select' -interface DataTablePaginationProps { - table: Table, RowData> +interface DataTablePaginationProps { + table: ReactTable pageSizeOptions?: Array } -export function DataTablePagination({ +export function DataTablePagination({ table, pageSizeOptions = [10, 20, 30, 40, 50], -}: DataTablePaginationProps) { +}: DataTablePaginationProps) { return (
diff --git a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-sort-list.tsx b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-sort-list.tsx index 37b250854a..06ff421076 100644 --- a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-sort-list.tsx +++ b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-sort-list.tsx @@ -10,12 +10,12 @@ import { } from 'lucide-react' import type { ColumnSort, + ReactTable, RowData, SortDirection, SortingState, - Table, - TableFeatures, } from '@tanstack/react-table' +import type { features } from '@/main' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' @@ -48,23 +48,17 @@ import { } from '@/components/ui/sortable' import { cn } from '@/lib/utils' -interface DataTableSortListProps< - TFeatures extends TableFeatures, - TData extends RowData, -> { - table: Table, TData> +interface DataTableSortListProps { + table: ReactTable sorting: SortingState onSortingChange: (sorting: SortingState) => void } -export function DataTableSortList< - TFeatures extends TableFeatures, - TData extends RowData, ->({ +export function DataTableSortList({ table, sorting, onSortingChange, -}: DataTableSortListProps) { +}: DataTableSortListProps) { const labelId = React.useId() const descriptionId = React.useId() const listId = React.useId() diff --git a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-view-options.tsx b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-view-options.tsx index 5db610b966..a07f664db1 100644 --- a/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-view-options.tsx +++ b/examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-view-options.tsx @@ -4,10 +4,10 @@ import * as React from 'react' import { Check, ChevronsUpDown, GripVertical, Settings2 } from 'lucide-react' import type { ColumnOrderState, + ReactTable, RowData, - Table, - TableFeatures, } from '@tanstack/react-table' +import type { features } from '@/main' import { Button } from '@/components/ui/button' import { @@ -33,23 +33,17 @@ import { SortableOverlay, } from '@/components/ui/sortable' -interface DataTableViewOptionsProps< - TFeatures extends TableFeatures, - TRowData extends RowData, -> { - table: Table, TRowData> +interface DataTableViewOptionsProps { + table: ReactTable columnOrder: ColumnOrderState onColumnOrderChange: (columnOrder: ColumnOrderState) => void } -export function DataTableViewOptions< - TFeatures extends TableFeatures, - TRowData extends RowData, ->({ +export function DataTableViewOptions({ table, columnOrder, onColumnOrderChange, -}: DataTableViewOptionsProps) { +}: DataTableViewOptionsProps) { const triggerRef = React.useRef(null) return ( diff --git a/examples/svelte/sorting/src/App.svelte b/examples/svelte/sorting/src/App.svelte index b5105472ff..e0a9ac55af 100644 --- a/examples/svelte/sorting/src/App.svelte +++ b/examples/svelte/sorting/src/App.svelte @@ -4,18 +4,13 @@ FlexRender, createSortedRowModel, createTable, - rowSortingFeature, renderComponent, sortFns, - tableFeatures, } from '@tanstack/svelte-table' import Header from './Header.svelte' import './index.css' import { makeData, type Person } from './makeData' - - const features = tableFeatures({ - rowSortingFeature, - }) + import { features } from './tableHelper.svelte' const columns: ColumnDef[] = [ { diff --git a/examples/svelte/sorting/src/Header.svelte b/examples/svelte/sorting/src/Header.svelte index ba70c2c941..44a362d3c1 100644 --- a/examples/svelte/sorting/src/Header.svelte +++ b/examples/svelte/sorting/src/Header.svelte @@ -1,13 +1,14 @@ {#if header && header.column} diff --git a/packages/angular-table-devtools/src/index.ts b/packages/angular-table-devtools/src/index.ts index 224ae9fee8..dd1675931f 100644 --- a/packages/angular-table-devtools/src/index.ts +++ b/packages/angular-table-devtools/src/index.ts @@ -3,18 +3,17 @@ import * as plugin from './plugin' import * as Devtools from './TableDevtools' import * as inject from './injectTanStackTableDevtools' -export const TableDevtoolsPanel = isDevMode() - ? Devtools.TableDevtoolsPanel - : Devtools.TableDevtoolsPanelNoOp +export const TableDevtoolsPanel: typeof Devtools.TableDevtoolsPanel = + isDevMode() ? Devtools.TableDevtoolsPanel : Devtools.TableDevtoolsPanelNoOp -export const tableDevtoolsPlugin = isDevMode() - ? plugin.tableDevtoolsPlugin - : plugin.tableDevtoolsNoOpPlugin +export const tableDevtoolsPlugin: typeof plugin.tableDevtoolsPlugin = + isDevMode() ? plugin.tableDevtoolsPlugin : plugin.tableDevtoolsNoOpPlugin export type { TableDevtoolsAngularInit } from './TableDevtools' export type { InjectTanStackTableDevtoolsOptions } from './injectTanStackTableDevtools' -export const injectTanStackTableDevtools = isDevMode() - ? inject.injectTanStackTableDevtools - : inject.injectTanStackTableDevtoolsNoOp +export const injectTanStackTableDevtools: typeof inject.injectTanStackTableDevtools = + isDevMode() + ? inject.injectTanStackTableDevtools + : inject.injectTanStackTableDevtoolsNoOp diff --git a/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts b/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts index ecde7320a5..04c377a490 100644 --- a/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts +++ b/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts @@ -6,17 +6,21 @@ import { inject, untracked, } from '@angular/core' -import type { Table } from '@tanstack/table-core' +import type { RowData, Table, TableFeatures } from '@tanstack/table-core' -export interface InjectTanStackTableDevtoolsOptions { - table: Table | undefined +export interface InjectTanStackTableDevtoolsOptions< + TFeatures extends TableFeatures = TableFeatures, + TData extends RowData = RowData, +> { + table: Table | undefined enabled?: () => boolean injector?: Injector } -export function injectTanStackTableDevtools( - options: () => InjectTanStackTableDevtoolsOptions, -): void { +export function injectTanStackTableDevtools< + TFeatures extends TableFeatures = TableFeatures, + TData extends RowData = RowData, +>(options: () => InjectTanStackTableDevtoolsOptions): void { const enabled = () => options().enabled?.() ?? true assertInInjectionContext(injectTanStackTableDevtools) const injector = options().injector ?? inject(Injector) @@ -37,6 +41,7 @@ export function injectTanStackTableDevtools( ) } -export function injectTanStackTableDevtoolsNoOp( - _options: () => InjectTanStackTableDevtoolsOptions, -): void {} +export function injectTanStackTableDevtoolsNoOp< + TFeatures extends TableFeatures = TableFeatures, + TData extends RowData = RowData, +>(_options: () => InjectTanStackTableDevtoolsOptions): void {} diff --git a/packages/angular-table/src/helpers/cell.ts b/packages/angular-table/src/helpers/cell.ts index ae0526aa7b..d4e68680fd 100644 --- a/packages/angular-table/src/helpers/cell.ts +++ b/packages/angular-table/src/helpers/cell.ts @@ -23,7 +23,7 @@ export interface TanStackTableCellContext< * This token is provided by the {@link TanStackTableCell} directive. */ export const TanStackTableCellToken = new InjectionToken< - TanStackTableCellContext['cell'] + TanStackTableCellContext['cell'] >('[TanStack Table] CellContext') /** @@ -100,5 +100,9 @@ export function injectTableCellContext< TData extends RowData, TValue extends CellData, >(): TanStackTableCellContext['cell'] { - return inject(TanStackTableCellToken) + return inject(TanStackTableCellToken) as unknown as TanStackTableCellContext< + TFeatures, + TData, + TValue + >['cell'] } diff --git a/packages/angular-table/src/helpers/createTableHook.ts b/packages/angular-table/src/helpers/createTableHook.ts index 4253246332..f3c220582c 100644 --- a/packages/angular-table/src/helpers/createTableHook.ts +++ b/packages/angular-table/src/helpers/createTableHook.ts @@ -447,7 +447,7 @@ export function createTableHook< return footer as Header & THeaderComponents } - const appTableFeatures: TableFeature<{}> = { + const appTableFeatures: TableFeature = { constructTableAPIs: (table) => { Object.assign(table, tableComponents, { appCell, appHeader, appFooter }) }, @@ -467,8 +467,14 @@ export function createTableHook< ...defaultTableOptions.features, appTableFeatures, }, - } as TableOptions - }) as AngularTable + } as unknown as TableOptions + }) as unknown as AppAngularTable< + TFeatures, + TData, + TTableComponents, + TCellComponents, + THeaderComponents + > } function createAppColumnHelper(): AppColumnHelper< diff --git a/packages/angular-table/src/helpers/header.ts b/packages/angular-table/src/helpers/header.ts index bc3f188c33..4bb7425dd1 100644 --- a/packages/angular-table/src/helpers/header.ts +++ b/packages/angular-table/src/helpers/header.ts @@ -23,7 +23,7 @@ export interface TanStackTableHeaderContext< * This token is provided by the {@link TanStackTableHeader} directive. */ export const TanStackTableHeaderToken = new InjectionToken< - TanStackTableHeaderContext['header'] + TanStackTableHeaderContext['header'] >('[TanStack Table] HeaderContext') /** @@ -95,5 +95,7 @@ export function injectTableHeaderContext< TData extends RowData, TValue extends CellData, >(): TanStackTableHeaderContext['header'] { - return inject(TanStackTableHeaderToken) + return inject( + TanStackTableHeaderToken, + ) as unknown as TanStackTableHeaderContext['header'] } diff --git a/packages/angular-table/src/helpers/table.ts b/packages/angular-table/src/helpers/table.ts index ed1cde5d9c..5187b74cbf 100644 --- a/packages/angular-table/src/helpers/table.ts +++ b/packages/angular-table/src/helpers/table.ts @@ -9,7 +9,7 @@ import type { Signal } from '@angular/core' * This token is provided by the {@link TanStackTable} directive. */ export const TanStackTableToken = new InjectionToken< - Signal> + Signal> >('[TanStack Table] Table Context') /** @@ -81,5 +81,7 @@ export function injectTableContext< TFeatures extends TableFeatures, TData extends RowData, >(): Signal> { - return inject(TanStackTableToken) + return inject(TanStackTableToken) as unknown as Signal< + AngularTable + > } diff --git a/packages/angular-table/tests/injectTable.test.ts b/packages/angular-table/tests/injectTable.test.ts index 2f3fef0bed..0dd3d423d7 100644 --- a/packages/angular-table/tests/injectTable.test.ts +++ b/packages/angular-table/tests/injectTable.test.ts @@ -94,7 +94,7 @@ describe('injectTable', () => { })) TestBed.runInInjectionContext(() => { - const table = injectTable(() => ({ + const table = injectTable(() => ({ data, columns: columns, features: stockFeatures, diff --git a/packages/react-table-devtools/src/table-devtools.d.ts b/packages/react-table-devtools/src/table-devtools.d.ts index 8b1c5f07b2..e8b6b1d122 100644 --- a/packages/react-table-devtools/src/table-devtools.d.ts +++ b/packages/react-table-devtools/src/table-devtools.d.ts @@ -4,17 +4,30 @@ declare module '@tanstack/table-devtools' { export const TableDevtoolsCore: ClassType + export interface TableDevtoolsTable { + options: { + key?: string + [key: string]: unknown + } + } + export interface TableDevtoolsRegistration { id: string - table: Table + table: TableDevtoolsTable } - export interface UpsertTableDevtoolsTargetOptions { - table: Table + export interface UpsertTableDevtoolsTargetOptions< + TFeatures extends TableFeatures, + TData extends RowData, + > { + table: Table } - export function upsertTableDevtoolsTarget( - options: UpsertTableDevtoolsTargetOptions, + export function upsertTableDevtoolsTarget< + TFeatures extends TableFeatures, + TData extends RowData, + >( + options: UpsertTableDevtoolsTargetOptions, ): (() => void) | undefined export function removeTableDevtoolsTarget(id: string): void diff --git a/packages/react-table/src/useLegacyTable.ts b/packages/react-table/src/useLegacyTable.ts index cb32a1f8e5..c70baefacc 100644 --- a/packages/react-table/src/useLegacyTable.ts +++ b/packages/react-table/src/useLegacyTable.ts @@ -22,6 +22,7 @@ import type { Cell, Column, ColumnDef, + ColumnHelper, CreateRowModels_All, FilterFns, Header, @@ -342,7 +343,10 @@ export type LegacyTable = Table * A column helper with StockFeatures pre-bound for use with useLegacyTable. * Only requires TData—no need to specify TFeatures. */ -export function legacyCreateColumnHelper() { +export function legacyCreateColumnHelper(): ColumnHelper< + StockFeatures, + TData +> { return createColumnHelper() } diff --git a/packages/table-core/src/core/cells/coreCellsFeature.ts b/packages/table-core/src/core/cells/coreCellsFeature.ts index 2409d56ee0..e79384620d 100644 --- a/packages/table-core/src/core/cells/coreCellsFeature.ts +++ b/packages/table-core/src/core/cells/coreCellsFeature.ts @@ -4,46 +4,24 @@ import { 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' - -export interface CoreCellsFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Cell: Cell_Cell - // TableOptions: TableOptions_Cell -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock core cells feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Core feature that adds cell value, render, and context APIs. */ -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], - }, - }) - }, - } +export const coreCellsFeature: TableFeature = { + 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() diff --git a/packages/table-core/src/core/columns/coreColumnsFeature.ts b/packages/table-core/src/core/columns/coreColumnsFeature.ts index 738183b0a7..f21a2b3bfc 100644 --- a/packages/table-core/src/core/columns/coreColumnsFeature.ts +++ b/packages/table-core/src/core/columns/coreColumnsFeature.ts @@ -10,91 +10,64 @@ import { 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' - -export interface CoreColumnsFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Column: Column_Column - // Table: Table_Columns - // TableOptions: TableOptions_Columns -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock core columns feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Core feature that builds the column tree and exposes table/column column APIs. */ -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.atoms.columnOrder?.get(), - column.table.atoms.grouping?.get(), - column.table.options.columns, - column.table.options.groupedColumnMode, - ], - }, - }) - }, +export const coreColumnsFeature: TableFeature = { + 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.atoms.columnOrder?.get(), + column.table.atoms.grouping?.get(), + 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.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.columns, - table.options.groupedColumnMode, - ], - }, - table_getAllLeafColumnsById: { - fn: () => table_getAllLeafColumnsById(table), - memoDeps: () => [table.getAllLeafColumns()], - }, - table_getColumn: { - fn: (columnId) => table_getColumn(table, columnId), - }, - }) - }, - } + 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.atoms.columnOrder?.get(), + table.atoms.grouping?.get(), + table.options.columns, + table.options.groupedColumnMode, + ], + }, + table_getAllLeafColumnsById: { + fn: () => table_getAllLeafColumnsById(table), + memoDeps: () => [table.getAllLeafColumns()], + }, + table_getColumn: { + fn: (columnId) => table_getColumn(table, columnId), + }, + }) + }, } - -/** - * The Core Columns feature provides the core column functionality. - */ -export const coreColumnsFeature = constructCoreColumnsFeature() diff --git a/packages/table-core/src/core/headers/buildHeaderGroups.ts b/packages/table-core/src/core/headers/buildHeaderGroups.ts index b6e9ca5a0c..386858caee 100644 --- a/packages/table-core/src/core/headers/buildHeaderGroups.ts +++ b/packages/table-core/src/core/headers/buildHeaderGroups.ts @@ -60,7 +60,7 @@ export function buildHeaderGroups< depth, id: [headerFamily, `${depth}`].filter(Boolean).join('_'), headers: [], - } as any + } // The parent columns we're going to scan next const pendingParentHeaders: Array> = [] diff --git a/packages/table-core/src/core/headers/coreHeadersFeature.ts b/packages/table-core/src/core/headers/coreHeadersFeature.ts index 9e21258086..b8c7a214e4 100644 --- a/packages/table-core/src/core/headers/coreHeadersFeature.ts +++ b/packages/table-core/src/core/headers/coreHeadersFeature.ts @@ -7,72 +7,50 @@ import { 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' - -export interface CoreHeadersFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Header: Header_Header - // Table: Table_Headers -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock core headers feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Core feature that builds header groups and exposes header context APIs. */ -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], - }, - }) - }, +export const coreHeadersFeature: TableFeature = { + 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.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - 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: () => [table.getHeaderGroups()], - }, - }) - }, - } + constructTableAPIs: (table) => { + assignTableAPIs('coreHeadersFeature', table, { + table_getHeaderGroups: { + fn: () => table_getHeaderGroups(table), + memoDeps: () => [ + table.options.columns, + table.atoms.columnOrder?.get(), + table.atoms.grouping?.get(), + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + 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: () => [table.getHeaderGroups()], + }, + }) + }, } - -/** - * The Core Headers feature provides the core header functionality. - */ -export const coreHeadersFeature = constructCoreHeadersFeature() diff --git a/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts b/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts index ff1ea28f99..a6152c03ef 100644 --- a/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts +++ b/packages/table-core/src/core/headers/coreHeadersFeature.utils.ts @@ -86,7 +86,7 @@ export function table_getHeaderGroups< table, 'getVisibleLeafColumns', table_getVisibleLeafColumns, - ) as Array> + ) // Fast path: no columns are pinned — skip per-side lookups, partition, and spread. if (!left.length && !right.length) { diff --git a/packages/table-core/src/core/row-models/coreRowModelsFeature.ts b/packages/table-core/src/core/row-models/coreRowModelsFeature.ts index 4b78645141..8b1b32b729 100644 --- a/packages/table-core/src/core/row-models/coreRowModelsFeature.ts +++ b/packages/table-core/src/core/row-models/coreRowModelsFeature.ts @@ -13,71 +13,50 @@ import { 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' - -export interface CoreRowModelsFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Table: Table_RowModels -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock core row models feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Core feature that wires table row-model accessors and row-model caches. */ -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), - }, - }) - }, - } +export const coreRowModelsFeature: TableFeature = { + 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() diff --git a/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts b/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts index e060a571a2..1547053db8 100644 --- a/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts +++ b/packages/table-core/src/core/row-models/coreRowModelsFeature.types.ts @@ -18,12 +18,10 @@ export interface RowModel< rowsById: Record> } -export interface CreateRowModel_Plugins {} - export interface CreateRowModel_Core< TFeatures extends TableFeatures, TData extends RowData, -> extends CreateRowModel_Plugins { +> { /** * Optional factory for the core row model. When omitted, the built-in * `createCoreRowModel()` factory is used. @@ -33,12 +31,10 @@ export interface CreateRowModel_Core< ) => () => RowModel } -export interface CachedRowModel_Plugins {} - export interface CachedRowModel_Core< TFeatures extends TableFeatures, TData extends RowData, -> extends CachedRowModel_Plugins { +> { coreRowModel: () => RowModel } diff --git a/packages/table-core/src/core/row-models/createCoreRowModel.ts b/packages/table-core/src/core/row-models/createCoreRowModel.ts index 36f0397590..54653beefb 100644 --- a/packages/table-core/src/core/row-models/createCoreRowModel.ts +++ b/packages/table-core/src/core/row-models/createCoreRowModel.ts @@ -17,7 +17,7 @@ export function createCoreRowModel< TData extends RowData, >(): (table: Table) => () => RowModel { return (_table) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal return tableMemo({ feature: 'coreRowModelsFeature', table, diff --git a/packages/table-core/src/core/rows/coreRowsFeature.ts b/packages/table-core/src/core/rows/coreRowsFeature.ts index c8e149739d..94ded78286 100644 --- a/packages/table-core/src/core/rows/coreRowsFeature.ts +++ b/packages/table-core/src/core/rows/coreRowsFeature.ts @@ -11,79 +11,52 @@ import { 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' - -export interface CoreRowsFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Row: Row_Row - // TableOptions: TableOptions_Rows - // Table: Table_Rows -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock core rows feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Core feature that creates row APIs for values, cells, and tree traversal. */ -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), - }, - }) - }, - } +export const coreRowsFeature: TableFeature = { + 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() diff --git a/packages/table-core/src/core/table/constructTable.ts b/packages/table-core/src/core/table/constructTable.ts index edb524a88d..46152e6afb 100644 --- a/packages/table-core/src/core/table/constructTable.ts +++ b/packages/table-core/src/core/table/constructTable.ts @@ -7,7 +7,7 @@ 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' +import type { TableState, TableState_All } from '../../types/TableState' /** * Builds the initial table state from registered features and user initial state. @@ -44,7 +44,7 @@ export function constructTable< atoms: {}, } as Table_Internal - const featuresList: Array> = Object.values(table._features) + const featuresList: Array = Object.values(table._features) const defaultOptions = featuresList.reduce((obj, feature) => { return Object.assign(obj, feature.getDefaultTableOptions?.(table)) @@ -100,7 +100,7 @@ export function constructTable< ) const stateKeys = Object.keys(table.initialState) as Array< - string & keyof TableState + string & keyof TableState_All > for (let i = 0; i < stateKeys.length; i++) { @@ -115,11 +115,14 @@ export function constructTable< // create readonly derived atom: on each get(), read either external atom or base atom ;(table.atoms as any)[key] = _reactivity.createReadonlyAtom( () => { - const externalAtom = table.options.atoms?.[key] + const externalAtoms = table.options.atoms as + | Partial>> + | undefined + const externalAtom = externalAtoms?.[key] if (externalAtom) { return externalAtom.get() } - return table.baseAtoms[key].get() + return table.baseAtoms[key]!.get() }, { debugName: `table/atoms/${key}` }, ) @@ -130,10 +133,10 @@ export function constructTable< table.store = atomToStore( _reactivity.createReadonlyAtom( () => { - const snapshot = {} as TableState + const snapshot = {} as TableState & TableState_All for (let i = 0; i < stateKeys.length; i++) { const key = stateKeys[i]! - ;(snapshot as Record)[key] = table.atoms[key].get() + ;(snapshot as Record)[key] = table.atoms[key]!.get() } return snapshot }, diff --git a/packages/table-core/src/core/table/coreTablesFeature.ts b/packages/table-core/src/core/table/coreTablesFeature.ts index 0ea424db86..baa1ab7075 100644 --- a/packages/table-core/src/core/table/coreTablesFeature.ts +++ b/packages/table-core/src/core/table/coreTablesFeature.ts @@ -1,41 +1,19 @@ 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' - -export interface CoreTablesFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Table: Table_Table - // TableOptions: TableOptions_Table -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock core tables feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Core feature that adds base table instance APIs such as reset and setOptions. */ -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), - }, - }) - }, - } +export const coreTablesFeature: TableFeature = { + 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() diff --git a/packages/table-core/src/core/table/coreTablesFeature.utils.ts b/packages/table-core/src/core/table/coreTablesFeature.utils.ts index 0c0fb2c388..5289c68d98 100644 --- a/packages/table-core/src/core/table/coreTablesFeature.utils.ts +++ b/packages/table-core/src/core/table/coreTablesFeature.utils.ts @@ -59,7 +59,7 @@ export function table_reset< const keys = Object.keys(snap) as Array for (let i = 0; i < keys.length; i++) { const key = keys[i]! - ;(table.baseAtoms as any)[key].set(snap[key] as any) + ;(table.baseAtoms as any)[key].set(snap[key]) } }) } diff --git a/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts b/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts index 52fec0e3b1..193d1066dc 100644 --- a/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts +++ b/packages/table-core/src/features/column-faceting/columnFacetingFeature.ts @@ -11,110 +11,79 @@ import { 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' - -export interface ColumnFacetingFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // CachedRowModel: CachedRowModel_Faceted - // Column: Column_ColumnFaceting - // CreateRowModels: CreateRowModel_Faceted -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column faceting feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that derives faceted row models, unique values, and min/max values for filters. */ -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.atoms.columnFilters?.get(), - table.atoms.globalFilter?.get(), - 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), - }, - }) - }, +export const columnFacetingFeature: TableFeature = { + assignColumnPrototype: (prototype, table) => { + assignPrototypeAPIs('columnFacetingFeature', prototype, table, { + column_getFacetedRowModel: { + memoDeps: () => [ + table.getPreFilteredRowModel().rows, + table.atoms.columnFilters?.get(), + table.atoms.globalFilter?.get(), + table.getFilteredRowModel().rows, + ], + fn: (column) => column_getFacetedRowModel(column, column.table), + }, + column_getFacetedMinMaxValues: { + memoDeps: (column) => [ + callMemoOrStaticFn( + column, + 'getFacetedRowModel', + column_getFacetedRowModel, + column.table, + ).flatRows, + ], + fn: (column) => column_getFacetedMinMaxValues(column, column.table), + }, + column_getFacetedUniqueValues: { + memoDeps: (column) => [ + 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.atoms.columnFilters?.get(), - table.atoms.globalFilter?.get(), - 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), - }, - }) - }, - } + constructTableAPIs: (table) => { + assignTableAPIs('columnFacetingFeature', table, { + table_getGlobalFacetedRowModel: { + memoDeps: () => [ + table.getPreFilteredRowModel().rows, + table.atoms.columnFilters?.get(), + table.atoms.globalFilter?.get(), + 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 stock column faceting feature. - * - * Register this feature to add faceted row model, unique value, and min/max - * helpers for column and global filter UIs. - */ -export const columnFacetingFeature = constructColumnFacetingFeature() diff --git a/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts b/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts index c60726898b..8db098c064 100644 --- a/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts +++ b/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts @@ -18,7 +18,7 @@ export function createFacetedMinMaxValues< columnId: string, ) => () => undefined | [number, number] { return (_table, columnId) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', fn: (flatRows) => _createFacetedMinMaxValues(columnId, flatRows), diff --git a/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts b/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts index e4bd4aaf82..9c944aa2ab 100644 --- a/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts +++ b/packages/table-core/src/features/column-faceting/createFacetedRowModel.ts @@ -23,7 +23,7 @@ export function createFacetedRowModel< columnId: string, ) => () => RowModel { return (_table, columnId) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', table, diff --git a/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts b/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts index 45a8f38308..8c6ce5c86e 100644 --- a/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts +++ b/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts @@ -18,7 +18,7 @@ export function createFacetedUniqueValues< columnId: string, ) => () => Map { return (_table, columnId) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal return tableMemo({ feature: 'columnFacetingFeature', table, diff --git a/packages/table-core/src/features/column-filtering/columnFilteringFeature.ts b/packages/table-core/src/features/column-filtering/columnFilteringFeature.ts index 4914757de3..ac5d92bd6e 100644 --- a/packages/table-core/src/features/column-filtering/columnFilteringFeature.ts +++ b/packages/table-core/src/features/column-filtering/columnFilteringFeature.ts @@ -15,115 +15,72 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column filtering feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds per-column filtering state, options, and column/table filter APIs. */ -export function constructColumnFilteringFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - columnFilters: getDefaultColumnFiltersState(), - ...initialState, - } - }, +export const columnFilteringFeature: TableFeature = { + getInitialState: (initialState) => { + return { + columnFilters: getDefaultColumnFiltersState(), + ...initialState, + } + }, - getDefaultColumnDef: () => { - return { - filterFn: 'auto', - } - }, + getDefaultColumnDef: () => { + return { + filterFn: 'auto', + } + }, - getDefaultTableOptions: (table) => { - return { - onColumnFiltersChange: makeStateUpdater('columnFilters', table), - filterFromLeafRows: false, - maxLeafRowFilterDepth: 100, - } - }, + 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), - }, - }) - }, + 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 = {} - }, + 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), - }, - }) - }, - } + constructTableAPIs: (table) => { + assignTableAPIs('columnFilteringFeature', table, { + table_setColumnFilters: { + fn: (updater) => table_setColumnFilters(table, updater), + }, + table_resetColumnFilters: { + fn: (defaultState) => table_resetColumnFilters(table, defaultState), + }, + }) + }, } - -/** - * The stock column filtering feature. - * - * Register this feature to add column filter state, filter defaults, and - * table/row/column APIs for client-side or manual column filtering. Global - * filtering is provided by `globalFilteringFeature`. - */ -export const columnFilteringFeature = constructColumnFilteringFeature() diff --git a/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts b/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts index 4f70fa715b..a5c537597e 100644 --- a/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts +++ b/packages/table-core/src/features/column-filtering/columnFilteringFeature.utils.ts @@ -323,7 +323,7 @@ export function shouldAutoRemoveFilter< ) { return ( (filterFn && filterFn.autoRemove - ? filterFn.autoRemove(value, column) + ? filterFn.autoRemove(value, column as Column_Internal) : false) || typeof value === 'undefined' || (typeof value === 'string' && !value) diff --git a/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts b/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts index 5f7e0801a9..b4c16a1214 100644 --- a/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts +++ b/packages/table-core/src/features/column-filtering/createFilteredRowModel.ts @@ -31,7 +31,7 @@ export function createFilteredRowModel< filterFns: Record>, ): (table: Table) => () => RowModel { return (_table) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal if (!table._rowModelFns.filterFns) table._rowModelFns.filterFns = filterFns return tableMemo({ feature: 'columnFilteringFeature', diff --git a/packages/table-core/src/features/column-grouping/columnGroupingFeature.ts b/packages/table-core/src/features/column-grouping/columnGroupingFeature.ts index 8b8ec3f0aa..bff57c9f16 100644 --- a/packages/table-core/src/features/column-grouping/columnGroupingFeature.ts +++ b/packages/table-core/src/features/column-grouping/columnGroupingFeature.ts @@ -20,140 +20,96 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column grouping feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds column grouping state, aggregation defaults, and grouped row APIs. */ -export function constructColumnGroupingFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - grouping: getDefaultGroupingState(), - ...initialState, - } - }, +export const columnGroupingFeature: TableFeature = { + getInitialState: (initialState) => { + return { + grouping: getDefaultGroupingState(), + ...initialState, + } + }, - getDefaultColumnDef: () => { - return { - aggregatedCell: ({ getValue }: any) => getValue()?.toString?.() ?? null, - aggregationFn: 'auto', - } - }, + getDefaultColumnDef: () => { + return { + aggregatedCell: ({ getValue }: any) => getValue()?.toString?.() ?? null, + aggregationFn: 'auto', + } + }, - getDefaultTableOptions: (table) => { - return { - onGroupingChange: makeStateUpdater('grouping', table), - groupedColumnMode: 'reorder', - } - }, + 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), - }, - }) - }, + 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), - }, - }) - }, + 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), - }, - }) - }, + 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 = {} - }, + 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), - }, - }) - }, - } + constructTableAPIs: (table) => { + assignTableAPIs('columnGroupingFeature', table, { + table_setGrouping: { + fn: (updater) => table_setGrouping(table, updater), + }, + table_resetGrouping: { + fn: (defaultState) => table_resetGrouping(table, defaultState), + }, + }) + }, } - -/** - * The stock column grouping feature. - * - * Register this feature to add grouping state, aggregation defaults, grouped - * row-model support, and table/row/column/cell grouping APIs. - */ -export const columnGroupingFeature = constructColumnGroupingFeature() diff --git a/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts b/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts index a9c0a8db87..c93bf4d3b2 100644 --- a/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts +++ b/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts @@ -31,7 +31,7 @@ export function createGroupedRowModel< aggregationFns: Record>, ): (table: Table) => () => RowModel { return (_table) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal if (!table._rowModelFns.aggregationFns) table._rowModelFns.aggregationFns = aggregationFns return tableMemo({ diff --git a/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts b/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts index 5014f5a1de..0aeabc9ba8 100644 --- a/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts +++ b/packages/table-core/src/features/column-ordering/columnOrderingFeature.ts @@ -12,94 +12,62 @@ import { 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' - -export interface ColumnOrderingFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Column: Column_ColumnOrdering - // Table: Table_ColumnOrdering - // TableOptions: TableOptions_ColumnOrdering - // TableState: TableState_ColumnOrdering -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column ordering feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds column ordering state and APIs for ordering leaf columns. */ -export function constructColumnOrderingFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - columnOrder: getDefaultColumnOrderState(), - ...initialState, - } - }, +export const columnOrderingFeature: TableFeature = { + getInitialState: (initialState) => { + return { + columnOrder: getDefaultColumnOrderState(), + ...initialState, + } + }, - getDefaultTableOptions: (table) => { - return { - onColumnOrderChange: makeStateUpdater('columnOrder', table), - } - }, + 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.atoms.columnOrder?.get(), - column.table.atoms.columnPinning?.get(), - column.table.atoms.grouping?.get(), - column.table.atoms.columnVisibility?.get(), - ], - }, - column_getIsFirstColumn: { - fn: (column, position) => column_getIsFirstColumn(column, position), - }, - column_getIsLastColumn: { - fn: (column, position) => column_getIsLastColumn(column, position), - }, - }) - }, + assignColumnPrototype: (prototype, table) => { + assignPrototypeAPIs('columnOrderingFeature', prototype, table, { + column_getIndex: { + fn: (column, position) => column_getIndex(column, position), + memoDeps: (column, position) => [ + position, + column.table.atoms.columnOrder?.get(), + column.table.atoms.columnPinning?.get(), + column.table.atoms.grouping?.get(), + column.table.atoms.columnVisibility?.get(), + ], + }, + 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.atoms.columnOrder?.get(), - table.atoms.grouping?.get(), - table.options.groupedColumnMode, - ], - }, - }) - }, - } + 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.atoms.columnOrder?.get(), + table.atoms.grouping?.get(), + table.options.groupedColumnMode, + ], + }, + }) + }, } - -/** - * The stock column ordering feature. - * - * Register this feature to add column order state and APIs for deriving the - * ordered leaf column list alongside grouping and pinning. - */ -export const columnOrderingFeature = constructColumnOrderingFeature() diff --git a/packages/table-core/src/features/column-pinning/columnPinningFeature.ts b/packages/table-core/src/features/column-pinning/columnPinningFeature.ts index 2cb207737b..ebbba31045 100644 --- a/packages/table-core/src/features/column-pinning/columnPinningFeature.ts +++ b/packages/table-core/src/features/column-pinning/columnPinningFeature.ts @@ -38,315 +38,279 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column pinning feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds column pinning state and APIs for left, center, and right regions. */ -export function constructColumnPinningFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - columnPinning: { - ...getDefaultColumnPinningState(), - ...initialState.columnPinning, - }, - ...initialState, - } - }, +export const columnPinningFeature: TableFeature = { + getInitialState: (initialState) => { + return { + columnPinning: { + ...getDefaultColumnPinningState(), + ...initialState.columnPinning, + }, + ...initialState, + } + }, - getDefaultTableOptions: (table) => { - return { - onColumnPinningChange: makeStateUpdater('columnPinning', table), - } - }, + 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), - }, - }) - }, + 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.atoms.columnPinning?.get(), - row.table.atoms.columnVisibility?.get(), - ], - }, - row_getLeftVisibleCells: { - fn: (row) => row_getLeftVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - row.table.atoms.columnPinning?.get()?.left, - row.table.atoms.columnVisibility?.get(), - ], - }, - row_getRightVisibleCells: { - fn: (row) => row_getRightVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - row.table.atoms.columnPinning?.get()?.right, - row.table.atoms.columnVisibility?.get(), - ], - }, - }) - }, + assignRowPrototype: (prototype, table) => { + assignPrototypeAPIs('columnPinningFeature', prototype, table, { + row_getCenterVisibleCells: { + fn: (row) => row_getCenterVisibleCells(row), + memoDeps: (row) => [ + row.getAllCells(), + row.table.atoms.columnPinning?.get(), + row.table.atoms.columnVisibility?.get(), + ], + }, + row_getLeftVisibleCells: { + fn: (row) => row_getLeftVisibleCells(row), + memoDeps: (row) => [ + row.getAllCells(), + row.table.atoms.columnPinning?.get()?.left, + row.table.atoms.columnVisibility?.get(), + ], + }, + row_getRightVisibleCells: { + fn: (row) => row_getRightVisibleCells(row), + memoDeps: (row) => [ + row.getAllCells(), + row.table.atoms.columnPinning?.get()?.right, + row.table.atoms.columnVisibility?.get(), + ], + }, + }) + }, - 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.atoms.columnPinning?.get()?.left, - table.atoms.columnOrder?.get(), - ], - }, - table_getCenterHeaderGroups: { - fn: () => table_getCenterHeaderGroups(table), - memoDeps: () => [ - table.getAllColumns(), - callMemoOrStaticFn( - table, - 'getVisibleLeafColumns', - table_getVisibleLeafColumns, - ), - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getRightHeaderGroups: { - fn: () => table_getRightHeaderGroups(table), - memoDeps: () => [ - table.getAllColumns(), - callMemoOrStaticFn( - table, - 'getVisibleLeafColumns', - table_getVisibleLeafColumns, - ), - table.atoms.columnPinning?.get()?.right, - table.atoms.columnOrder?.get(), - ], - }, - // 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.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getRightLeafColumns: { - fn: () => table_getRightLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getCenterLeafColumns: { - fn: () => table_getCenterLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getPinnedLeafColumns: { - fn: (position) => table_getPinnedLeafColumns(table, position), - // must not memo here as it's just a shortcut function - }, - // visible leaf columns - table_getLeftVisibleLeafColumns: { - fn: () => table_getLeftVisibleLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getCenterVisibleLeafColumns: { - fn: () => table_getCenterVisibleLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getRightVisibleLeafColumns: { - fn: () => table_getRightVisibleLeafColumns(table), - memoDeps: () => [ - table.options.columns, - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - ], - }, - table_getPinnedVisibleLeafColumns: { - fn: (position) => table_getPinnedVisibleLeafColumns(table, position), - // must not memo here as it's just a shortcut function - }, - }) - }, - } + 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.atoms.columnPinning?.get()?.left, + table.atoms.columnOrder?.get(), + ], + }, + table_getCenterHeaderGroups: { + fn: () => table_getCenterHeaderGroups(table), + memoDeps: () => [ + table.getAllColumns(), + callMemoOrStaticFn( + table, + 'getVisibleLeafColumns', + table_getVisibleLeafColumns, + ), + table.atoms.columnPinning?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getRightHeaderGroups: { + fn: () => table_getRightHeaderGroups(table), + memoDeps: () => [ + table.getAllColumns(), + callMemoOrStaticFn( + table, + 'getVisibleLeafColumns', + table_getVisibleLeafColumns, + ), + table.atoms.columnPinning?.get()?.right, + table.atoms.columnOrder?.get(), + ], + }, + // 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.atoms.columnPinning?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getRightLeafColumns: { + fn: () => table_getRightLeafColumns(table), + memoDeps: () => [ + table.options.columns, + table.atoms.columnPinning?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getCenterLeafColumns: { + fn: () => table_getCenterLeafColumns(table), + memoDeps: () => [ + table.options.columns, + table.atoms.columnPinning?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getPinnedLeafColumns: { + fn: (position) => table_getPinnedLeafColumns(table, position), + // must not memo here as it's just a shortcut function + }, + // visible leaf columns + table_getLeftVisibleLeafColumns: { + fn: () => table_getLeftVisibleLeafColumns(table), + memoDeps: () => [ + table.options.columns, + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getCenterVisibleLeafColumns: { + fn: () => table_getCenterVisibleLeafColumns(table), + memoDeps: () => [ + table.options.columns, + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getRightVisibleLeafColumns: { + fn: () => table_getRightVisibleLeafColumns(table), + memoDeps: () => [ + table.options.columns, + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + table.atoms.columnOrder?.get(), + ], + }, + table_getPinnedVisibleLeafColumns: { + fn: (position) => table_getPinnedVisibleLeafColumns(table, position), + // must not memo here as it's just a shortcut function + }, + }) + }, } - -/** - * The stock column pinning feature. - * - * Register this feature to add column pinning state plus table, row, and column - * APIs for splitting columns into left, center, and right regions. - */ -export const columnPinningFeature = constructColumnPinningFeature() diff --git a/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts b/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts index 7700a01832..069063420d 100644 --- a/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts +++ b/packages/table-core/src/features/column-pinning/columnPinningFeature.utils.ts @@ -230,7 +230,7 @@ export function row_getLeftVisibleCells< const cell = allVisibleCells[columnId] if (cell) { // Assign position property directly to preserve prototype chain - cell.position = 'left' + ;(cell as any).position = 'left' cells.push(cell) } } @@ -266,7 +266,7 @@ export function row_getRightVisibleCells< const cell = allVisibleCells[columnId] if (cell) { // Assign position property directly to preserve prototype chain - cell.position = 'right' + ;(cell as any).position = 'right' cells.push(cell) } } @@ -550,7 +550,7 @@ export function table_getLeftFlatHeaders< for (let i = 0; i < leftHeaderGroups.length; i++) { const headers = leftHeaderGroups[i]!.headers for (let j = 0; j < headers.length; j++) { - result.push(headers[j]) + result.push(headers[j]!) } } return result @@ -579,7 +579,7 @@ export function table_getRightFlatHeaders< for (let i = 0; i < rightHeaderGroups.length; i++) { const headers = rightHeaderGroups[i]!.headers for (let j = 0; j < headers.length; j++) { - result.push(headers[j]) + result.push(headers[j]!) } } return result @@ -608,7 +608,7 @@ export function table_getCenterFlatHeaders< for (let i = 0; i < centerHeaderGroups.length; i++) { const headers = centerHeaderGroups[i]!.headers for (let j = 0; j < headers.length; j++) { - result.push(headers[j]) + result.push(headers[j]!) } } return result diff --git a/packages/table-core/src/features/column-resizing/columnResizingFeature.ts b/packages/table-core/src/features/column-resizing/columnResizingFeature.ts index 94f075741d..d1149600e6 100644 --- a/packages/table-core/src/features/column-resizing/columnResizingFeature.ts +++ b/packages/table-core/src/features/column-resizing/columnResizingFeature.ts @@ -11,89 +11,55 @@ import { 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' - -export interface ColumnResizingFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Column: Column_ColumnResizing - // Header: Header_ColumnResizing - // Table: Table_ColumnResizing - // TableOptions: TableOptions_ColumnResizing - // TableState: TableState_ColumnResizing -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column resizing feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds column resizing state, options, and resize handlers. */ -export function constructColumnResizingFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - columnResizing: getDefaultColumnResizingState(), - ...initialState, - } - }, +export const columnResizingFeature: TableFeature = { + getInitialState: (initialState) => { + return { + columnResizing: getDefaultColumnResizingState(), + ...initialState, + } + }, - getDefaultTableOptions: (table) => { - return { - columnResizeMode: 'onEnd', - columnResizeDirection: 'ltr', - onColumnResizingChange: makeStateUpdater('columnResizing', table), - } - }, + 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), - }, - }) - }, + 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), - }, - }) - }, + 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), - }, - }) - }, - } + constructTableAPIs: (table) => { + assignTableAPIs('columnResizingFeature', table, { + table_setColumnResizing: { + fn: (updater) => table_setColumnResizing(table, updater), + }, + table_resetHeaderSizeInfo: { + fn: (defaultState) => table_resetHeaderSizeInfo(table, defaultState), + }, + }) + }, } - -/** - * The stock column resizing feature. - * - * Register this feature with `columnSizingFeature` to add resize interaction - * state and APIs for drag-based column resizing. - */ -export const columnResizingFeature = constructColumnResizingFeature() diff --git a/packages/table-core/src/features/column-sizing/columnSizingFeature.ts b/packages/table-core/src/features/column-sizing/columnSizingFeature.ts index 8f34347c1c..fc2098cb92 100644 --- a/packages/table-core/src/features/column-sizing/columnSizingFeature.ts +++ b/packages/table-core/src/features/column-sizing/columnSizingFeature.ts @@ -19,164 +19,127 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column sizing feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds column sizing state, defaults, and size measurement APIs. */ -export function constructColumnSizingFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - columnSizing: getDefaultColumnSizingState(), - ...initialState, - } - }, +export const columnSizingFeature: TableFeature = { + getInitialState: (initialState) => { + return { + columnSizing: getDefaultColumnSizingState(), + ...initialState, + } + }, - getDefaultColumnDef: () => { - return getDefaultColumnSizingColumnDef() - }, + getDefaultColumnDef: () => { + return getDefaultColumnSizingColumnDef() + }, - getDefaultTableOptions: (table) => { - return { - onColumnSizingChange: makeStateUpdater('columnSizing', table), - } - }, + getDefaultTableOptions: (table) => { + return { + onColumnSizingChange: makeStateUpdater('columnSizing', table), + } + }, - assignColumnPrototype: (prototype, table) => { - assignPrototypeAPIs('columnSizingFeature', prototype, table, { - column_getSize: { - fn: (column) => column_getSize(column), - memoDeps: (column) => [ - table.options.columns, - table.atoms.columnSizing?.get()?.[column.id], // just this column's size state - ], - }, - column_getStart: { - fn: (column, position) => column_getStart(column, position), - memoDeps: (column, position) => [ - position, - table.options.columns, - table.atoms.columnSizing?.get(), - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - ], - }, - column_getAfter: { - fn: (column, position) => column_getAfter(column, position), - memoDeps: (column, position) => [ - position, - table.options.columns, - table.atoms.columnSizing?.get(), - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - ], - }, - column_resetSize: { - fn: (column) => column_resetSize(column), - }, - }) - }, + assignColumnPrototype: (prototype, table) => { + assignPrototypeAPIs('columnSizingFeature', prototype, table, { + column_getSize: { + fn: (column) => column_getSize(column), + memoDeps: (column) => [ + table.options.columns, + table.atoms.columnSizing?.get()?.[column.id], // just this column's size state + ], + }, + column_getStart: { + fn: (column, position) => column_getStart(column, position), + memoDeps: (column, position) => [ + position, + table.options.columns, + table.atoms.columnSizing?.get(), + table.atoms.columnOrder?.get(), + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + ], + }, + column_getAfter: { + fn: (column, position) => column_getAfter(column, position), + memoDeps: (column, position) => [ + position, + table.options.columns, + table.atoms.columnSizing?.get(), + table.atoms.columnOrder?.get(), + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + ], + }, + column_resetSize: { + fn: (column) => column_resetSize(column), + }, + }) + }, - assignHeaderPrototype: (prototype, table) => { - assignPrototypeAPIs('columnSizingFeature', prototype, table, { - header_getSize: { - fn: (header) => header_getSize(header), - memoDeps: (header) => [ - table.options.columns, - header.column.columns.length > 0 - ? table.atoms.columnSizing?.get() // must be all columns (sum child columns) - : table.atoms.columnSizing?.get()?.[header.column.id], // can just check it's associated column size state - ], - }, - header_getStart: { - fn: (header) => header_getStart(header), - memoDeps: (header, position) => [ - position, - table.options.columns, - table.atoms.columnSizing?.get(), - table.atoms.columnOrder?.get(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - ], - }, - }) - }, + assignHeaderPrototype: (prototype, table) => { + assignPrototypeAPIs('columnSizingFeature', prototype, table, { + header_getSize: { + fn: (header) => header_getSize(header), + memoDeps: (header) => [ + table.options.columns, + header.column.columns.length > 0 + ? table.atoms.columnSizing?.get() // must be all columns (sum child columns) + : table.atoms.columnSizing?.get()?.[header.column.id], // can just check it's associated column size state + ], + }, + header_getStart: { + fn: (header) => header_getStart(header), + memoDeps: (header, position) => [ + position, + table.options.columns, + table.atoms.columnSizing?.get(), + table.atoms.columnOrder?.get(), + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + ], + }, + }) + }, - 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), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], - }, - table_getLeftTotalSize: { - fn: () => table_getLeftTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], - }, - table_getCenterTotalSize: { - fn: () => table_getCenterTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], - }, - table_getRightTotalSize: { - fn: () => table_getRightTotalSize(table), - memoDeps: () => [ - table.atoms.columnSizing?.get(), - table.getHeaderGroups(), - ], - }, - }) - }, - } + 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), + memoDeps: () => [ + table.atoms.columnSizing?.get(), + table.getHeaderGroups(), + ], + }, + table_getLeftTotalSize: { + fn: () => table_getLeftTotalSize(table), + memoDeps: () => [ + table.atoms.columnSizing?.get(), + table.getHeaderGroups(), + ], + }, + table_getCenterTotalSize: { + fn: () => table_getCenterTotalSize(table), + memoDeps: () => [ + table.atoms.columnSizing?.get(), + table.getHeaderGroups(), + ], + }, + table_getRightTotalSize: { + fn: () => table_getRightTotalSize(table), + memoDeps: () => [ + table.atoms.columnSizing?.get(), + table.getHeaderGroups(), + ], + }, + }) + }, } - -/** - * The stock column sizing feature. - * - * Register this feature to add column width state and table, header, and column - * APIs for reading and resetting sizes. Column drag resizing lives in - * `columnResizingFeature`. - */ -export const columnSizingFeature = constructColumnSizingFeature() diff --git a/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts b/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts index 0f9bc40064..d0e2bbd8db 100644 --- a/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts +++ b/packages/table-core/src/features/column-visibility/columnVisibilityFeature.ts @@ -20,140 +20,103 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock column visibility feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds column visibility state and APIs for hiding and showing columns. */ -export function constructColumnVisibilityFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - columnVisibility: getDefaultColumnVisibilityState(), - ...initialState, - } - }, +export const columnVisibilityFeature: TableFeature = { + getInitialState: (initialState) => { + return { + columnVisibility: getDefaultColumnVisibilityState(), + ...initialState, + } + }, - getDefaultTableOptions: (table) => { - return { - onColumnVisibilityChange: makeStateUpdater('columnVisibility', table), - } - }, + getDefaultTableOptions: (table) => { + return { + onColumnVisibilityChange: makeStateUpdater('columnVisibility', table), + } + }, - assignColumnPrototype: (prototype, table) => { - assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { - column_getIsVisible: { - fn: (column) => column_getIsVisible(column), - memoDeps: (column) => [ - table.options.columns, - table.atoms.columnVisibility?.get(), - 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), - }, - }) - }, + assignColumnPrototype: (prototype, table) => { + assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { + column_getIsVisible: { + fn: (column) => column_getIsVisible(column), + memoDeps: (column) => [ + table.options.columns, + table.atoms.columnVisibility?.get(), + 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_getVisibleCells: { - fn: (row) => row_getVisibleCells(row), - memoDeps: (row) => [ - row.getAllCells(), - table.atoms.columnPinning?.get(), - table.atoms.columnVisibility?.get(), - ], - }, - row_getVisibleCellsByColumnId: { - fn: (row) => row_getVisibleCellsByColumnId(row), - memoDeps: (row) => [ - row.getAllCells(), - table.atoms.columnVisibility?.get(), - ], - }, - }) - }, + assignRowPrototype: (prototype, table) => { + assignPrototypeAPIs('columnVisibilityFeature', prototype, table, { + row_getVisibleCells: { + fn: (row) => row_getVisibleCells(row), + memoDeps: (row) => [ + row.getAllCells(), + table.atoms.columnPinning?.get(), + table.atoms.columnVisibility?.get(), + ], + }, + row_getVisibleCellsByColumnId: { + fn: (row) => row_getVisibleCellsByColumnId(row), + memoDeps: (row) => [ + row.getAllCells(), + table.atoms.columnVisibility?.get(), + ], + }, + }) + }, - constructTableAPIs: (table) => { - assignTableAPIs('columnVisibilityFeature', table, { - table_getVisibleFlatColumns: { - fn: () => table_getVisibleFlatColumns(table), - memoDeps: () => [ - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - table.options.columns, - ], - }, - table_getVisibleLeafColumns: { - fn: () => table_getVisibleLeafColumns(table), - memoDeps: () => [ - table.atoms.columnVisibility?.get(), - table.atoms.columnOrder?.get(), - 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), - }, - }) - }, - } + constructTableAPIs: (table) => { + assignTableAPIs('columnVisibilityFeature', table, { + table_getVisibleFlatColumns: { + fn: () => table_getVisibleFlatColumns(table), + memoDeps: () => [ + table.atoms.columnVisibility?.get(), + table.atoms.columnOrder?.get(), + table.options.columns, + ], + }, + table_getVisibleLeafColumns: { + fn: () => table_getVisibleLeafColumns(table), + memoDeps: () => [ + table.atoms.columnVisibility?.get(), + table.atoms.columnOrder?.get(), + 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 stock column visibility feature. - * - * Register this feature to add column visibility state and APIs for deriving - * visible columns and visible row cells. - */ -export const columnVisibilityFeature = constructColumnVisibilityFeature() diff --git a/packages/table-core/src/features/global-filtering/globalFilteringFeature.ts b/packages/table-core/src/features/global-filtering/globalFilteringFeature.ts index 56cf8c2df1..ef4f630c02 100644 --- a/packages/table-core/src/features/global-filtering/globalFilteringFeature.ts +++ b/packages/table-core/src/features/global-filtering/globalFilteringFeature.ts @@ -10,90 +10,56 @@ import { 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' - -export interface GlobalFilteringFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Column: Column_GlobalFiltering - // ColumnDef: ColumnDef_GlobalFiltering - // Table: Table_GlobalFiltering - // TableOptions: TableOptions_GlobalFiltering - // TableState: TableState_GlobalFiltering -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock global filtering feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds global filtering state, defaults, and global filter APIs. */ -export function constructGlobalFilteringFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - globalFilter: undefined, - ...initialState, - } - }, +export const globalFilteringFeature: TableFeature = { + 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() + 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' - }, - } - }, + return typeof value === 'string' || typeof value === 'number' + }, + } + }, - assignColumnPrototype: (prototype, table) => { - assignPrototypeAPIs('globalFilteringFeature', prototype, table, { - column_getCanGlobalFilter: { - fn: (column) => column_getCanGlobalFilter(column), - }, - }) - }, + 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), - }, - }) - }, - } + 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 stock global filtering feature. - * - * Register this feature with column filtering support to add global filter - * state, global filter function resolution, and column eligibility APIs. - */ -export const globalFilteringFeature = constructGlobalFilteringFeature() diff --git a/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts b/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts index f548653d1f..093b8fbed9 100644 --- a/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts +++ b/packages/table-core/src/features/row-expanding/createExpandedRowModel.ts @@ -16,7 +16,7 @@ export function createExpandedRowModel< TData extends RowData = any, >(): (table: Table) => () => RowModel { return (_table) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal return tableMemo({ feature: 'rowExpandingFeature', table, diff --git a/packages/table-core/src/features/row-expanding/rowExpandingFeature.ts b/packages/table-core/src/features/row-expanding/rowExpandingFeature.ts index 770754d1b8..4e22359d38 100644 --- a/packages/table-core/src/features/row-expanding/rowExpandingFeature.ts +++ b/packages/table-core/src/features/row-expanding/rowExpandingFeature.ts @@ -20,111 +20,75 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock row expanding feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds row expansion state and APIs for expandable row trees. */ -export function constructRowExpandingFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - expanded: getDefaultExpandedState(), - ...initialState, - } - }, +export const rowExpandingFeature: TableFeature = { + getInitialState: (initialState) => { + return { + expanded: getDefaultExpandedState(), + ...initialState, + } + }, - getDefaultTableOptions: (table) => { - return { - onExpandedChange: makeStateUpdater('expanded', table), - paginateExpandedRows: true, - } - }, + 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), - }, - }) - }, + 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), - }, - }) - }, - } + 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 stock row expanding feature. - * - * Register this feature to add expanded row state, row expansion APIs, and - * helpers for deriving expanded row models and expansion depth. - */ -export const rowExpandingFeature = constructRowExpandingFeature() diff --git a/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts b/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts index 3a93b96652..f6fd43c0a3 100644 --- a/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts +++ b/packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts @@ -17,7 +17,7 @@ export function createPaginatedRowModel< TData extends RowData = any, >(): (table: Table) => () => RowModel { return (_table) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal return tableMemo({ feature: 'rowPaginationFeature', table, diff --git a/packages/table-core/src/features/row-pagination/rowPaginationFeature.ts b/packages/table-core/src/features/row-pagination/rowPaginationFeature.ts index 41ce4164f5..c1475c758f 100644 --- a/packages/table-core/src/features/row-pagination/rowPaginationFeature.ts +++ b/packages/table-core/src/features/row-pagination/rowPaginationFeature.ts @@ -18,112 +18,78 @@ import { 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' - -export interface RowPaginationFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // CachedRowModel: CachedRowModel_Paginated - // CreateRowModels: CreateRowModel_Paginated - // Table: Table_RowPagination - // TableOptions: TableOptions_RowPagination - // TableState: TableState_RowPagination -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock row pagination feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds pagination state and table APIs for page navigation. */ -export function constructRowPaginationFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - ...initialState, - pagination: { - ...getDefaultPaginationState(), - ...initialState.pagination, - }, - } - }, +export const rowPaginationFeature: TableFeature = { + getInitialState: (initialState) => { + return { + ...initialState, + pagination: { + ...getDefaultPaginationState(), + ...initialState.pagination, + }, + } + }, - getDefaultTableOptions: (table) => { - return { - onPaginationChange: makeStateUpdater('pagination', table), - } - }, + 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), - }, - }) - }, - } + 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 stock row pagination feature. - * - * Register this feature to add pagination state, page navigation APIs, and - * pagination-aware row model helpers to a table. - */ -export const rowPaginationFeature = constructRowPaginationFeature() diff --git a/packages/table-core/src/features/row-pinning/rowPinningFeature.ts b/packages/table-core/src/features/row-pinning/rowPinningFeature.ts index 9b974f2ccb..cbd075e2b4 100644 --- a/packages/table-core/src/features/row-pinning/rowPinningFeature.ts +++ b/packages/table-core/src/features/row-pinning/rowPinningFeature.ts @@ -16,114 +16,82 @@ import { 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' - -export interface RowPinningFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Row: Row_RowPinning - // Table: Table_RowPinning - // TableOptions: TableOptions_RowPinning - // TableState: TableState_RowPinning -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock row pinning feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds row pinning state and APIs for top, center, and bottom rows. */ -export function constructRowPinningFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - ...initialState, - rowPinning: { - ...getDefaultRowPinningState(), - ...initialState.rowPinning, - }, - } - }, +export const rowPinningFeature: TableFeature = { + getInitialState: (initialState) => { + return { + ...initialState, + rowPinning: { + ...getDefaultRowPinningState(), + ...initialState.rowPinning, + }, + } + }, - getDefaultTableOptions: (table) => { - return { - onRowPinningChange: makeStateUpdater('rowPinning', table), - } - }, + 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.atoms.rowPinning?.get(), - ], - }, - row_pin: { - fn: (row, position, includeLeafRows, includeParentRows) => - row_pin(row, position, includeLeafRows, includeParentRows), - }, - }) - }, + 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.atoms.rowPinning?.get(), + ], + }, + 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.atoms.rowPinning?.get()?.top, - ], - }, - table_getBottomRows: { - fn: () => table_getBottomRows(table), - memoDeps: () => [ - table.getRowModel().rows, - table.atoms.rowPinning?.get()?.bottom, - ], - }, - table_getCenterRows: { - fn: () => table_getCenterRows(table), - memoDeps: () => [ - table.getRowModel().rows, - table.atoms.rowPinning?.get(), - ], - }, - }) - }, - } + 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.atoms.rowPinning?.get()?.top, + ], + }, + table_getBottomRows: { + fn: () => table_getBottomRows(table), + memoDeps: () => [ + table.getRowModel().rows, + table.atoms.rowPinning?.get()?.bottom, + ], + }, + table_getCenterRows: { + fn: () => table_getCenterRows(table), + memoDeps: () => [ + table.getRowModel().rows, + table.atoms.rowPinning?.get(), + ], + }, + }) + }, } - -/** - * The stock row pinning feature. - * - * Register this feature to add row pinning state and APIs for deriving top, - * center, and bottom row regions. - */ -export const rowPinningFeature = constructRowPinningFeature() diff --git a/packages/table-core/src/features/row-selection/rowSelectionFeature.ts b/packages/table-core/src/features/row-selection/rowSelectionFeature.ts index 0556be0579..691e9dadc3 100644 --- a/packages/table-core/src/features/row-selection/rowSelectionFeature.ts +++ b/packages/table-core/src/features/row-selection/rowSelectionFeature.ts @@ -28,145 +28,113 @@ import { 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' - -export interface RowSelectionFeatureConstructors< - TFeatures extends TableFeatures, - TData extends RowData, -> { - // Row: Row_RowSelection - // Table: Table_RowSelection - // TableOptions: TableOptions_RowSelection - // TableState: TableState_RowSelection -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock row selection feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds row selection state and APIs for row and page selection. */ -export function constructRowSelectionFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState: (initialState) => { - return { - rowSelection: getDefaultRowSelectionState(), - ...initialState, - } - }, +export const rowSelectionFeature: TableFeature = { + getInitialState: (initialState) => { + return { + rowSelection: getDefaultRowSelectionState(), + ...initialState, + } + }, - getDefaultTableOptions: (table) => { - return { - onRowSelectionChange: makeStateUpdater('rowSelection', table), - enableRowSelection: true, - enableMultiRowSelection: true, - enableSubRowSelection: true, - } - }, + 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), - }, - }) - }, + 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.atoms.rowSelection?.get(), - table.getCoreRowModel(), - ], - }, - table_getFilteredSelectedRowModel: { - fn: () => table_getFilteredSelectedRowModel(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - table.getFilteredRowModel(), - ], - }, - table_getGroupedSelectedRowModel: { - fn: () => table_getGroupedSelectedRowModel(table), - memoDeps: () => [ - table.atoms.rowSelection?.get(), - 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), - }, - }) - }, - } + 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.atoms.rowSelection?.get(), + table.getCoreRowModel(), + ], + }, + table_getFilteredSelectedRowModel: { + fn: () => table_getFilteredSelectedRowModel(table), + memoDeps: () => [ + table.atoms.rowSelection?.get(), + table.getFilteredRowModel(), + ], + }, + table_getGroupedSelectedRowModel: { + fn: () => table_getGroupedSelectedRowModel(table), + memoDeps: () => [ + table.atoms.rowSelection?.get(), + 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 stock row selection feature. - * - * Register this feature to add row selection state, selected row-model helpers, - * and table/row APIs for checkbox and bulk-selection UI. - */ -export const rowSelectionFeature = constructRowSelectionFeature() diff --git a/packages/table-core/src/features/row-sorting/createSortedRowModel.ts b/packages/table-core/src/features/row-sorting/createSortedRowModel.ts index 9bb8ab54ad..b6ab9ce83b 100644 --- a/packages/table-core/src/features/row-sorting/createSortedRowModel.ts +++ b/packages/table-core/src/features/row-sorting/createSortedRowModel.ts @@ -21,7 +21,7 @@ export function createSortedRowModel< sortFns: Record>, ): (table: Table) => () => RowModel { return (_table) => { - const table: Table_Internal = _table + const table = _table as unknown as Table_Internal if (!table._rowModelFns.sortFns) table._rowModelFns.sortFns = sortFns return tableMemo({ feature: 'rowSortingFeature', diff --git a/packages/table-core/src/features/row-sorting/rowSortingFeature.ts b/packages/table-core/src/features/row-sorting/rowSortingFeature.ts index f1df214cbd..a39b7b09e2 100644 --- a/packages/table-core/src/features/row-sorting/rowSortingFeature.ts +++ b/packages/table-core/src/features/row-sorting/rowSortingFeature.ts @@ -20,125 +20,84 @@ import { 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' - -export 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 -} +import type { TableFeature } from '../../types/TableFeatures' /** - * Creates the stock row sorting feature. - * - * The returned feature registers its state defaults, option defaults, and instance APIs so it can be included in a `tableFeatures({ ... })` call. + * Feature that adds row sorting state, defaults, and column/table sorting APIs. */ -export function constructRowSortingFeature< - TFeatures extends TableFeatures, - TData extends RowData, ->(): TableFeature> { - return { - getInitialState(initialState) { - return { - sorting: getDefaultSortingState(), - ...initialState, - } - }, +export const rowSortingFeature: TableFeature = { + getInitialState(initialState) { + return { + sorting: getDefaultSortingState(), + ...initialState, + } + }, - getDefaultColumnDef() { - return { - sortFn: 'auto', - sortUndefined: 1, - } - }, + getDefaultColumnDef() { + return { + sortFn: 'auto', + sortUndefined: 1, + } + }, - getDefaultTableOptions(table) { - return { - onSortingChange: makeStateUpdater('sorting', table), - isMultiSortEvent: (e: unknown) => { - return (e as MouseEvent).shiftKey - }, - } - }, + 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), - }, - }) - }, + 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), - }, - }) - }, - } + constructTableAPIs(table) { + assignTableAPIs('rowSortingFeature', table, { + table_setSorting: { + fn: (updater) => table_setSorting(table, updater), + }, + table_resetSorting: { + fn: (defaultState) => table_resetSorting(table, defaultState), + }, + }) + }, } - -/** - * The stock row sorting feature. - * - * Register this feature to add sorting state, column sorting APIs, and sorted - * row-model support for client-side or manual sorting. - */ -export const rowSortingFeature = constructRowSortingFeature() diff --git a/packages/table-core/src/fns/aggregationFns.ts b/packages/table-core/src/fns/aggregationFns.ts index e172e0098c..457296d35c 100755 --- a/packages/table-core/src/fns/aggregationFns.ts +++ b/packages/table-core/src/fns/aggregationFns.ts @@ -1,7 +1,6 @@ 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' /** * Sums numeric child-row values for a grouped column. @@ -9,14 +8,14 @@ import type { AggregationFn } from '../features/column-grouping/columnGroupingFe * Non-number values contribute `0`. Child rows are used so nested group totals * can reuse already aggregated values. */ -export const aggregationFn_sum: AggregationFn = < +export function aggregationFn_sum< TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, - _leafRows: Array>, - childRows: Array>, -) => { + _leafRows: Array>, + childRows: Array>, +) { // It's faster to just add the aggregations together instead of // process leaf nodes individually return childRows.reduce((sumValue, next) => { @@ -31,14 +30,14 @@ export const aggregationFn_sum: AggregationFn = < * Nullish and non-number values are ignored. Returns `undefined` when no * numeric value is found. */ -export const aggregationFn_min: AggregationFn = < +export function aggregationFn_min< TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, - _leafRows: Array>, - childRows: Array>, -) => { + _leafRows: Array>, + childRows: Array>, +) { let minValue: number | undefined childRows.forEach((row) => { @@ -62,14 +61,14 @@ export const aggregationFn_min: AggregationFn = < * Nullish and non-number values are ignored. Returns `undefined` when no * numeric value is found. */ -export const aggregationFn_max: AggregationFn = < +export function aggregationFn_max< TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, - _leafRows: Array>, - childRows: Array>, -) => { + _leafRows: Array>, + childRows: Array>, +) { let maxValue: number | undefined childRows.forEach((row) => { @@ -92,14 +91,14 @@ export const aggregationFn_max: AggregationFn = < * Returns `[min, max]`, where each entry is `undefined` when no numeric value is * present. */ -export const aggregationFn_extent: AggregationFn = < +export function aggregationFn_extent< TFeatures extends TableFeatures, TData extends RowData, >( columnId: string, - _leafRows: Array>, - childRows: Array>, -) => { + _leafRows: Array>, + childRows: Array>, +) { let minValue: number | undefined let maxValue: number | undefined @@ -124,13 +123,10 @@ export const aggregationFn_extent: AggregationFn = < * Number-like values are coerced with unary `+`; nullish and non-numeric values * are ignored. */ -export const aggregationFn_mean: AggregationFn = < +export function aggregationFn_mean< TFeatures extends TableFeatures, TData extends RowData, ->( - columnId: string, - leafRows: Array>, -) => { +>(columnId: string, leafRows: Array>) { let count = 0 let sumValue = 0 @@ -159,13 +155,10 @@ export const aggregationFn_mean: AggregationFn = < * All values must be numbers. If any value is non-numeric, or no leaf rows are * present, the result is `undefined`. */ -export const aggregationFn_median: AggregationFn = < +export function aggregationFn_median< TFeatures extends TableFeatures, TData extends RowData, ->( - columnId: string, - leafRows: Array>, -) => { +>(columnId: string, leafRows: Array>) { if (!leafRows.length) { return } @@ -193,13 +186,10 @@ export const aggregationFn_median: AggregationFn = < * * Values are compared with JavaScript `Set` semantics. */ -export const aggregationFn_unique: AggregationFn = < +export function aggregationFn_unique< TFeatures extends TableFeatures, TData extends RowData, ->( - columnId: string, - leafRows: Array>, -) => { +>(columnId: string, leafRows: Array>) { const set = new Set() for (let i = 0; i < leafRows.length; i++) { set.add(leafRows[i]!.getValue(columnId)) @@ -212,13 +202,10 @@ export const aggregationFn_unique: AggregationFn = < * * Values are compared with JavaScript `Set` semantics. */ -export const aggregationFn_uniqueCount: AggregationFn = < +export function aggregationFn_uniqueCount< TFeatures extends TableFeatures, TData extends RowData, ->( - columnId: string, - leafRows: Array>, -) => { +>(columnId: string, leafRows: Array>) { const set = new Set() for (let i = 0; i < leafRows.length; i++) { set.add(leafRows[i]!.getValue(columnId)) @@ -231,13 +218,10 @@ export const aggregationFn_uniqueCount: AggregationFn = < * * The column id is ignored because the result is based only on group size. */ -export const aggregationFn_count: AggregationFn = < +export function aggregationFn_count< TFeatures extends TableFeatures, TData extends RowData, ->( - _columnId: string, - leafRows: Array>, -) => { +>(_columnId: string, leafRows: Array>) { return leafRows.length } diff --git a/packages/table-core/src/fns/filterFns.ts b/packages/table-core/src/fns/filterFns.ts index 975e7f5e4d..44c4fb02d2 100644 --- a/packages/table-core/src/fns/filterFns.ts +++ b/packages/table-core/src/fns/filterFns.ts @@ -1,7 +1,6 @@ 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 @@ -10,18 +9,16 @@ import type { FilterFn } from '../features/column-filtering/columnFilteringFeatu * * Uses JavaScript `===` comparison and auto-removes empty filter values. */ -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) +export const filterFn_equals = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return row.getValue(columnId) === filterValue + }, + { autoRemove: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose column value is loosely equal to the filter value. @@ -29,18 +26,16 @@ filterFn_equals.autoRemove = (val: any) => testFalsy(val) * Uses JavaScript `==` comparison and auto-removes empty filter values. This is * useful for matching string input against numeric row values. */ -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) +export const filterFn_weakEquals = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return row.getValue(columnId) == filterValue + }, + { autoRemove: (val: any) => testFalsy(val) }, +) // String filters @@ -49,20 +44,18 @@ filterFn_weakEquals.autoRemove = (val: any) => testFalsy(val) * * Matching is case-sensitive and empty filter values are auto-removed. */ -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) +export const filterFn_includesStringSensitive = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return Boolean( + row.getValue(columnId)?.toString().includes(String(filterValue)), + ) + }, + { autoRemove: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose stringified column value includes the filter text. @@ -70,24 +63,22 @@ filterFn_includesStringSensitive.autoRemove = (val: any) => testFalsy(val) * Both values are lowercased before comparison, and empty filter values are * auto-removed. */ -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) +export const filterFn_includesString = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return Boolean( + row + .getValue(columnId) + ?.toString() + .toLowerCase() + .includes(String(filterValue).toLowerCase()), + ) + }, + { autoRemove: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose stringified column value equals the filter text. @@ -95,39 +86,35 @@ filterFn_includesString.autoRemove = (val: any) => testFalsy(val) * Both values are lowercased before comparison, and empty filter values are * auto-removed. */ -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) +export const filterFn_equalsString = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return ( + row.getValue(columnId)?.toString().toLowerCase() === + String(filterValue).toLowerCase() + ) + }, + { autoRemove: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose stringified column value exactly equals the filter text. * * Matching is case-sensitive and empty filter values are auto-removed. */ -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) +export const filterFn_equalsStringSensitive = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return row.getValue(columnId)?.toString() === String(filterValue) + }, + { autoRemove: (val: any) => testFalsy(val) }, +) // Number filters @@ -137,86 +124,78 @@ filterFn_equalsStringSensitive.autoRemove = (val: any) => testFalsy(val) * Numeric values are compared numerically when both sides can be coerced to * numbers; otherwise normalized strings are compared. */ -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) +export const filterFn_greaterThan = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + const rowValue = row.getValue(columnId) + const numericRowValue = + rowValue === null || rowValue === undefined ? 0 : +rowValue + const numericFilterValue = Number(filterValue) + + if (!isNaN(numericFilterValue) && !isNaN(numericRowValue)) { + return numericRowValue > numericFilterValue + } + + const stringValue = (rowValue ?? '').toString().toLowerCase().trim() + const stringFilterValue = String(filterValue).toLowerCase().trim() + return stringValue > stringFilterValue + }, + { resolveFilterValue: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose value is greater than or equal to the filter value. * * Delegates to the built-in greater-than and equality comparisons. */ -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) +export const filterFn_greaterThanOrEqualTo = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return ( + filterFn_greaterThan(row, columnId, filterValue) || + filterFn_equals(row, columnId, filterValue) + ) + }, + { resolveFilterValue: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose value is less than the filter value. * * This is implemented as the inverse of greater-than-or-equal comparison. */ -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) +export const filterFn_lessThan = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return !filterFn_greaterThanOrEqualTo(row, columnId, filterValue) + }, + { resolveFilterValue: (val: any) => testFalsy(val) }, +) /** * Keeps rows whose value is less than or equal to the filter value. * * This is implemented as the inverse of greater-than comparison. */ -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) +export const filterFn_lessThanOrEqualTo = Object.assign( + ( + row: Row, + columnId: string, + filterValue: unknown, + ) => { + return !filterFn_greaterThan(row, columnId, filterValue) + }, + { resolveFilterValue: (val: any) => testFalsy(val) }, +) // Range filters @@ -225,46 +204,42 @@ filterFn_lessThanOrEqualTo.resolveFilterValue = (val: any) => testFalsy(val) * * Blank range endpoints are treated as open-ended. */ -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 +const filterFn_between = Object.assign( + ( + row: Row, + columnId: string, + filterValues: [unknown, unknown], + ): boolean => + ((['', undefined] as Array).includes(filterValues[0]) || + filterFn_greaterThan(row, columnId, filterValues[0])) && + ((!isNaN(Number(filterValues[0])) && + !isNaN(Number(filterValues[1])) && + Number(filterValues[0]) > Number(filterValues[1])) || + (['', undefined] as Array).includes(filterValues[1]) || + filterFn_lessThan(row, columnId, filterValues[1])), + { autoRemove: (val: any) => !val }, +) /** * Keeps rows whose value falls between an inclusive min/max pair. * * Blank range endpoints are treated as open-ended. */ -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 +const filterFn_betweenInclusive = Object.assign( + ( + row: Row, + columnId: string, + filterValues: [unknown, unknown], + ): boolean => + ((['', undefined] as Array).includes(filterValues[0]) || + filterFn_greaterThanOrEqualTo(row, columnId, filterValues[0])) && + ((!isNaN(Number(filterValues[0])) && + !isNaN(Number(filterValues[1])) && + Number(filterValues[0]) > Number(filterValues[1])) || + (['', undefined] as Array).includes(filterValues[1]) || + filterFn_lessThanOrEqualTo(row, columnId, filterValues[1])), + { autoRemove: (val: any) => !val }, +) /** * Keeps rows whose numeric value is inside an inclusive `[min, max]` range. @@ -272,50 +247,50 @@ filterFn_betweenInclusive.autoRemove = (val: any) => !val * Filter values are normalized so blank endpoints become open-ended and * reversed endpoints are swapped. */ -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])) +export const filterFn_inNumberRange = Object.assign( + ( + row: Row, + columnId: string, + filterValue: [number, number], + ) => { + const [min, max] = filterValue + + const rowValue: number = row.getValue(columnId) + return rowValue >= min && rowValue <= max + }, + { + 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 + }, + autoRemove: (val: any) => + testFalsy(val) || (testFalsy(val[0]) && testFalsy(val[1])), + }, +) // Array filters /** * Keeps rows whose scalar column value equals at least one filter value. */ -export const filterFn_arrHas: FilterFn = < +export const filterFn_arrHas = < TFeatures extends TableFeatures, TData extends RowData, >( @@ -329,60 +304,52 @@ export const filterFn_arrHas: FilterFn = < /** * Keeps rows whose array or string column value includes at least one filter 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 +export const filterFn_arrIncludes = Object.assign( + ( + row: Row, + columnId: string, + filterValue: Array, + ) => { + return filterValue.some((val) => + (row.getValue(columnId) as Array | string).includes( + val as any, + ), + ) + }, + { autoRemove: (val: any) => testFalsy(val) || !val?.length }, +) /** * Keeps rows whose array column value includes every filter value. */ -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 +export const filterFn_arrIncludesAll = Object.assign( + ( + row: Row, + columnId: string, + filterValue: Array, + ) => { + const value = row.getValue>(columnId) + if (!Array.isArray(value)) return false + return !filterValue.some((val) => !value.includes(val)) + }, + { autoRemove: (val: any) => testFalsy(val) || !val?.length }, +) /** * Keeps rows whose array column value includes at least one filter value. */ -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 const filterFn_arrIncludesSome = Object.assign( + ( + row: Row, + columnId: string, + filterValue: Array, + ) => { + const value = row.getValue>(columnId) + if (!Array.isArray(value)) return false + return filterValue.some((val) => value.includes(val)) + }, + { autoRemove: (val: any) => testFalsy(val) || !val?.length }, +) // Export diff --git a/packages/table-core/src/fns/sortFns.ts b/packages/table-core/src/fns/sortFns.ts index c680e874d7..84889cb934 100644 --- a/packages/table-core/src/fns/sortFns.ts +++ b/packages/table-core/src/fns/sortFns.ts @@ -1,7 +1,6 @@ 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' /** * Regular expression used to split mixed text and numeric chunks. @@ -16,12 +15,12 @@ export const reSplitAlphaNumeric = /([0-9]+)/gm * * This comparator returns ascending-order results; descending order is applied by the sorting row model. */ -export const sortFn_alphanumeric: SortFn = < +export const sortFn_alphanumeric = < TFeatures extends TableFeatures, TData extends RowData, >( - rowA: Row, - rowB: Row, + rowA: Row, + rowB: Row, columnId: string, ) => { return compareAlphanumeric( @@ -35,12 +34,12 @@ export const sortFn_alphanumeric: SortFn = < * * This comparator returns ascending-order results; descending order is applied by the sorting row model. */ -export const sortFn_alphanumericCaseSensitive: SortFn = < +export const sortFn_alphanumericCaseSensitive = < TFeatures extends TableFeatures, TData extends RowData, >( - rowA: Row, - rowB: Row, + rowA: Row, + rowB: Row, columnId: string, ) => { return compareAlphanumeric( @@ -56,12 +55,12 @@ export const sortFn_alphanumericCaseSensitive: SortFn = < * * This comparator returns ascending-order results; descending order is applied by the sorting row model. */ -export const sortFn_text: SortFn = < +export const sortFn_text = < TFeatures extends TableFeatures, TData extends RowData, >( - rowA: Row, - rowB: Row, + rowA: Row, + rowB: Row, columnId: string, ) => { return compareBasic( @@ -77,12 +76,12 @@ export const sortFn_text: SortFn = < * * This comparator returns ascending-order results; descending order is applied by the sorting row model. */ -export const sortFn_textCaseSensitive: SortFn = < +export const sortFn_textCaseSensitive = < TFeatures extends TableFeatures, TData extends RowData, >( - rowA: Row, - rowB: Row, + rowA: Row, + rowB: Row, columnId: string, ) => { return compareBasic( @@ -96,12 +95,12 @@ export const sortFn_textCaseSensitive: SortFn = < * * This comparator returns ascending-order results; descending order is applied by the sorting row model. */ -export const sortFn_datetime: SortFn = < +export const sortFn_datetime = < TFeatures extends TableFeatures, TData extends RowData, >( - rowA: Row, - rowB: Row, + rowA: Row, + rowB: Row, columnId: string, ) => { const a: number | string = rowA.getValue(columnId) @@ -118,12 +117,12 @@ export const sortFn_datetime: SortFn = < * * This comparator returns ascending-order results; descending order is applied by the sorting row model. */ -export const sortFn_basic: SortFn = < +export const sortFn_basic = < TFeatures extends TableFeatures, TData extends RowData, >( - rowA: Row, - rowB: Row, + rowA: Row, + rowB: Row, columnId: string, ) => { return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId)) diff --git a/packages/table-core/src/types/Cell.ts b/packages/table-core/src/types/Cell.ts index 4386a9b321..1c17789ca8 100644 --- a/packages/table-core/src/types/Cell.ts +++ b/packages/table-core/src/types/Cell.ts @@ -1,22 +1,8 @@ import type { Cell_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { CellData, RowData } from './type-utils' -import type { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' +import type { ExtractFeatureMapTypes, 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, @@ -31,7 +17,5 @@ export type Cell< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, -> = Cell_Cell & - ExtractFeatureMapTypes & - ExtractFeatureTypes<'Cell', TFeatures> & - Cell_Plugins +> = Cell_Core & + ExtractFeatureMapTypes diff --git a/packages/table-core/src/types/Column.ts b/packages/table-core/src/types/Column.ts index 56e3a707b3..541b13ce62 100644 --- a/packages/table-core/src/types/Column.ts +++ b/packages/table-core/src/types/Column.ts @@ -10,23 +10,9 @@ import type { Column_ColumnSizing } from '../features/column-sizing/columnSizing import type { Column_ColumnVisibility } from '../features/column-visibility/columnVisibilityFeature.types' import type { ColumnDefBase_All } from './ColumnDef' import type { RowData } from './type-utils' -import type { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' +import type { ExtractFeatureMapTypes, 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, @@ -54,9 +40,7 @@ export type Column< TData extends RowData, TValue = unknown, > = Column_Core & - ExtractFeatureMapTypes> & - ExtractFeatureTypes<'Column', TFeatures> & - Column_Plugins + ExtractFeatureMapTypes> export type Column_Internal< TFeatures extends TableFeatures, diff --git a/packages/table-core/src/types/ColumnDef.ts b/packages/table-core/src/types/ColumnDef.ts index 6520c52dd9..9877741ad4 100644 --- a/packages/table-core/src/types/ColumnDef.ts +++ b/packages/table-core/src/types/ColumnDef.ts @@ -1,9 +1,5 @@ import type { CellData, RowData, UnionToIntersection } from './type-utils' -import type { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' +import type { ExtractFeatureMapTypes, 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' @@ -15,16 +11,6 @@ import type { ColumnDef_ColumnVisibility } from '../features/column-visibility/c 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, @@ -137,9 +123,7 @@ export type ColumnDefBase< ExtractFeatureMapTypes< TFeatures, ColumnDef_FeatureMap - > & - ExtractFeatureTypes<'ColumnDef', TFeatures> & - ColumnDef_Plugins + > export type ColumnDefBase_All< TFeatures extends TableFeatures, diff --git a/packages/table-core/src/types/Header.ts b/packages/table-core/src/types/Header.ts index f5c3c0fb86..39aa608a26 100644 --- a/packages/table-core/src/types/Header.ts +++ b/packages/table-core/src/types/Header.ts @@ -1,23 +1,9 @@ import type { Header_ColumnSizing } from '../features/column-sizing/columnSizingFeature.types' import type { CellData, RowData } from './type-utils' -import type { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' +import type { ExtractFeatureMapTypes, 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, @@ -34,6 +20,4 @@ export type Header< TData extends RowData, TValue extends CellData = CellData, > = Header_Core & - ExtractFeatureMapTypes & - ExtractFeatureTypes<'Header', TFeatures> & - Header_Plugins + ExtractFeatureMapTypes diff --git a/packages/table-core/src/types/HeaderGroup.ts b/packages/table-core/src/types/HeaderGroup.ts index 4290be490e..b09509bf8c 100644 --- a/packages/table-core/src/types/HeaderGroup.ts +++ b/packages/table-core/src/types/HeaderGroup.ts @@ -1,16 +1,7 @@ import type { HeaderGroup_Header } from '../core/headers/coreHeadersFeature.types' -import type { ExtractFeatureTypes, TableFeatures } from './TableFeatures' +import type { 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, @@ -19,6 +10,4 @@ export interface HeaderGroup_Core< export type HeaderGroup< TFeatures extends TableFeatures, TData extends RowData, -> = HeaderGroup_Core & - ExtractFeatureTypes<'HeaderGroup', TFeatures> & - HeaderGroup_Plugins +> = HeaderGroup_Core diff --git a/packages/table-core/src/types/Row.ts b/packages/table-core/src/types/Row.ts index dc638287a9..aa2051f04a 100644 --- a/packages/table-core/src/types/Row.ts +++ b/packages/table-core/src/types/Row.ts @@ -6,22 +6,9 @@ import type { RowData } 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 { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' +import type { ExtractFeatureMapTypes, 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, @@ -44,6 +31,4 @@ export type Row< TFeatures extends TableFeatures, TData extends RowData, > = Row_Core & - ExtractFeatureMapTypes> & - ExtractFeatureTypes<'Row', TFeatures> & - Row_Plugins + ExtractFeatureMapTypes> diff --git a/packages/table-core/src/types/RowModel.ts b/packages/table-core/src/types/RowModel.ts index 341845fd62..ae3bc30c43 100644 --- a/packages/table-core/src/types/RowModel.ts +++ b/packages/table-core/src/types/RowModel.ts @@ -28,20 +28,7 @@ import type { CreateRowModel_Sorted, } from '../features/row-sorting/rowSortingFeature.types' import type { RowData } from './type-utils' -import type { - ExtractFeatureMapTypes, - 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, -> {} +import type { ExtractFeatureMapTypes, TableFeatures } from './TableFeatures' export interface CreateRowModels_FeatureMap< TFeatures extends TableFeatures, @@ -62,9 +49,7 @@ export type CreateRowModels< ExtractFeatureMapTypes< TFeatures, CreateRowModels_FeatureMap - > & - ExtractFeatureTypes<'CreateRowModels', TFeatures> & - CreateRowModels_Plugins + > export type CreateRowModels_All< TFeatures extends TableFeatures, @@ -77,11 +62,6 @@ export type CreateRowModels_All< CreateRowModel_Paginated & CreateRowModel_Sorted -export interface CachedRowModels_Plugins< - TFeatures extends TableFeatures, - TData extends RowData, -> {} - export interface CachedRowModels_FeatureMap< TFeatures extends TableFeatures, TData extends RowData, @@ -102,9 +82,7 @@ export type CachedRowModels< } & ExtractFeatureMapTypes< TFeatures, CachedRowModels_FeatureMap -> & - ExtractFeatureTypes<'CachedRowModel', TFeatures> & - CachedRowModels_Plugins +> export type CachedRowModel_All< TFeatures extends TableFeatures, diff --git a/packages/table-core/src/types/RowModelFns.ts b/packages/table-core/src/types/RowModelFns.ts index 07c3e60c9a..bdeea67462 100644 --- a/packages/table-core/src/types/RowModelFns.ts +++ b/packages/table-core/src/types/RowModelFns.ts @@ -2,20 +2,7 @@ import type { RowModelFns_RowSorting } from '../features/row-sorting/rowSortingF import type { RowModelFns_ColumnGrouping } from '../features/column-grouping/columnGroupingFeature.types' import type { RowData } from './type-utils' import type { RowModelFns_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types' -import type { - ExtractFeatureMapTypes, - 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, -> {} +import type { ExtractFeatureMapTypes, TableFeatures } from './TableFeatures' export interface RowModelFns_Core {} @@ -32,9 +19,7 @@ export type RowModelFns< TFeatures extends TableFeatures, TData extends RowData, > = Partial< - ExtractFeatureMapTypes> & - ExtractFeatureTypes<'RowModelFns', TFeatures> & - RowModelFns_Plugins + ExtractFeatureMapTypes> > export type RowModelFns_All< diff --git a/packages/table-core/src/types/Table.ts b/packages/table-core/src/types/Table.ts index a6b8de6883..80cb3714f6 100644 --- a/packages/table-core/src/types/Table.ts +++ b/packages/table-core/src/types/Table.ts @@ -18,11 +18,7 @@ import type { CachedRowModel_All, CreateRowModels_All } from './RowModel' import type { RowModelFns_All } from './RowModelFns' import type { TableState_All } from './TableState' import type { RowData } from './type-utils' -import type { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' +import type { ExtractFeatureMapTypes, 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' @@ -34,15 +30,6 @@ import type { } 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. @@ -83,9 +70,7 @@ export type Table< TFeatures extends TableFeatures, TData extends RowData, > = Table_Core & - ExtractFeatureMapTypes> & - ExtractFeatureTypes<'Table', TFeatures> & - Table_Plugins + ExtractFeatureMapTypes> export type Table_Internal< TFeatures extends TableFeatures, diff --git a/packages/table-core/src/types/TableFeatures.ts b/packages/table-core/src/types/TableFeatures.ts index 9813a3d1ed..dbc8cd0272 100644 --- a/packages/table-core/src/types/TableFeatures.ts +++ b/packages/table-core/src/types/TableFeatures.ts @@ -7,22 +7,10 @@ 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]: K extends 'coreReativityFeature' - ? never - : TFeatures[K] extends TableFeature - ? TKey extends keyof FeatureConstructorOptions - ? FeatureConstructorOptions[TKey] - : never - : any - }[keyof TFeatures] -> - type IsAny = 0 extends 1 & T ? true : false +type UnionToIntersectionOrEmpty = [T] extends [never] + ? {} + : UnionToIntersection & {} export type ExtractFeatureMapTypes< TFeatures extends TableFeatures, @@ -30,133 +18,84 @@ export type ExtractFeatureMapTypes< > = IsAny extends true ? UnionToIntersection - : UnionToIntersection< + : UnionToIntersectionOrEmpty< TFeatureMap[Extract] > -export 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 { +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 + assignCellPrototype?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + prototype: Record, + table: Table_Internal, + ) => void /** * 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 + assignColumnPrototype?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + prototype: Record, + table: Table_Internal, + ) => void /** * 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 + assignHeaderPrototype?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + prototype: Record, + table: Table_Internal, + ) => void /** * 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 + assignRowPrototype?: ( + prototype: Record, + table: Table_Internal, + ) => void /** * 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 + constructTableAPIs?: ( + table: Table_Internal, + ) => void + getDefaultColumnDef?: < + TFeatures extends TableFeatures, + TData extends RowData, + TValue extends CellData = CellData, + >() => ColumnDefBase_All + getDefaultTableOptions?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + table: Table_Internal, + ) => Partial> + getInitialState?: (initialState: Partial) => TableState_All /** * Initializes instance-specific data on each row (e.g., caches). * Methods should be assigned via assignRowPrototype instead. */ - initRowInstanceData?: InitRowInstanceData + initRowInstanceData?: < + TFeatures extends TableFeatures, + TData extends RowData, + >( + row: Row, + ) => void } diff --git a/packages/table-core/src/types/TableOptions.ts b/packages/table-core/src/types/TableOptions.ts index 36fd0aebff..9a9b48a1bd 100644 --- a/packages/table-core/src/types/TableOptions.ts +++ b/packages/table-core/src/types/TableOptions.ts @@ -17,16 +17,7 @@ import type { TableOptions_RowPinning } from '../features/row-pinning/rowPinning 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 { - ExtractFeatureMapTypes, - ExtractFeatureTypes, - TableFeatures, -} from './TableFeatures' - -export interface TableOptions_Plugins< - TFeatures extends TableFeatures, - TData extends RowData, -> {} +import type { ExtractFeatureMapTypes, TableFeatures } from './TableFeatures' /** * Core options that are always available on a table, before optional feature @@ -97,8 +88,6 @@ export type TableOptions< TData extends RowData, > = TableOptions_Core & ExtractFeatureMapTypes> & - ExtractFeatureTypes<'TableOptions', TFeatures> & - TableOptions_Plugins & DebugOptions /** diff --git a/packages/table-core/src/types/TableState.ts b/packages/table-core/src/types/TableState.ts index 188aae77c7..d8459df545 100644 --- a/packages/table-core/src/types/TableState.ts +++ b/packages/table-core/src/types/TableState.ts @@ -11,17 +11,7 @@ import type { TableState_RowPagination } from '../features/row-pagination/rowPag 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 { - ExtractFeatureMapTypes, - 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 {} +import type { ExtractFeatureMapTypes, TableFeatures } from './TableFeatures' export interface TableState_FeatureMap { columnFilteringFeature: TableState_ColumnFiltering @@ -46,28 +36,12 @@ export interface TableState_FeatureMap { * then custom feature/plugin state is mixed in. */ export type TableState = - ExtractFeatureMapTypes & - ExtractFeatureTypes<'TableState', TFeatures> & - TableState_Plugins + ExtractFeatureMapTypes /** - * Internal broad state shape containing every stock feature state slice. + * Internal broad state shape containing every registered feature state slice. * * Feature internals use this when they may need to inspect optional slices owned * by other features. */ -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 -> +export type TableState_All = Partial> diff --git a/packages/table-core/src/utils.ts b/packages/table-core/src/utils.ts index 5e42b11ef0..d0d3e52389 100755 --- a/packages/table-core/src/utils.ts +++ b/packages/table-core/src/utils.ts @@ -427,13 +427,14 @@ export function assignPrototypeAPIs< */ export function callMemoOrStaticFn< TObject extends Record, - TStaticFn extends AnyFunction, + TArgs extends Array, + TReturn, >( obj: TObject, fnKey: string, - staticFn: TStaticFn, - ...args: Parameters extends [any, ...infer Rest] ? Rest : never -): ReturnType { + staticFn: (obj: TObject, ...args: TArgs) => TReturn, + ...args: TArgs +): TReturn { return ( (obj[fnKey] as Function | undefined)?.(...args) ?? staticFn(obj, ...args) ) diff --git a/packages/table-core/tests/helpers/generateTestTable.ts b/packages/table-core/tests/helpers/generateTestTable.ts index 7977fd2f8a..2a4c5ca9ac 100644 --- a/packages/table-core/tests/helpers/generateTestTable.ts +++ b/packages/table-core/tests/helpers/generateTestTable.ts @@ -4,10 +4,10 @@ import { generateTestData } from '../fixtures/data/generateTestData' import { storeReactivityBindings } from '../../src/store-reactivity-bindings' import type { Row, - Table, TableFeatures, TableOptions, TableState, + Table_Internal, } from '../../src' import type { Person } from '../fixtures/data/types' @@ -17,9 +17,9 @@ export function generateTestTableWithData( TableOptions, 'data' | 'columns' | 'features' > & { - features?: TableFeatures + features?: TFeatures }, -): Table { +): Table_Internal { const lengthsArray = Array.isArray(lengths) ? lengths : [lengths] const data = generateTestData(...lengthsArray) const columns = generateTestColumnDefs(data) @@ -34,15 +34,15 @@ export function generateTestTableWithData( ...options?.features, coreReativityFeature: storeReactivityBindings(), }, - } as any) + } as any) as unknown as Table_Internal } export function generateTestTableFromData( data: Array, options?: Omit, 'data' | 'columns'>, -): Table { +): Table_Internal { const columns = generateTestColumnDefs(data) - return constructTable({ + return constructTable({ data, columns, ...options, @@ -51,7 +51,7 @@ export function generateTestTableFromData( ...options?.features, coreReativityFeature: storeReactivityBindings(), }, - } as any) + } as any) as unknown as Table_Internal } export function generateTestTableWithDataAndState< @@ -62,13 +62,13 @@ export function generateTestTableWithDataAndState< TableOptions, 'data' | 'columns' | 'onStateChange' >, -): Table { +): Table_Internal { 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, { + const table = generateTestTableWithData(lengths, { data, columns, ...options, @@ -83,7 +83,7 @@ export function generateTestTableWithDataAndState< state = updater } - table.options.state = state + ;(table.options as any).state = state }, } as any) @@ -98,11 +98,11 @@ export function generateTestTableWithStateFromData< TableOptions, 'data' | 'columns' | 'onStateChange' >, -): Table { +): Table_Internal { const columns = generateTestColumnDefs(data) let state = { ...options?.initialState } as TableState - const table = generateTestTableFromData(data, { + const table = generateTestTableFromData(data, { columns, ...options, features: { diff --git a/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts b/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts index 3ab95aac20..9022bf7919 100644 --- a/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts +++ b/packages/table-core/tests/implementation/features/row-pinning/rowPinningFeature.test.ts @@ -13,7 +13,7 @@ import { } from '../../../helpers/rowPinningHelpers' import { generateTestData } from '../../../fixtures/data/generateTestData' import { storeReactivityBindings } from '../../../../src/store-reactivity-bindings' -import type { ColumnDef, Row } from '../../../../src' +import type { ColumnDef, TableFeatures } from '../../../../src' import type { Person } from '../../../fixtures/data/types' // Define feature set with proper typing @@ -24,10 +24,13 @@ const features = { } type personKeys = keyof Person -type PersonColumn = ColumnDef +type PersonColumn = + ColumnDef -function generateColumnDefs(people: Array): Array { - const columnHelper = createColumnHelper() +function generateColumnDefs( + people: Array, +): Array> { + const columnHelper = createColumnHelper() const person = people[0] if (!person) { @@ -36,7 +39,7 @@ function generateColumnDefs(people: Array): Array { return Object.keys(person).map((key) => { const typedKey = key as personKeys - return columnHelper.accessor(typedKey, { id: typedKey }) + return columnHelper.accessor(typedKey, { id: typedKey } as any) }) } @@ -165,14 +168,13 @@ describe('table methods', () => { it('should handle keepPinnedRows - false', () => { const data = generateTestData(10) - const columns = generateColumnDefs(data) - const _featuresWithPagination = { ...coreFeatures, rowPinningFeature, rowPaginationFeature, coreReativityFeature: storeReactivityBindings(), } + const columns = generateColumnDefs(data) const table = constructTable({ features: _featuresWithPagination, @@ -205,14 +207,13 @@ describe('table methods', () => { it('should handle keepPinnedRows - true', () => { const data = generateTestData(10) - const columns = generateColumnDefs(data) - const _featuresWithPagination = { ...coreFeatures, rowPinningFeature, rowPaginationFeature, coreReativityFeature: storeReactivityBindings(), } + const columns = generateColumnDefs(data) const table = constructTable({ features: _featuresWithPagination, @@ -263,7 +264,7 @@ describe('row methods', () => { it('should use enableRowPinning function when provided', () => { const table = createRowPinningTable({ - enableRowPinning: (row: Row) => row.id === ROW[1], + enableRowPinning: (row) => row.id === ROW[1], }) expect(table.getRow(ROW[0]).getCanPin()).toBe(false) @@ -335,7 +336,7 @@ describe('row methods', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() // Set up initial state with a pinned row - table.baseAtoms.rowPinning.set({ + table.baseAtoms.rowPinning!.set({ top: [ROW[0]], bottom: [], }) diff --git a/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts b/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts index ed44de4c14..faace0d30c 100644 --- a/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts +++ b/packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts @@ -23,7 +23,7 @@ type personKeys = keyof Person type PersonColumn = ColumnDef function generateColumnDefs(people: Array): Array { - const columnHelper = createColumnHelper() + const columnHelper = createColumnHelper() const person = people[0] if (!person) { diff --git a/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts b/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts index 1729befc6d..94596905e7 100644 --- a/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts +++ b/packages/table-core/tests/performance/features/column-grouping/columnGroupingFeature.test.ts @@ -15,10 +15,17 @@ import type { ColumnDef } from '../../../../src' // TODO: bring up to new test structure type personKeys = keyof Person -type PersonColumn = ColumnDef + +const features = { + ...coreFeatures, + columnGroupingFeature, + coreReativityFeature: storeReactivityBindings(), +} + +type PersonColumn = ColumnDef function generateColumns(people: Array): Array { - const columnHelper = createColumnHelper() + const columnHelper = createColumnHelper() const person = people[0] if (!person) { @@ -42,16 +49,11 @@ describe('#getGroupedRowModel', () => { data.forEach((p) => (p.lastName = 'Name')) data.forEach((p) => (p.age = 123)) - const table = constructTable({ - features: { - columnGroupingFeature, - ...coreFeatures, - coreReativityFeature: storeReactivityBindings(), - }, + const table = constructTable({ + features, rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns), }, - onStateChange() {}, renderFallbackValue: '', data, initialState: { grouping }, diff --git a/packages/table-core/tests/unit/core/cells/constructCell.test.ts b/packages/table-core/tests/unit/core/cells/constructCell.test.ts index ab88f2e968..e075e0966e 100644 --- a/packages/table-core/tests/unit/core/cells/constructCell.test.ts +++ b/packages/table-core/tests/unit/core/cells/constructCell.test.ts @@ -3,16 +3,24 @@ 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' +import type { Table_Internal } from '../../../../src/types/Table' + +type TestData = Record +type TestFeatures = { + coreCellsFeature: typeof coreCellsFeature +} 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 column = { id: 'test-column' } as unknown as Column< + TestFeatures, + TestData > + const row = { id: 'test-row' } as unknown as Row + const table = { + _features: { coreCellsFeature }, + options: {}, + } as unknown as Table_Internal const coreCell = constructCell(column, row, table) expect(coreCell).toBeDefined() diff --git a/packages/table-core/tests/unit/core/columns/constructColumn.test.ts b/packages/table-core/tests/unit/core/columns/constructColumn.test.ts index df35e2a984..4edb8b6bb9 100644 --- a/packages/table-core/tests/unit/core/columns/constructColumn.test.ts +++ b/packages/table-core/tests/unit/core/columns/constructColumn.test.ts @@ -5,25 +5,31 @@ import { constructTable } from '../../../../src' import { storeReactivityBindings } from '../../../../src/store-reactivity-bindings' import type { ColumnDef } from '../../../../src/types/ColumnDef' +const features = { + coreColumnsFeature, + coreReativityFeature: storeReactivityBindings(), +} + +interface TestRow { + 'test-accessor-key'?: string +} + describe('constructColumn', () => { it('should create a column with all core column APIs and properties', () => { - const table = constructTable({ - features: { - coreColumnsFeature, - coreReativityFeature: storeReactivityBindings(), - }, - columns: [] as Array, - data: [] as Array, + const table = constructTable({ + features, + columns: [], + data: [], }) const columnDef = { id: 'test-column', accessorKey: 'test-accessor-key', - } as ColumnDef + } as ColumnDef const depth = 0 const parent = undefined - const column = constructColumn(table as any, columnDef, depth, parent) + const column = constructColumn(table, columnDef, depth, parent) expect(column).toBeDefined() expect(column).toHaveProperty('accessorFn') diff --git a/packages/table-core/tests/unit/core/headers/constructHeader.test.ts b/packages/table-core/tests/unit/core/headers/constructHeader.test.ts index fdfe777152..47774b8cdd 100644 --- a/packages/table-core/tests/unit/core/headers/constructHeader.test.ts +++ b/packages/table-core/tests/unit/core/headers/constructHeader.test.ts @@ -2,18 +2,23 @@ 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' +import type { Table_Internal } from '../../../../src/types/Table' + +type TestData = Record +type TestFeatures = { + coreHeadersFeature: typeof coreHeadersFeature +} describe('constructHeader', () => { it('should create a column with all core column APIs and properties', () => { - const table = { _features: { coreHeadersFeature }, options: {} } as Table< - any, - any - > + const table = { + _features: { coreHeadersFeature }, + options: {}, + } as unknown as Table_Internal const column = { id: 'test-column', columnDef: { id: 'test-column-def' }, - } as Column + } as unknown as Column const index = 0 const depth = 0 diff --git a/packages/table-core/tests/unit/core/rows/constructRow.test.ts b/packages/table-core/tests/unit/core/rows/constructRow.test.ts index 333c8e0312..d83c60bf9d 100644 --- a/packages/table-core/tests/unit/core/rows/constructRow.test.ts +++ b/packages/table-core/tests/unit/core/rows/constructRow.test.ts @@ -1,24 +1,28 @@ 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 { Table_Internal } from '../../../../src/types/Table' import type { Row } from '../../../../src/types/Row' +type TestFeatures = { + coreRowsFeature: typeof coreRowsFeature +} + 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 table = { + _features: { coreRowsFeature }, + options: {}, + } as unknown as Table_Internal const id = 'test-row' const original = { firstName: 'Tanner' } const rowIndex = 0 const depth = 0 - const subRows = [] as Array> + const subRows = [] as Array> const parentId = 'parent-id' const row = constructRow( diff --git a/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts b/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts index 7aa572cbe4..34513352f8 100644 --- a/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts +++ b/packages/table-core/tests/unit/core/table/stockFeaturesInitialState.test.ts @@ -35,8 +35,8 @@ describe('constructTable with stockFeatures', () => { expect(table.atoms.columnPinning).toBeDefined() // Defaults - expect(table.atoms.columnFilters.get()).toEqual([]) - expect(table.atoms.columnOrder.get()).toEqual([]) - expect(table.atoms.grouping.get()).toEqual([]) + expect(table.atoms.columnFilters!.get()).toEqual([]) + expect(table.atoms.columnOrder!.get()).toEqual([]) + expect(table.atoms.grouping!.get()).toEqual([]) }) }) diff --git a/packages/table-core/tests/unit/core/tableAtoms.test.ts b/packages/table-core/tests/unit/core/tableAtoms.test.ts index c9610c884d..798fbf3ebf 100644 --- a/packages/table-core/tests/unit/core/tableAtoms.test.ts +++ b/packages/table-core/tests/unit/core/tableAtoms.test.ts @@ -38,8 +38,8 @@ describe('three-layer atom architecture', () => { describe('baseAtoms (writable internal layer)', () => { it('stores initial feature state for each slice', () => { const table = makeTable() - expect(table.baseAtoms.sorting.get()).toEqual([]) - expect(table.baseAtoms.pagination.get()).toEqual({ + expect(table.baseAtoms.sorting!.get()).toEqual([]) + expect(table.baseAtoms.pagination!.get()).toEqual({ pageIndex: 0, pageSize: 10, }) @@ -48,7 +48,7 @@ describe('three-layer atom architecture', () => { it('writes from makeStateUpdater land on baseAtoms', () => { const table = makeTable() table.setSorting([{ id: 'name', desc: false }]) - expect(table.baseAtoms.sorting.get()).toEqual([ + expect(table.baseAtoms.sorting!.get()).toEqual([ { id: 'name', desc: false }, ]) }) @@ -57,15 +57,15 @@ describe('three-layer atom architecture', () => { describe('atoms (readonly derived layer)', () => { it('reflects baseAtoms when no external state/atom is provided', () => { const table = makeTable() - table.baseAtoms.sorting.set([{ id: 'age', desc: true }]) - expect(table.atoms.sorting.get()).toEqual([{ id: 'age', desc: true }]) + table.baseAtoms.sorting!.set([{ id: 'age', desc: true }]) + expect(table.atoms.sorting!.get()).toEqual([{ id: 'age', desc: true }]) }) it('options.state[key] syncs into baseAtoms', () => { const external: SortingState = [{ id: 'external', desc: false }] const table = makeTable({ state: { sorting: external } }) - expect(table.baseAtoms.sorting.get()).toEqual(external) - expect(table.atoms.sorting.get()).toEqual(external) + expect(table.baseAtoms.sorting!.get()).toEqual(external) + expect(table.atoms.sorting!.get()).toEqual(external) expect(table.store.state.sorting).toEqual(external) }) @@ -77,7 +77,7 @@ describe('three-layer atom architecture', () => { state: { sorting: [{ id: 'fromState', desc: false }] }, atoms: { sorting: externalAtom }, }) - expect(table.atoms.sorting.get()).toEqual([ + expect(table.atoms.sorting!.get()).toEqual([ { id: 'fromAtom', desc: true }, ]) expect(table.store.state.sorting).toEqual([ @@ -96,7 +96,7 @@ describe('three-layer atom architecture', () => { pageSize: 5, }) externalAtom.set({ pageIndex: 2, pageSize: 5 }) - expect(table.atoms.pagination.get()).toEqual({ + expect(table.atoms.pagination!.get()).toEqual({ pageIndex: 2, pageSize: 5, }) @@ -105,7 +105,7 @@ describe('three-layer atom architecture', () => { pageSize: 5, }) // baseAtoms are untouched — external wins - expect(table.baseAtoms.pagination.get()).toEqual({ + expect(table.baseAtoms.pagination!.get()).toEqual({ pageIndex: 0, pageSize: 10, }) @@ -128,7 +128,7 @@ describe('three-layer atom architecture', () => { pageSize: 5, }) // baseAtom stays at its initial default — external is the canonical source - expect(table.baseAtoms.pagination.get()).toEqual({ + expect(table.baseAtoms.pagination!.get()).toEqual({ pageIndex: 0, pageSize: 10, }) @@ -148,7 +148,7 @@ describe('three-layer atom architecture', () => { const table = makeTable() const observer = vi.fn() const sub = table.store.subscribe(observer) - table.baseAtoms.sorting.set([{ id: 'x', desc: false }]) + table.baseAtoms.sorting!.set([{ id: 'x', desc: false }]) expect(observer).toHaveBeenCalled() expect(table.store.state.sorting).toEqual([{ id: 'x', desc: false }]) sub.unsubscribe() @@ -160,8 +160,8 @@ describe('three-layer atom architecture', () => { const table = makeTable({ initialState: { pagination: { pageIndex: 0, pageSize: 25 } }, }) - table.baseAtoms.pagination.set({ pageIndex: 3, pageSize: 25 }) - table.baseAtoms.sorting.set([{ id: 'age', desc: true }]) + table.baseAtoms.pagination!.set({ pageIndex: 3, pageSize: 25 }) + table.baseAtoms.sorting!.set([{ id: 'age', desc: true }]) const observer = vi.fn() const sub = table.store.subscribe(observer) @@ -169,11 +169,11 @@ describe('three-layer atom architecture', () => { table.reset() // Values reset - expect(table.baseAtoms.pagination.get()).toEqual({ + expect(table.baseAtoms.pagination!.get()).toEqual({ pageIndex: 0, pageSize: 25, }) - expect(table.baseAtoms.sorting.get()).toEqual([]) + expect(table.baseAtoms.sorting!.get()).toEqual([]) // Subscriber fired exactly once (batched) despite resetting multiple slices expect(observer).toHaveBeenCalledTimes(1) diff --git a/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts index b57f7299dd..c4fddab1be 100644 --- a/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-ordering/columnOrderingFeature.utils.test.ts @@ -34,7 +34,7 @@ describe('column_getIndex', () => { table, } - expect(column_getIndex(column)).toBe(-1) + expect(column_getIndex(column as any)).toBe(-1) }) }) diff --git a/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts index 9178d6c032..db294ea042 100644 --- a/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-pinning/columnPinningFeature.utils.test.ts @@ -128,9 +128,9 @@ describe('column_pin', () => { describe('column_getCanPin', () => { it('should return true when column pinning is enabled', () => { const table = generateTestTableWithData(1) - const column = table.getAllColumns()[0] + const column = table.getAllColumns()[0]! - const result = column_getCanPin(column) + const result = column_getCanPin(column as any) expect(result).toBe(true) }) @@ -139,23 +139,30 @@ describe('column_getCanPin', () => { const table = generateTestTableWithData(1, { enableColumnPinning: false, }) - const column = table.getAllColumns()[0] + const column = table.getAllColumns()[0]! - const result = column_getCanPin(column) + const result = column_getCanPin(column as any) expect(result).toBe(false) }) it('should return false when column pinning is disabled for specific column', () => { const table = generateTestTableWithData(1) + const baseColumn = table.getAllColumns()[0]! const column = { - ...table.getAllColumns()[0], - columnDef: { enablePinning: false }, + ...baseColumn, + columnDef: { + ...baseColumn.columnDef, + enablePinning: false, + }, table: table, getLeafColumns: () => [ { - ...table.getAllColumns()[0], - columnDef: { enablePinning: false }, + ...baseColumn, + columnDef: { + ...baseColumn.columnDef, + enablePinning: false, + }, }, ], } @@ -469,7 +476,7 @@ describe('table_getCenterHeaderGroups', () => { const headerGroups = table_getCenterHeaderGroups(table) const centerColumnIds = headerGroups[0]?.headers.map( - (header: Header) => header.column.id, + (header) => header.column.id, ) expect(centerColumnIds).not.toContain('firstName') @@ -752,7 +759,7 @@ describe('table_getFooterGroups', () => { const footerGroups = table_getCenterFooterGroups(table) const centerColumnIds = footerGroups[0]?.headers.map( - (header: Header) => header.column.id, + (header) => header.column.id, ) expect(centerColumnIds).not.toContain('firstName') diff --git a/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts index 2e9355e0d8..b8d2db635e 100644 --- a/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-resizing/columnResizingFeature.utils.test.ts @@ -76,7 +76,7 @@ describe('column_getCanResize', () => { table, } - const result = column_getCanResize(column) + const result = column_getCanResize(column as any) expect(result).toBe(true) }) @@ -91,7 +91,7 @@ describe('column_getCanResize', () => { table, } - const result = column_getCanResize(column) + const result = column_getCanResize(column as any) expect(result).toBe(false) }) @@ -104,7 +104,7 @@ describe('column_getCanResize', () => { table, } - const result = column_getCanResize(column) + const result = column_getCanResize(column as any) expect(result).toBe(false) }) @@ -130,7 +130,7 @@ describe('column_getIsResizing', () => { table, } - const result = column_getIsResizing(column) + const result = column_getIsResizing(column as any) expect(result).toBe(true) }) @@ -142,7 +142,7 @@ describe('column_getIsResizing', () => { table, } - const result = column_getIsResizing(column) + const result = column_getIsResizing(column as any) expect(result).toBe(false) }) diff --git a/packages/table-core/tests/unit/features/column-visibility/columnVisibilityFeature.utils.test.ts b/packages/table-core/tests/unit/features/column-visibility/columnVisibilityFeature.utils.test.ts index 2f1c036524..8856701cfa 100644 --- a/packages/table-core/tests/unit/features/column-visibility/columnVisibilityFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/column-visibility/columnVisibilityFeature.utils.test.ts @@ -22,7 +22,6 @@ import { } from '../../../../src/static-functions' import { generateTestTableWithData } from '../../../helpers/generateTestTable' import { getUpdaterResult } from '../../../helpers/testUtils' -import type { Column } from '../../../../src' const features = tableFeatures({ ...coreFeatures, @@ -89,7 +88,7 @@ describe('columnVisibilityFeature.utils', () => { const table = generateTestTableWithData(1, { features }) const column = table.getAllColumns()[0]! - const result = column_getCanHide(column) + const result = column_getCanHide(column as any) expect(result).toBe(true) }) @@ -101,7 +100,7 @@ describe('columnVisibilityFeature.utils', () => { }) const column = table.getAllColumns()[0]! - const result = column_getCanHide(column) + const result = column_getCanHide(column as any) expect(result).toBe(false) }) @@ -110,7 +109,10 @@ describe('columnVisibilityFeature.utils', () => { const table = generateTestTableWithData(1, { features }) const column = { ...table.getAllColumns()[0]!, - columnDef: { enableHiding: false }, + columnDef: { + ...table.getAllColumns()[0]!.columnDef, + enableHiding: false, + }, } const result = column_getCanHide(column) @@ -312,9 +314,7 @@ describe('columnVisibilityFeature.utils', () => { expect(onColumnVisibilityChange).toHaveBeenCalled() const result = onColumnVisibilityChange.mock.calls[0]?.[0] - const allColumnIds = table - .getAllLeafColumns() - .map((col: Column) => col.id) + const allColumnIds = table.getAllLeafColumns().map((col) => col.id) expect(Object.entries(result)).toEqual( allColumnIds.map((id: string) => [id, true]), ) @@ -331,9 +331,7 @@ describe('columnVisibilityFeature.utils', () => { expect(onColumnVisibilityChange).toHaveBeenCalled() const result = onColumnVisibilityChange.mock.calls[0]?.[0] - const allColumnIds = table - .getAllLeafColumns() - .map((col: Column) => col.id) + const allColumnIds = table.getAllLeafColumns().map((col) => col.id) expect(Object.entries(result)).toEqual( allColumnIds.map((id: string) => [id, false]), ) @@ -382,9 +380,7 @@ describe('columnVisibilityFeature.utils', () => { it('should return false when no columns are visible', () => { const table = generateTestTableWithData(1, { features }) - const allColumnIds = table - .getAllLeafColumns() - .map((col: Column) => col.id) + const allColumnIds = table.getAllLeafColumns().map((col) => col.id) const hideAllColumns = Object.fromEntries( allColumnIds.map((id: string) => [id, false]), ) @@ -415,9 +411,7 @@ describe('columnVisibilityFeature.utils', () => { expect(onColumnVisibilityChange).toHaveBeenCalled() const result = onColumnVisibilityChange.mock.calls[0]?.[0] - const allColumnIds = table - .getAllLeafColumns() - .map((col: Column) => col.id) + const allColumnIds = table.getAllLeafColumns().map((col) => col.id) expect(Object.entries(result)).toEqual( allColumnIds.map((id: string) => [id, true]), ) diff --git a/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts b/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts index 3c43e62608..bd1f3e039f 100644 --- a/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts +++ b/packages/table-core/tests/unit/features/row-pinning/rowPinningFeature.utils.test.ts @@ -18,7 +18,7 @@ import { createTableWithMockOnPinningChange, createTableWithPinningState, } from '../../../helpers/rowPinningHelpers' -import type { Row } from '../../../../src' +import type { Row, TableFeatures } from '../../../../src' import type { Person } from '../../../fixtures/data/types' const DEFAULT_ROW_COUNT = 10 @@ -486,7 +486,7 @@ describe('row_pin', () => { it('should unpin a row when position is false', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() - table.baseAtoms.rowPinning.set({ + table.baseAtoms.rowPinning!.set({ top: [ROW[0]], bottom: [], }) @@ -509,7 +509,7 @@ describe('row_pin', () => { const row = table.getRow('0') const leafRows = [{ id: LEAF[1] }, { id: LEAF[2] }] vi.spyOn(row, 'getLeafRows').mockReturnValue( - leafRows as unknown as Array>, + leafRows as unknown as Array>, ) row_pin(row, 'top', true) @@ -529,7 +529,7 @@ describe('row_pin', () => { const row = table.getRow('0') const parentRows = [{ id: PARENT[1] }, { id: PARENT[2] }] vi.spyOn(row, 'getParentRows').mockReturnValue( - parentRows as unknown as Array>, + parentRows as unknown as Array>, ) row_pin(row, 'top', false, true) @@ -546,7 +546,7 @@ describe('row_pin', () => { it('should maintain existing pinned rows when pinning additional rows', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() - table.baseAtoms.rowPinning.set({ + table.baseAtoms.rowPinning!.set({ top: [ROW[1]], bottom: [ROW[2]], }) @@ -569,7 +569,7 @@ describe('row_pin', () => { it('should remove row from other position when moving between top and bottom', () => { const { table, onRowPinningChangeMock } = createTableWithMockOnPinningChange() - table.baseAtoms.rowPinning.set({ + table.baseAtoms.rowPinning!.set({ top: [ROW[0]], bottom: [], }) diff --git a/packages/table-devtools/src/TableContextProvider.tsx b/packages/table-devtools/src/TableContextProvider.tsx index 26aa5119fb..aaee2c2964 100644 --- a/packages/table-devtools/src/TableContextProvider.tsx +++ b/packages/table-devtools/src/TableContextProvider.tsx @@ -11,17 +11,18 @@ import { subscribeTableDevtoolsTargets, } from './tableTarget' import type { Accessor, ParentComponent, Setter } from 'solid-js' -import type { RowData, Table, TableFeatures } from '@tanstack/table-core' -import type { TableDevtoolsRegistration } from './tableTarget' +import type { + TableDevtoolsRegistration, + TableDevtoolsTable, +} from './tableTarget' type TableDevtoolsTabId = 'features' | 'state' | 'options' | 'rows' | 'columns' -type AnyTable = Table<{}, RowData> interface TableDevtoolsContextValue { targets: Accessor> selectedTargetId: Accessor setSelectedTargetId: Setter - table: Accessor + table: Accessor activeTab: Accessor setActiveTab: Setter } @@ -42,7 +43,9 @@ export const TableContextProvider: ParentComponent = (props) => { const selectedTarget = createMemo(() => targets().find((target) => target.id === selectedTargetId()), ) - const table = createMemo(() => selectedTarget()?.table) + const table = createMemo( + () => selectedTarget()?.table, + ) createEffect(() => { const unsubscribe = subscribeTableDevtoolsTargets((nextTargets) => { diff --git a/packages/table-devtools/src/components/ColumnsPanel.tsx b/packages/table-devtools/src/components/ColumnsPanel.tsx index 8395b6d400..500e33a639 100644 --- a/packages/table-devtools/src/components/ColumnsPanel.tsx +++ b/packages/table-devtools/src/components/ColumnsPanel.tsx @@ -9,7 +9,7 @@ import type { Column, RowData, TableFeatures } from '@tanstack/table-core' type AnyColumn = Column function getColumnDefSummary(column: AnyColumn): string { - const def = column.columnDef as Record + const def = column.columnDef as unknown as Record const header = def.header const accessorKey = def.accessorKey const accessorFn = def.accessorFn @@ -45,9 +45,14 @@ export function ColumnsPanel() { tableState() + const tableWithColumnFns = tableInstance as unknown as { + getAllFlatColumns?: () => Array + getAllLeafColumns?: () => Array + } + return ( - tableInstance.getAllFlatColumns?.() ?? - tableInstance.getAllLeafColumns?.() ?? + tableWithColumnFns.getAllFlatColumns?.() ?? + tableWithColumnFns.getAllLeafColumns?.() ?? [] ) }) diff --git a/packages/table-devtools/src/components/FeaturesPanel.tsx b/packages/table-devtools/src/components/FeaturesPanel.tsx index 08ab22946d..8912fb445a 100644 --- a/packages/table-devtools/src/components/FeaturesPanel.tsx +++ b/packages/table-devtools/src/components/FeaturesPanel.tsx @@ -5,8 +5,7 @@ import { useTableStore } from '../useTableStore' import { useStyles } from '../styles/use-styles' import { NoTableConnected } from './NoTableConnected' import { ResizableSplit } from './ResizableSplit' - -import type { RowData, Table } from '@tanstack/table-core' +import type { TableDevtoolsTable } from '../tableTarget' type FnBuckets = Partial< Record<'filterFns' | 'sortFns' | 'aggregationFns', Record> @@ -110,7 +109,7 @@ const ROW_MODEL_TO_GETTER: Record< } function getRowCountForModel( - tableInstance: Table<{}, RowData> | undefined, + tableInstance: TableDevtoolsTable | undefined, rowModelName: string, ): number { const getter = ROW_MODEL_TO_GETTER[rowModelName] diff --git a/packages/table-devtools/src/components/OptionsPanel.tsx b/packages/table-devtools/src/components/OptionsPanel.tsx index e154000a1b..0ea122fc6b 100644 --- a/packages/table-devtools/src/components/OptionsPanel.tsx +++ b/packages/table-devtools/src/components/OptionsPanel.tsx @@ -29,7 +29,7 @@ export function OptionsPanel() { () => { const tableInstance = table() return tableInstance - ? projectOptionsForTree(tableInstance.options as unknown) + ? projectOptionsForTree(tableInstance.options) : undefined }, ) @@ -41,7 +41,7 @@ export function OptionsPanel() { } tableOptions() - return projectOptionsForTree(tableInstance.options as unknown) + return projectOptionsForTree(tableInstance.options) }) return ( diff --git a/packages/table-devtools/src/index.ts b/packages/table-devtools/src/index.ts index 2519ec4039..1c5d82106e 100644 --- a/packages/table-devtools/src/index.ts +++ b/packages/table-devtools/src/index.ts @@ -18,5 +18,7 @@ export { } from './tableTarget' export type { TableDevtoolsRegistration, + TableDevtoolsStore, + TableDevtoolsTable, UpsertTableDevtoolsTargetOptions, } from './tableTarget' diff --git a/packages/table-devtools/src/production.ts b/packages/table-devtools/src/production.ts index 38eb93b21a..df414118c9 100644 --- a/packages/table-devtools/src/production.ts +++ b/packages/table-devtools/src/production.ts @@ -12,5 +12,7 @@ export { } from './tableTarget' export type { TableDevtoolsRegistration, + TableDevtoolsStore, + TableDevtoolsTable, UpsertTableDevtoolsTargetOptions, } from './tableTarget' diff --git a/packages/table-devtools/src/tableTarget.ts b/packages/table-devtools/src/tableTarget.ts index 6fc2ce943e..fe59e4b0aa 100644 --- a/packages/table-devtools/src/tableTarget.ts +++ b/packages/table-devtools/src/tableTarget.ts @@ -1,34 +1,61 @@ import { createEffect, createRoot, createSignal, untrack } from 'solid-js' +import type { Readable } from '@tanstack/solid-store' import type { RowData, Table, TableFeatures } from '@tanstack/table-core' -type AnyTable = Table type Listener = (targets: Array) => void const MISSING_KEY_ERROR = '[TanStack Table Devtools] Missing table key. Add a `key` option to your table to use devtools.' +export interface TableDevtoolsStore extends Readable { + state: TState +} + +export interface TableDevtoolsTable { + _features: Record + _rowModelFns: unknown + baseAtoms: Record + initialState: unknown + options: { + atoms?: Record + data?: unknown + key?: string + rowModels?: Record + state?: Record + [key: string]: unknown + } + optionsStore?: TableDevtoolsStore + reset: () => void + store: TableDevtoolsStore +} + export interface TableDevtoolsRegistration { id: string - table: AnyTable + table: TableDevtoolsTable } -export interface UpsertTableDevtoolsTargetOptions { - table: AnyTable +export interface UpsertTableDevtoolsTargetOptions< + TFeatures extends TableFeatures, + TData extends RowData, +> { + table: Table } const [registrationsMap, setRegistrationsMap] = createSignal< Map >(new Map()) -function getTableKey(table: AnyTable) { +function getTableKey(table: TableDevtoolsTable) { const key = untrack(() => table.options.key?.trim()) return key || undefined } -export function upsertTableDevtoolsTarget( - options: UpsertTableDevtoolsTargetOptions, -) { - const key = getTableKey(options.table) +export function upsertTableDevtoolsTarget< + TFeatures extends TableFeatures, + TData extends RowData, +>(options: UpsertTableDevtoolsTargetOptions) { + const table = options.table as unknown as TableDevtoolsTable + const key = getTableKey(table) if (!key) { console.error(MISSING_KEY_ERROR) @@ -39,7 +66,7 @@ export function upsertTableDevtoolsTarget( const existingRegistration = registrations.get(key) if (existingRegistration) { - if (existingRegistration.table === options.table) { + if (existingRegistration.table === table) { return () => { removeTableDevtoolsTarget(key) } @@ -48,14 +75,14 @@ export function upsertTableDevtoolsTarget( const nextRegistrations = new Map(registrations) nextRegistrations.set(key, { id: key, - table: options.table, + table, }) setRegistrationsMap(nextRegistrations) } else { const nextRegistrations = new Map(registrations) nextRegistrations.set(key, { id: key, - table: options.table, + table, }) setRegistrationsMap(nextRegistrations) } @@ -92,7 +119,10 @@ export function subscribeTableDevtoolsTargets(listener: Listener) { return disposeRoot } -export function setTableDevtoolsTarget(table: Table | undefined) { +export function setTableDevtoolsTarget< + TFeatures extends TableFeatures, + TData extends RowData, +>(table: Table | undefined) { if (!table) { return } diff --git a/packages/vue-table/src/FlexRender.ts b/packages/vue-table/src/FlexRender.ts index eb64fd90bd..14a657b950 100644 --- a/packages/vue-table/src/FlexRender.ts +++ b/packages/vue-table/src/FlexRender.ts @@ -1,12 +1,27 @@ import { defineComponent, h, isVNode } from 'vue' import type { PropType } from 'vue' -import type { - Cell, - CellData, - Header, - RowData, - TableFeatures, -} from '@tanstack/table-core' + +export interface FlexRenderCell { + column: { + columnDef: { + aggregatedCell?: any + cell?: any + } + } + getContext: () => any + getIsAggregated?: () => boolean + getIsPlaceholder?: () => boolean +} + +export interface FlexRenderHeader { + column: { + columnDef: { + footer?: any + header?: any + } + } + getContext: () => any +} /** * If rendering headers, cells, or footers with custom markup, use flexRender instead of `cell.getValue()` or `cell.renderValue()`. @@ -60,24 +75,24 @@ export const FlexRender = defineComponent({ default: undefined, }, cell: { - type: Object as PropType>, + type: Object as PropType, default: undefined, }, header: { - type: Object as PropType>, + type: Object as PropType, default: undefined, }, footer: { - type: Object as PropType>, + type: Object as PropType, default: undefined, }, }, setup: (props: { render?: any props?: any - cell?: Cell - header?: Header - footer?: Header + cell?: FlexRenderCell + header?: FlexRenderHeader + footer?: FlexRenderHeader }) => { return () => { // New shorthand pattern: extract render and props from cell/header/footer diff --git a/packages/vue-table/src/createTableHook.ts b/packages/vue-table/src/createTableHook.ts index 960e2b452f..e22af4261f 100644 --- a/packages/vue-table/src/createTableHook.ts +++ b/packages/vue-table/src/createTableHook.ts @@ -4,6 +4,7 @@ import { FlexRender } from './FlexRender' import { mergeProxy } from './merge-proxy' import { useTable } from './useTable' import type { TableOptionsWithReactiveData, VueTable } from './useTable' +import type { FlexRenderCell, FlexRenderHeader } from './FlexRender' import type { Component, InjectionKey, PropType, VNodeChild } from 'vue' import type { AccessorFn, @@ -229,15 +230,15 @@ export const AppFlexRender = defineComponent({ name: 'TableFlexRender', props: { cell: { - type: Object as PropType>, + type: Object as PropType, default: undefined, }, header: { - type: Object as PropType>, + type: Object as PropType, default: undefined, }, footer: { - type: Object as PropType>, + type: Object as PropType, default: undefined, }, },