@tanstack/table-core 9.0.0-beta.7 → 9.0.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/core/coreFeatures.cjs.map +1 -1
  2. package/dist/core/coreFeatures.d.cts +1 -1
  3. package/dist/core/coreFeatures.d.ts +1 -1
  4. package/dist/core/coreFeatures.js.map +1 -1
  5. package/dist/core/table/constructTable.cjs +3 -2
  6. package/dist/core/table/constructTable.cjs.map +1 -1
  7. package/dist/core/table/constructTable.js +3 -2
  8. package/dist/core/table/constructTable.js.map +1 -1
  9. package/dist/core/table/coreTablesFeature.types.d.cts +17 -3
  10. package/dist/core/table/coreTablesFeature.types.d.ts +17 -3
  11. package/dist/features/row-selection/rowSelectionFeature.utils.cjs +10 -6
  12. package/dist/features/row-selection/rowSelectionFeature.utils.cjs.map +1 -1
  13. package/dist/features/row-selection/rowSelectionFeature.utils.js +10 -6
  14. package/dist/features/row-selection/rowSelectionFeature.utils.js.map +1 -1
  15. package/dist/helpers/metaHelper.cjs +30 -0
  16. package/dist/helpers/metaHelper.cjs.map +1 -0
  17. package/dist/helpers/metaHelper.d.cts +26 -0
  18. package/dist/helpers/metaHelper.d.ts +26 -0
  19. package/dist/helpers/metaHelper.js +29 -0
  20. package/dist/helpers/metaHelper.js.map +1 -0
  21. package/dist/helpers/tableFeatures.cjs +11 -1
  22. package/dist/helpers/tableFeatures.cjs.map +1 -1
  23. package/dist/helpers/tableFeatures.d.cts +11 -1
  24. package/dist/helpers/tableFeatures.d.ts +11 -1
  25. package/dist/helpers/tableFeatures.js +11 -1
  26. package/dist/helpers/tableFeatures.js.map +1 -1
  27. package/dist/index.cjs +2 -0
  28. package/dist/index.d.cts +5 -4
  29. package/dist/index.d.ts +5 -4
  30. package/dist/index.js +2 -1
  31. package/dist/store-reactivity-bindings.cjs +1 -1
  32. package/dist/store-reactivity-bindings.cjs.map +1 -1
  33. package/dist/store-reactivity-bindings.d.cts +1 -1
  34. package/dist/store-reactivity-bindings.d.ts +1 -1
  35. package/dist/store-reactivity-bindings.js +1 -1
  36. package/dist/store-reactivity-bindings.js.map +1 -1
  37. package/dist/types/ColumnDef.d.cts +17 -3
  38. package/dist/types/ColumnDef.d.ts +17 -3
  39. package/dist/types/TableFeatures.d.cts +24 -2
  40. package/dist/types/TableFeatures.d.ts +24 -2
  41. package/dist/types/TableOptions.d.cts +1 -1
  42. package/dist/types/TableOptions.d.ts +1 -1
  43. package/package.json +1 -1
  44. package/src/core/coreFeatures.ts +1 -1
  45. package/src/core/table/constructTable.ts +9 -2
  46. package/src/core/table/coreTablesFeature.types.ts +23 -2
  47. package/src/features/row-selection/rowSelectionFeature.utils.ts +12 -7
  48. package/src/helpers/metaHelper.ts +24 -0
  49. package/src/helpers/tableFeatures.ts +11 -1
  50. package/src/index.ts +1 -0
  51. package/src/store-reactivity-bindings.ts +1 -1
  52. package/src/types/ColumnDef.ts +28 -2
  53. package/src/types/TableFeatures.ts +24 -2
  54. package/src/types/TableOptions.ts +4 -1
@@ -12,7 +12,29 @@ type IsAny<T> = 0 extends 1 & T ? true : false;
12
12
  type UnionToIntersectionOrEmpty<T> = [T] extends [never] ? {} : UnionToIntersection<T> & {};
13
13
  type ExtractFeatureMapTypes<TFeatures extends TableFeatures, TFeatureMap extends object> = IsAny<TFeatures> extends true ? UnionToIntersection<TFeatureMap[keyof TFeatureMap]> : UnionToIntersectionOrEmpty<TFeatureMap[Extract<keyof TFeatures, keyof TFeatureMap>]>;
14
14
  interface Plugins {}
15
- interface TableFeatures extends Partial<CoreFeatures>, Partial<StockFeatures>, Partial<Plugins> {}
15
+ interface TableFeatures extends Partial<CoreFeatures>, Partial<StockFeatures>, Partial<Plugins> {
16
+ /**
17
+ * Type-only slot for declaring the type of this table's `options.meta`.
18
+ *
19
+ * Pass a phantom value: `tableMeta: {} as MyTableMeta`. The value itself is
20
+ * ignored and stripped from the table's registered features at runtime — only
21
+ * its type is used, inferred wherever `TFeatures` flows.
22
+ *
23
+ * When omitted, the global declaration-merged `TableMeta` interface applies.
24
+ */
25
+ tableMeta?: object;
26
+ /**
27
+ * Type-only slot for declaring the type of `columnDef.meta` for all columns
28
+ * of this table.
29
+ *
30
+ * Pass a phantom value: `columnMeta: {} as MyColumnMeta`. The value itself is
31
+ * ignored and stripped from the table's registered features at runtime — only
32
+ * its type is used, inferred wherever `TFeatures` flows.
33
+ *
34
+ * When omitted, the global declaration-merged `ColumnMeta` interface applies.
35
+ */
36
+ columnMeta?: object;
37
+ }
16
38
  interface TableFeature {
17
39
  /**
18
40
  * Assigns Cell APIs to the cell prototype for memory-efficient method sharing.
@@ -49,5 +71,5 @@ interface TableFeature {
49
71
  initRowInstanceData?: <TFeatures extends TableFeatures, TData extends RowData>(row: Row<TFeatures, TData>) => void;
50
72
  }
51
73
  //#endregion
52
- export { ExtractFeatureMapTypes, Plugins, TableFeature, TableFeatures };
74
+ export { ExtractFeatureMapTypes, IsAny, Plugins, TableFeature, TableFeatures };
53
75
  //# sourceMappingURL=TableFeatures.d.ts.map
@@ -25,7 +25,7 @@ import { TableOptions_ColumnGrouping } from "../features/column-grouping/columnG
25
25
  * options are mixed in.
26
26
  */
27
27
  interface TableOptions_Core<TFeatures extends TableFeatures, TData extends RowData> extends TableOptions_Table<TFeatures, TData>, TableOptions_Cell, TableOptions_Columns<TFeatures, TData>, TableOptions_Rows<TFeatures, TData> {}
28
- type DebugKeysFor<TFeatures extends TableFeatures> = { [K in keyof TFeatures & string as `debug${Capitalize<K>}`]?: boolean };
28
+ type DebugKeysFor<TFeatures extends TableFeatures> = { [K in Exclude<keyof TFeatures & string, 'tableMeta' | 'columnMeta'> as `debug${Capitalize<K>}`]?: boolean };
29
29
  type DebugOptions<TFeatures extends TableFeatures> = {
30
30
  debugAll?: boolean;
31
31
  debugCache?: boolean;
@@ -25,7 +25,7 @@ import { TableOptions_ColumnGrouping } from "../features/column-grouping/columnG
25
25
  * options are mixed in.
26
26
  */
27
27
  interface TableOptions_Core<TFeatures extends TableFeatures, TData extends RowData> extends TableOptions_Table<TFeatures, TData>, TableOptions_Cell, TableOptions_Columns<TFeatures, TData>, TableOptions_Rows<TFeatures, TData> {}
28
- type DebugKeysFor<TFeatures extends TableFeatures> = { [K in keyof TFeatures & string as `debug${Capitalize<K>}`]?: boolean };
28
+ type DebugKeysFor<TFeatures extends TableFeatures> = { [K in Exclude<keyof TFeatures & string, 'tableMeta' | 'columnMeta'> as `debug${Capitalize<K>}`]?: boolean };
29
29
  type DebugOptions<TFeatures extends TableFeatures> = {
30
30
  debugAll?: boolean;
31
31
  debugCache?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/table-core",
3
- "version": "9.0.0-beta.7",
3
+ "version": "9.0.0-beta.9",
4
4
  "description": "Headless UI for building powerful tables & datagrids for TS/JS.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -7,7 +7,7 @@ import { coreTablesFeature } from './table/coreTablesFeature'
7
7
  import type { TableReactivityBindings } from '../reactivity'
8
8
 
9
9
  export interface CoreFeatures {
10
- coreReativityFeature?: TableReactivityBindings
10
+ coreReactivityFeature?: TableReactivityBindings
11
11
  coreCellsFeature: typeof coreCellsFeature
12
12
  coreColumnsFeature: typeof coreColumnsFeature
13
13
  coreHeadersFeature: typeof coreHeadersFeature
@@ -33,11 +33,18 @@ export function constructTable<
33
33
  TFeatures extends TableFeatures,
34
34
  TData extends RowData,
35
35
  >(tableOptions: TableOptions<TFeatures, TData>): Table<TFeatures, TData> {
36
- const _reactivity = tableOptions.features.coreReativityFeature!
36
+ const _reactivity = tableOptions.features.coreReactivityFeature!
37
+
38
+ // `tableMeta`/`columnMeta` are type-only slots, not real features
39
+ const {
40
+ columnMeta: _columnMeta,
41
+ tableMeta: _tableMeta,
42
+ ...features
43
+ } = tableOptions.features
37
44
 
38
45
  const table = {
39
46
  _reactivity,
40
- _features: { ...coreFeatures, ...tableOptions.features },
47
+ _features: { ...coreFeatures, ...features },
41
48
  _rowModels: {},
42
49
  _rowModelFns: {},
43
50
  baseAtoms: {},
@@ -3,7 +3,7 @@ import type { Atom, ReadonlyAtom, ReadonlyStore } from '@tanstack/store'
3
3
  import type { CoreFeatures } from '../coreFeatures'
4
4
  import type { RowModelFns } from '../../types/RowModelFns'
5
5
  import type { RowData, Updater } from '../../types/type-utils'
6
- import type { TableFeatures } from '../../types/TableFeatures'
6
+ import type { IsAny, TableFeatures } from '../../types/TableFeatures'
7
7
  import type { CachedRowModels, CreateRowModels_All } from '../../types/RowModel'
8
8
  import type { TableOptions } from '../../types/TableOptions'
9
9
  import type { TableState, TableState_All } from '../../types/TableState'
@@ -13,6 +13,24 @@ export interface TableMeta<
13
13
  TData extends RowData,
14
14
  > {}
15
15
 
16
+ /**
17
+ * Resolves the type of `options.meta` for a feature set.
18
+ *
19
+ * When the features object declares a `tableMeta` type-only slot
20
+ * (`tableFeatures({ ..., tableMeta: {} as MyTableMeta })`), that type wins.
21
+ * Otherwise this falls back to the global declaration-merged `TableMeta`
22
+ * interface.
23
+ */
24
+ export type ExtractTableMeta<
25
+ TFeatures extends TableFeatures,
26
+ TData extends RowData,
27
+ > =
28
+ IsAny<TFeatures> extends true
29
+ ? TableMeta<TFeatures, TData>
30
+ : TFeatures extends { tableMeta: infer TMeta extends object }
31
+ ? TMeta
32
+ : TableMeta<TFeatures, TData>
33
+
16
34
  /**
17
35
  * A map of writable atoms, one per `TableState` slice. These are the internal
18
36
  * writable atoms that the library always writes to via `makeStateUpdater`.
@@ -116,8 +134,11 @@ export interface TableOptions_Table<
116
134
  ) => TableOptions<TFeatures, TData>
117
135
  /**
118
136
  * You can pass any object to `options.meta` and access it anywhere the `table` is available via `table.options.meta`.
137
+ *
138
+ * Declare its type per-table via the `tableMeta` type-only slot on the
139
+ * `features` option, or globally via declaration merging on `TableMeta`.
119
140
  */
120
- readonly meta?: TableMeta<TFeatures, TData>
141
+ readonly meta?: ExtractTableMeta<TFeatures, TData>
121
142
  /**
122
143
  * Optionally provide externally managed values for individual state slices.
123
144
  *
@@ -649,7 +649,7 @@ export function selectRowsFn<
649
649
  ): Array<Row<TFeatures, TData>> => {
650
650
  const result: Array<Row<TFeatures, TData>> = []
651
651
  for (let i = 0; i < rows.length; i++) {
652
- let row = rows[i]!
652
+ const row = rows[i]!
653
653
  const isSelected = isRowSelected(row)
654
654
 
655
655
  if (isSelected) {
@@ -658,13 +658,18 @@ export function selectRowsFn<
658
658
  }
659
659
 
660
660
  if (row.subRows.length) {
661
- row = {
662
- ...row,
663
- subRows: recurseRows(row.subRows, depth + 1),
661
+ // Always recurse — selected descendants of unselected parents must
662
+ // still be collected into flatRows/rowsById.
663
+ const newSubRows = recurseRows(row.subRows, depth + 1)
664
+
665
+ if (isSelected) {
666
+ // Preserve prototype chain so methods like getValue() remain accessible
667
+ const cloned = Object.create(Object.getPrototypeOf(row))
668
+ Object.assign(cloned, row)
669
+ cloned.subRows = newSubRows
670
+ result.push(cloned)
664
671
  }
665
- }
666
-
667
- if (isSelected) {
672
+ } else if (isSelected) {
668
673
  result.push(row)
669
674
  }
670
675
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A helper for declaring the `tableMeta`/`columnMeta` type-only slots in the
3
+ * `features` option without a type assertion.
4
+ *
5
+ * Equivalent to `{} as TMeta`, but reads as type-only at the call site and
6
+ * avoids `@typescript-eslint/no-unnecessary-type-assertion` false positives
7
+ * when the meta type has only optional properties (where an auto-fix removing
8
+ * the assertion would silently degrade the inferred meta type to `{}`).
9
+ *
10
+ * The returned value is a phantom — it is ignored and stripped from the
11
+ * table's registered features at runtime; only its type is used.
12
+ * @example
13
+ * ```
14
+ * import { metaHelper, tableFeatures, rowSortingFeature } from '@tanstack/react-table'
15
+ * const features = tableFeatures({
16
+ * rowSortingFeature,
17
+ * tableMeta: metaHelper<MyTableMeta>(),
18
+ * columnMeta: metaHelper<MyColumnMeta>(),
19
+ * });
20
+ * ```
21
+ */
22
+ export function metaHelper<TMeta extends object>(): TMeta {
23
+ return {} as TMeta
24
+ }
@@ -4,10 +4,20 @@ import type { TableFeatures } from '../types/TableFeatures'
4
4
  * A helper function to help define the features that are to be imported and applied to a table instance.
5
5
  * Use this utility to make it easier to have the correct type inference for the features that are being imported.
6
6
  * **Note:** It is recommended to use this utility statically outside of a component.
7
+ *
8
+ * You can also declare per-table `meta` types here with the `tableMeta` and
9
+ * `columnMeta` type-only slots instead of using global declaration merging.
10
+ * The values are phantom (ignored and stripped at runtime) — only their types
11
+ * are used.
7
12
  * @example
8
13
  * ```
9
14
  * import { tableFeatures, columnVisibilityFeature, rowPinningFeature } from '@tanstack/react-table'
10
- * const features = tableFeatures({ columnVisibilityFeature, rowPinningFeature });
15
+ * const features = tableFeatures({
16
+ * columnVisibilityFeature,
17
+ * rowPinningFeature,
18
+ * tableMeta: {} as { updateData: (rowIndex: number, columnId: string, value: unknown) => void },
19
+ * columnMeta: {} as { align?: 'left' | 'right' },
20
+ * });
11
21
  * const table = useTable({ features, rowModels: {}, columns, data });
12
22
  * ```
13
23
  */
package/src/index.ts CHANGED
@@ -22,6 +22,7 @@ export * from './types/type-utils'
22
22
 
23
23
  export * from './core/coreFeatures'
24
24
  export * from './helpers/columnHelper'
25
+ export * from './helpers/metaHelper'
25
26
  export * from './helpers/tableFeatures'
26
27
  export * from './helpers/tableOptions'
27
28
  export * from './utils'
@@ -11,7 +11,7 @@ import type { TableReactivityBindings } from './core/reactivity/coreReactivityFe
11
11
  * import { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings'
12
12
  *
13
13
  * const table = constructTable({
14
- * features: tableFeatures({ coreReativityFeature: storeReactivityBindings() }),
14
+ * features: tableFeatures({ coreReactivityFeature: storeReactivityBindings() }),
15
15
  * // ...
16
16
  * })
17
17
  * ```
@@ -1,5 +1,9 @@
1
1
  import type { CellData, RowData, UnionToIntersection } from './type-utils'
2
- import type { ExtractFeatureMapTypes, TableFeatures } from './TableFeatures'
2
+ import type {
3
+ ExtractFeatureMapTypes,
4
+ IsAny,
5
+ TableFeatures,
6
+ } from './TableFeatures'
3
7
  import type { CellContext } from '../core/cells/coreCellsFeature.types'
4
8
  import type { HeaderContext } from '../core/headers/coreHeadersFeature.types'
5
9
  import type { ColumnDef_ColumnFiltering } from '../features/column-filtering/columnFilteringFeature.types'
@@ -17,6 +21,25 @@ export interface ColumnMeta<
17
21
  TValue extends CellData = CellData,
18
22
  > {}
19
23
 
24
+ /**
25
+ * Resolves the type of `columnDef.meta` for a feature set.
26
+ *
27
+ * When the features object declares a `columnMeta` type-only slot
28
+ * (`tableFeatures({ ..., columnMeta: {} as MyColumnMeta })`), that type wins.
29
+ * Otherwise this falls back to the global declaration-merged `ColumnMeta`
30
+ * interface.
31
+ */
32
+ export type ExtractColumnMeta<
33
+ TFeatures extends TableFeatures,
34
+ TData extends RowData,
35
+ TValue extends CellData = CellData,
36
+ > =
37
+ IsAny<TFeatures> extends true
38
+ ? ColumnMeta<TFeatures, TData, TValue>
39
+ : TFeatures extends { columnMeta: infer TMeta extends object }
40
+ ? TMeta
41
+ : ColumnMeta<TFeatures, TData, TValue>
42
+
20
43
  /**
21
44
  * Reads a cell value from an original row object.
22
45
  *
@@ -96,8 +119,11 @@ interface ColumnDefBase_Core<
96
119
  cell?: ColumnDefTemplate<CellContext<TFeatures, TData, TValue>>
97
120
  /**
98
121
  * User-defined metadata available on the resolved column definition.
122
+ *
123
+ * Declare its type per-table via the `columnMeta` type-only slot on the
124
+ * `features` option, or globally via declaration merging on `ColumnMeta`.
99
125
  */
100
- meta?: ColumnMeta<TFeatures, TData, TValue>
126
+ meta?: ExtractColumnMeta<TFeatures, TData, TValue>
101
127
  }
102
128
 
103
129
  export interface ColumnDef_FeatureMap<
@@ -7,7 +7,7 @@ import type { TableOptions_All } from './TableOptions'
7
7
  import type { TableState_All } from './TableState'
8
8
  import type { StockFeatures } from '../features/stockFeatures'
9
9
 
10
- type IsAny<T> = 0 extends 1 & T ? true : false
10
+ export type IsAny<T> = 0 extends 1 & T ? true : false
11
11
  type UnionToIntersectionOrEmpty<T> = [T] extends [never]
12
12
  ? {}
13
13
  : UnionToIntersection<T> & {}
@@ -25,7 +25,29 @@ export type ExtractFeatureMapTypes<
25
25
  export interface Plugins {}
26
26
 
27
27
  export interface TableFeatures
28
- extends Partial<CoreFeatures>, Partial<StockFeatures>, Partial<Plugins> {}
28
+ extends Partial<CoreFeatures>, Partial<StockFeatures>, Partial<Plugins> {
29
+ /**
30
+ * Type-only slot for declaring the type of this table's `options.meta`.
31
+ *
32
+ * Pass a phantom value: `tableMeta: {} as MyTableMeta`. The value itself is
33
+ * ignored and stripped from the table's registered features at runtime — only
34
+ * its type is used, inferred wherever `TFeatures` flows.
35
+ *
36
+ * When omitted, the global declaration-merged `TableMeta` interface applies.
37
+ */
38
+ tableMeta?: object
39
+ /**
40
+ * Type-only slot for declaring the type of `columnDef.meta` for all columns
41
+ * of this table.
42
+ *
43
+ * Pass a phantom value: `columnMeta: {} as MyColumnMeta`. The value itself is
44
+ * ignored and stripped from the table's registered features at runtime — only
45
+ * its type is used, inferred wherever `TFeatures` flows.
46
+ *
47
+ * When omitted, the global declaration-merged `ColumnMeta` interface applies.
48
+ */
49
+ columnMeta?: object
50
+ }
29
51
 
30
52
  export interface TableFeature {
31
53
  /**
@@ -34,7 +34,10 @@ export interface TableOptions_Core<
34
34
  TableOptions_Rows<TFeatures, TData> {}
35
35
 
36
36
  type DebugKeysFor<TFeatures extends TableFeatures> = {
37
- [K in keyof TFeatures & string as `debug${Capitalize<K>}`]?: boolean
37
+ [K in Exclude<
38
+ keyof TFeatures & string,
39
+ 'tableMeta' | 'columnMeta' // type-only slots, not real features
40
+ > as `debug${Capitalize<K>}`]?: boolean
38
41
  }
39
42
 
40
43
  export type DebugOptions<TFeatures extends TableFeatures> = {