diff --git a/docs/framework/alpine/guide/aggregation.md b/docs/framework/alpine/guide/aggregation.md index 304d5cbdec..19f43db173 100644 --- a/docs/framework/alpine/guide/aggregation.md +++ b/docs/framework/alpine/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/angular/guide/aggregation.md b/docs/framework/angular/guide/aggregation.md index 2c54c0e9fd..21f33f4b42 100644 --- a/docs/framework/angular/guide/aggregation.md +++ b/docs/framework/angular/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/angular/guide/migrating.md b/docs/framework/angular/guide/migrating.md index 346fbf55ed..22ec2fc7c2 100644 --- a/docs/framework/angular/guide/migrating.md +++ b/docs/framework/angular/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (Angular) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -217,6 +217,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/framework/ember/guide/aggregation.md b/docs/framework/ember/guide/aggregation.md index 2035f35b66..8198571c6c 100644 --- a/docs/framework/ember/guide/aggregation.md +++ b/docs/framework/ember/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/lit/guide/aggregation.md b/docs/framework/lit/guide/aggregation.md index 33d859c052..e6faab5f57 100644 --- a/docs/framework/lit/guide/aggregation.md +++ b/docs/framework/lit/guide/aggregation.md @@ -81,19 +81,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -122,9 +127,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/lit/guide/migrating.md b/docs/framework/lit/guide/migrating.md index 40d7b330df..eb97e776f1 100644 --- a/docs/framework/lit/guide/migrating.md +++ b/docs/framework/lit/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (Lit) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -228,6 +228,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/framework/preact/guide/aggregation.md b/docs/framework/preact/guide/aggregation.md index cd9123e514..0e51c2f7bd 100644 --- a/docs/framework/preact/guide/aggregation.md +++ b/docs/framework/preact/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```tsx -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/preact/guide/migrating.md b/docs/framework/preact/guide/migrating.md index c1b2ec2599..91ac868be0 100644 --- a/docs/framework/preact/guide/migrating.md +++ b/docs/framework/preact/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (Preact) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -214,6 +214,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/framework/react/guide/aggregation.md b/docs/framework/react/guide/aggregation.md index 19ebaa603e..dcb39b563a 100644 --- a/docs/framework/react/guide/aggregation.md +++ b/docs/framework/react/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```tsx -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/react/guide/migrating.md b/docs/framework/react/guide/migrating.md index 12a6c2c148..a9348650a5 100644 --- a/docs/framework/react/guide/migrating.md +++ b/docs/framework/react/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (React) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -234,6 +234,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/framework/solid/guide/aggregation.md b/docs/framework/solid/guide/aggregation.md index 6a60db29fe..31fb2535ab 100644 --- a/docs/framework/solid/guide/aggregation.md +++ b/docs/framework/solid/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```tsx -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/solid/guide/migrating.md b/docs/framework/solid/guide/migrating.md index 025893c834..f807c57102 100644 --- a/docs/framework/solid/guide/migrating.md +++ b/docs/framework/solid/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (Solid) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -214,6 +214,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/framework/svelte/guide/aggregation.md b/docs/framework/svelte/guide/aggregation.md index fb17db4237..81e09dfe39 100644 --- a/docs/framework/svelte/guide/aggregation.md +++ b/docs/framework/svelte/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/svelte/guide/migrating.md b/docs/framework/svelte/guide/migrating.md index c8ba15c4f7..48c9fb769d 100644 --- a/docs/framework/svelte/guide/migrating.md +++ b/docs/framework/svelte/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (Svelte) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -225,6 +225,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/framework/vanilla/guide/aggregation.md b/docs/framework/vanilla/guide/aggregation.md index 22fb259daa..c6ed345704 100644 --- a/docs/framework/vanilla/guide/aggregation.md +++ b/docs/framework/vanilla/guide/aggregation.md @@ -78,19 +78,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -119,9 +124,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/vue/guide/aggregation.md b/docs/framework/vue/guide/aggregation.md index 10e3d5727f..da20bc3686 100644 --- a/docs/framework/vue/guide/aggregation.md +++ b/docs/framework/vue/guide/aggregation.md @@ -79,19 +79,24 @@ pagination do not change that default total. footer: ({ column }) => column.getAggregationValue().toLocaleString() ``` -Pass rows from any row model to choose a different set explicitly: +Pass one options object with rows from any row model to choose a different set: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // visible page/pipeline -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(table.getCoreRowModel().rows.slice(0, 3)) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) +column.getAggregationValue({ rows: table.getRowModel().rows }) +column.getAggregationValue({ rows: table.getFilteredSelectedRowModel().rows }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows.slice(0, 3) }) +column.getAggregationValue({ rows: table.getCoreRowModel().rows, maxDepth: 1 }) ``` -There is no separate scope option. The row array is the complete override. -Column option `getAggregationValue(context)` can provide an external or -server-computed value; return `undefined` to fall back to the configured -aggregation function. +Depth is relative to the supplied row array. `0` selects those roots, `1` +selects their direct sub-rows, and `Infinity` selects terminal rows. Configure +`maxAggregationDepth` on the column for cached default calls, or pass +`maxDepth` in the options object as an explicit override. +`table.getMaxSubRowDepth()` returns +the deepest structural depth in the core row model. Column option +`getAggregationValue(context)` can provide an external or server-computed +value; return `undefined` to fall back to the configured aggregation function. ## Grouped Aggregation @@ -120,9 +125,11 @@ rendering uses the adapter's normal footer renderer. ## Custom Aggregation Definitions Use `constructAggregationFn({ aggregate, merge? })` for custom definitions. -The aggregate context includes terminal `rows`, `getValue`, `column`, -`table`, and an optional `groupingRow`. A `merge` implementation can make -nested grouped aggregation more efficient. +The aggregate context includes depth-selected `rows`, `maxDepth`, `getValue`, +`column`, and `table`. Every aggregation configured on a column receives the +same row frontier. Grouped calls also include `groupingRow` and immediate +`subRows` for custom structural behavior. A `merge` implementation can more +efficiently combine already-computed sub-row results. See [Custom Aggregation Definitions](../../../guide/aggregation#custom-aggregation-definitions) for the full contract, return typing, caching behavior, and worker limitations. diff --git a/docs/framework/vue/guide/migrating.md b/docs/framework/vue/guide/migrating.md index 104251c445..cc5956966e 100644 --- a/docs/framework/vue/guide/migrating.md +++ b/docs/framework/vue/guide/migrating.md @@ -3,7 +3,7 @@ title: Migrating to TanStack Table V9 (Vue) --- > [!IMPORTANT] -> `v9.0.0-beta.48` introduces a breaking feature split: `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. See the [Grouping Guide](./grouping) and [Aggregation Guide](./aggregation). +> `v9.0.0-beta.48` and `v9.0.0-beta.49` introduces breaking aggregation changes. `columnGroupingFeature` no longer provides aggregation options or APIs. Tables that group rows and calculate aggregate values must now register both `columnGroupingFeature` and `aggregationFeature`. Grouping-only tables can register only `columnGroupingFeature`, while grand totals or other aggregation without grouping can register only `aggregationFeature`. `stockFeatures` already contains both. If you use an explicit feature list, add `aggregationFeature` anywhere you use `aggregationFns`, `aggregationFn`, `aggregatedCell`, `cell.getIsAggregated()`, or `column.getAggregationValue()`. Aggregation definitions, row-depth selection, and the `getAggregationValue` signature also changed; see [Aggregation Feature Split](#aggregation-feature-split), the [Grouping Guide](./grouping), and the [Aggregation Guide](./aggregation). > [!NOTE] > `v9.0.0-beta.38` renames column pinning from physical `left`/`right` terminology to logical `start`/`end` terminology. These are logical positions: in LTR languages/layouts, `start` usually corresponds to left and `end` to right; in RTL languages/layouts, `start` usually corresponds to right and `end` to left. If you migrated on an earlier beta, update `columnPinning.left` to `columnPinning.start`, `columnPinning.right` to `columnPinning.end`, `column.pin('left' | 'right')` to `column.pin('start' | 'end')`, and `getLeft*` / `getRight*` table and row APIs to `getStart*` / `getEnd*`. See the [Column Pinning](#column-pinning) section below for the full mapping. @@ -208,6 +208,38 @@ const total = constructAggregationFn({ }) ``` +Aggregation row selection is now depth-based and shared by every definition on +a column. `maxAggregationDepth` defaults to `0` (the supplied root rows); use +`1` for direct sub-rows or `Infinity` for terminal rows. An explicit +`column.getAggregationValue({ rows, maxDepth })` call can override the column +default. + +`getAggregationValue` now has one options-object signature. Calls without +arguments are unchanged, but positional row and depth arguments must be moved +into the object: + +```ts +// Table V8/earlier V9 betas +column.getAggregationValue(rows, maxDepth) + +// Current V9 +column.getAggregationValue({ rows, maxDepth }) +``` + +All built-in definitions on a column now consume the same depth-selected +`context.rows` frontier. This replaces the old per-function choice between +`childRows` and `leafRows`. The default depth `0` preserves direct-child +grouped aggregation; set `maxAggregationDepth: Infinity` to aggregate terminal +rows. Custom definitions can still inspect grouped `context.subRows`, and +`merge` receives matching `subRowResults` for nested groups. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core +row model. For example, use `Math.max(0, table.getMaxSubRowDepth() - 1)` as +`maxDepth` to target one level before the maximum structural depth; shorter +branches still contribute their deepest available row. Default no-row calls +are cached; calls with `options.rows` are recomputed because the caller owns +that array. + `column.getAggregationFn()` is now `column.getAggregationFns()` because a column can run multiple definitions. A single `aggregationFn` still returns a scalar; an array returns an object keyed by function name or descriptor `id`. The old callable `AggregationFn` and `CreatedAggregationFn` types are replaced by `AggregationFnDef`. ### Available Features diff --git a/docs/guide/aggregation.md b/docs/guide/aggregation.md index f39548a098..0aa5539024 100644 --- a/docs/guide/aggregation.md +++ b/docs/guide/aggregation.md @@ -58,24 +58,53 @@ const amountColumn = columnHelper.accessor('amount', { }) ``` -With no row argument, `column.getAggregationValue()` aggregates the table's +With no options argument, `column.getAggregationValue()` aggregates the table's pre-grouped row model. In the normal client pipeline this includes filtering, -but precedes grouping, sorting, expansion, and pagination. +but precedes grouping, sorting, expansion, and pagination. It uses the column's +`maxAggregationDepth` (`0` by default). ## Choosing Which Rows To Aggregate -Pass any row array to override the default: +Pass rows in the options object to override the default: ```ts -column.getAggregationValue(table.getCoreRowModel().rows) // all core rows -column.getAggregationValue(table.getRowModel().rows) // currently rendered model -column.getAggregationValue(table.getFilteredSelectedRowModel().rows) -column.getAggregationValue(customRows) +column.getAggregationValue({ rows: table.getCoreRowModel().rows }) // all core rows +column.getAggregationValue({ rows: table.getRowModel().rows }) // rendered model +column.getAggregationValue({ + rows: table.getFilteredSelectedRowModel().rows, +}) +column.getAggregationValue({ rows: customRows }) +column.getAggregationValue({ rows: customRows, maxDepth: 1 }) +``` + +Depth is relative to the supplied row array. `0` selects those root rows, `1` +selects their direct sub-rows, and so on. Selection returns a unique frontier: +a branch that ends before the maximum depth contributes its deepest available +row. `Infinity` selects terminal rows. + +Set the cached default depth on the column: + +```ts +const amountColumn = columnHelper.accessor('amount', { + aggregationFn: ['sum', 'mean', 'count'], + maxAggregationDepth: 0, +}) ``` -Hierarchical inputs are normalized to unique terminal leaves. Explicit row -calls are recomputed each time; the default call is cached against its row -model, registry, and column aggregation option. +Every aggregation configured on the column receives the same selected rows. +Explicit-row calls are recomputed each time; the default call is cached against +its row model, depth, registry, and column aggregation option. + +`table.getMaxSubRowDepth()` returns the deepest structural depth in the core row +model. To stop one level before the deepest sub-row frontier: + +```ts +const maxDepth = Math.max(0, table.getMaxSubRowDepth() - 1) +column.getAggregationValue({ + rows: table.getCoreRowModel().rows, + maxDepth, +}) +``` ## Multiple Aggregations Per Column @@ -104,8 +133,9 @@ an `undefined` value. ## Custom Aggregation Definitions -Custom aggregations are context-based definitions. `rows` contains normalized -terminal rows and `getValue(row)` reads the current column's value. +Custom aggregations are context-based definitions. `rows` contains the unique +frontier selected at `maxDepth`, and `getValue(row)` reads the current column's +value. ```ts const joined = constructAggregationFn({ @@ -117,12 +147,28 @@ const joined = constructAggregationFn({ }) ``` -The context also includes `column`, `columnId`, and `table`. During grouped -aggregation it includes `groupingRow`; root and caller-supplied-row aggregation -omit that property. The grouping depth is `groupingRow.depth`. +The context also includes `column`, `columnId`, `maxDepth`, and `table`. During grouped +aggregation it includes `groupingRow` and `subRows`; root and +caller-supplied-row aggregation omit those properties. The grouping depth is +`groupingRow.depth`. `subRows` contains the immediate rows at that grouping +level, so an aggregation can explicitly choose immediate sub-rows instead of +the depth-selected `rows`: + +```ts +const subRowCount = constructAggregationFn({ + aggregate: ({ subRows, rows }) => (subRows ?? rows).length, +}) +``` + +At the terminal grouping level, `subRows` contains direct data rows. At a +nested level, it contains the immediate synthetic sub-row groups. -For a result that can be combined efficiently across nested groups, provide a -`merge` function: +All built-in aggregation definitions consume the same depth-selected `rows`. +`subRows` remains available when a custom definition intentionally needs the +grouping row's immediate structural children. + +For a result that can be combined more efficiently from already-computed +sub-row results, provide a `merge` function: ```ts const sum = constructAggregationFn({ @@ -131,14 +177,18 @@ const sum = constructAggregationFn({ const value = getValue(row) return total + (typeof value === 'number' ? value : 0) }, 0), - merge: ({ childResults }) => - childResults.reduce((total, value) => total + value, 0), + merge: ({ subRowResults }) => + subRowResults.reduce((total, value) => total + value, 0), }) ``` -Without `merge`, nested grouping calls `aggregate` over the group's terminal -rows. This replaces the previous callable aggregation signature and its -`fromRows` and `resolveDataValue` properties. +For `merge`, `subRowResults[i]` is the aggregation result previously computed +for `subRows[i]`. + +Without `merge`, nested grouping calls `aggregate` with both the group's +depth-selected `rows` and its immediate `subRows`. This replaces the previous +callable aggregation signature and its `fromRows` and `resolveDataValue` +properties while preserving the ability to choose either row set. ## Grouped Cell Rendering diff --git a/docs/guide/row-models.md b/docs/guide/row-models.md index 8b3e077eef..abc0c5c5b0 100644 --- a/docs/guide/row-models.md +++ b/docs/guide/row-models.md @@ -139,7 +139,7 @@ For normal rendering use cases, you will probably only need to use the `table.ge - `getPreFilteredRowModel` - returns a row model before column filtering and global filtering are applied. - `getGroupedRowModel` - returns a row model that applies grouping and creates sub-rows. When `aggregationFeature` is also registered, configured aggregate values are computed for those grouped rows. -- `getPreGroupedRowModel` - returns the row model before grouping. It is also the default row set used by `column.getAggregationValue()` for grand totals. +- `getPreGroupedRowModel` - returns the row model before grouping. Its root rows are the default row set used by `column.getAggregationValue()` for grand totals; `maxAggregationDepth` can select a deeper frontier. - `getSortedRowModel` - returns a row model that has had sorting applied to it. - `getPreSortedRowModel` - returns a row model before sorting is applied (rows are in original order). diff --git a/docs/guide/rows.md b/docs/guide/rows.md index f65768f8f6..7791d3304e 100644 --- a/docs/guide/rows.md +++ b/docs/guide/rows.md @@ -103,6 +103,7 @@ If you are using either grouping or expanding features, your rows may contain su - `row.depth`: The depth of the row (if nested or grouped) relative to the root row array. 0 for root level rows, 1 for child rows, 2 for grandchild rows, etc. - `row.parentId`: The unique ID of the parent row for the row (The row that contains this row in its subRows array). - `row.getParentRow`: Returns the parent row for the row, if it exists. +- `table.getMaxSubRowDepth()`: Returns the deepest structural depth in the core row model. The result is memoized until the core row model changes. ## More Row APIs diff --git a/docs/guide/worker-row-models.md b/docs/guide/worker-row-models.md index 4a7e418a08..9d01557a47 100644 --- a/docs/guide/worker-row-models.md +++ b/docs/guide/worker-row-models.md @@ -108,7 +108,7 @@ Offloaded stages must form a contiguous prefix of the pipeline (filtered, then g - **Table options that affect processing** (a custom `globalFilterFn`, for example) must be passed to `initTableWorker` in the shared config, not just to your table hook. - **Grouping aggregates** require both `aggregationFeature` and `columnGroupingFeature` in the shared feature set. They are computed eagerly in the worker, but only for columns with an explicit `aggregationFn` or `aggregatedCell`; group-row `getValue()` for other columns returns `undefined`. - **Multiple aggregation results** are transferred as keyed objects. Custom aggregation results must be supported by the browser's structured-clone algorithm. -- **Grand totals and caller-selected row totals** from `column.getAggregationValue(rows?)` run on the main thread. The worker currently offloads row-model stages, not arbitrary aggregation requests. +- **Grand totals and caller-selected row totals** from `column.getAggregationValue(options?)` run on the main thread. The worker currently offloads row-model stages, not arbitrary aggregation requests. - **SSR** works out of the box: on the server (no `Worker` global) the table renders unprocessed rows, and the client takes over after hydration. - **If the worker fails** to load or throws, the plugin logs an error, keeps the last results on screen, and stops updating; un-resulted stages fall back to their pre-stage models. - **Nothing terminates the worker automatically** yet. `tableWorker.terminate()` exists as a manual escape hatch and self-heals on the next read. diff --git a/docs/reference/index/functions/constructAggregationFn.md b/docs/reference/index/functions/constructAggregationFn.md index db6fb7823a..ce349904f8 100644 --- a/docs/reference/index/functions/constructAggregationFn.md +++ b/docs/reference/index/functions/constructAggregationFn.md @@ -9,7 +9,7 @@ title: constructAggregationFn function constructAggregationFn(definition): AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:75](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L75) +Defined in: [features/aggregation/aggregationFeature.types.ts:83](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L83) Creates a typed context-based aggregation definition for a column or aggregation-function registry. diff --git a/docs/reference/index/functions/createFacetedMinMaxValues.md b/docs/reference/index/functions/createFacetedMinMaxValues.md index 8460fb348f..045b11b632 100644 --- a/docs/reference/index/functions/createFacetedMinMaxValues.md +++ b/docs/reference/index/functions/createFacetedMinMaxValues.md @@ -9,7 +9,7 @@ title: createFacetedMinMaxValues function createFacetedMinMaxValues(): (table, columnId) => () => [number, number] | undefined; ``` -Defined in: [features/column-faceting/createFacetedMinMaxValues.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts#L13) +Defined in: [features/column-faceting/createFacetedMinMaxValues.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedMinMaxValues.ts#L17) Creates a memoized faceted min max values helper for faceted filtering. diff --git a/docs/reference/index/functions/createFacetedUniqueValues.md b/docs/reference/index/functions/createFacetedUniqueValues.md index b57c386c31..88346a3b88 100644 --- a/docs/reference/index/functions/createFacetedUniqueValues.md +++ b/docs/reference/index/functions/createFacetedUniqueValues.md @@ -9,7 +9,7 @@ title: createFacetedUniqueValues function createFacetedUniqueValues(): (table, columnId) => () => Map; ``` -Defined in: [features/column-faceting/createFacetedUniqueValues.ts:13](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts#L13) +Defined in: [features/column-faceting/createFacetedUniqueValues.ts:17](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/column-faceting/createFacetedUniqueValues.ts#L17) Creates a memoized faceted unique values helper for faceted filtering. diff --git a/docs/reference/index/index.md b/docs/reference/index/index.md index 11393af8fc..d330a9a3b5 100644 --- a/docs/reference/index/index.md +++ b/docs/reference/index/index.md @@ -13,6 +13,7 @@ title: index - [AggregationFns](interfaces/AggregationFns.md) - [AggregationMergeContext](interfaces/AggregationMergeContext.md) - [AggregationValueContext](interfaces/AggregationValueContext.md) +- [AggregationValueOptions](interfaces/AggregationValueOptions.md) - [AggregationValueResult](interfaces/AggregationValueResult.md) - [API](interfaces/API.md) - [CachedRowModel\_All](interfaces/CachedRowModel_All.md) diff --git a/docs/reference/index/interfaces/AggregationContext.md b/docs/reference/index/interfaces/AggregationContext.md index 53cd0d1c92..46010c52a6 100644 --- a/docs/reference/index/interfaces/AggregationContext.md +++ b/docs/reference/index/interfaces/AggregationContext.md @@ -59,7 +59,7 @@ Convenience alias for `column.id`. getValue: (row) => TValue; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L24) +Defined in: [features/aggregation/aggregationFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L32) Reads this column's value from one of `rows`. @@ -81,7 +81,7 @@ Reads this column's value from one of `rows`. optional groupingRow: Row; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L30) +Defined in: [features/aggregation/aggregationFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L38) The synthetic grouped row receiving this result. This property is omitted for root or caller-supplied-row aggregation. Its `depth` identifies the @@ -89,16 +89,42 @@ grouping level when grouped aggregation needs that distinction. *** +### maxDepth + +```ts +maxDepth: number; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L24) + +Maximum relative sub-row depth used to select `rows`. + +*** + ### rows ```ts rows: readonly Row[]; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L35) +Defined in: [features/aggregation/aggregationFeature.types.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L43) + +Unique rows selected at `maxDepth`. Branches that end before `maxDepth` +contribute their deepest available row. + +*** + +### subRows? + +```ts +optional subRows: readonly Row[]; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L30) -Terminal leaf rows included in this aggregation. The executor normalizes -hierarchical and duplicate row inputs before invoking the definition. +Immediate sub-rows for grouped aggregation. This property is omitted +for root or caller-supplied-row aggregation. At a terminal grouping level +these are the direct data rows; at a nested level they are sub-row groups. *** @@ -108,6 +134,6 @@ hierarchical and duplicate row inputs before invoking the definition. table: Table; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L37) +Defined in: [features/aggregation/aggregationFeature.types.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L45) The table that owns the column and rows. diff --git a/docs/reference/index/interfaces/AggregationFnDef.md b/docs/reference/index/interfaces/AggregationFnDef.md index 580b19edc3..4d711adab2 100644 --- a/docs/reference/index/interfaces/AggregationFnDef.md +++ b/docs/reference/index/interfaces/AggregationFnDef.md @@ -5,7 +5,7 @@ title: AggregationFnDef # Interface: AggregationFnDef\ -Defined in: [features/aggregation/aggregationFeature.types.ts:54](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L54) +Defined in: [features/aggregation/aggregationFeature.types.ts:62](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L62) A context-based aggregation definition and optional grouped-result merge. @@ -35,9 +35,9 @@ A context-based aggregation definition and optional grouped-result merge. aggregate: (context) => TResult; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:61](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L61) +Defined in: [features/aggregation/aggregationFeature.types.ts:69](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L69) -Computes a result directly from normalized terminal rows. +Computes a result directly from the selected `rows`. #### Parameters @@ -57,10 +57,10 @@ Computes a result directly from normalized terminal rows. optional merge: (context) => TResult; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L66) +Defined in: [features/aggregation/aggregationFeature.types.ts:74](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L74) -Combines already-computed immediate child-group results. When omitted, -nested grouping falls back to `aggregate` over the group's terminal rows. +Combines already-computed immediate sub-row results. When omitted, +nested grouping falls back to `aggregate` over the group's selected rows. #### Parameters diff --git a/docs/reference/index/interfaces/AggregationFnDescriptor.md b/docs/reference/index/interfaces/AggregationFnDescriptor.md index ab8b9981d0..194bc8a340 100644 --- a/docs/reference/index/interfaces/AggregationFnDescriptor.md +++ b/docs/reference/index/interfaces/AggregationFnDescriptor.md @@ -5,7 +5,7 @@ title: AggregationFnDescriptor # Interface: AggregationFnDescriptor\ -Defined in: [features/aggregation/aggregationFeature.types.ts:120](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L120) +Defined in: [features/aggregation/aggregationFeature.types.ts:128](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L128) Gives an aggregation reference a stable key in a multiple result. @@ -35,7 +35,7 @@ Gives an aggregation reference a stable key in a multiple result. aggregationFn: AggregationFnRef; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:127](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L127) +Defined in: [features/aggregation/aggregationFeature.types.ts:135](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L135) The named, automatic, or inline definition to execute. @@ -47,6 +47,6 @@ The named, automatic, or inline definition to execute. id: string; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:129](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L129) +Defined in: [features/aggregation/aggregationFeature.types.ts:137](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L137) Stable key used in the object returned by a multiple aggregation. diff --git a/docs/reference/index/interfaces/AggregationMergeContext.md b/docs/reference/index/interfaces/AggregationMergeContext.md index 3ed2dde8b9..b4f39cdb99 100644 --- a/docs/reference/index/interfaces/AggregationMergeContext.md +++ b/docs/reference/index/interfaces/AggregationMergeContext.md @@ -5,7 +5,7 @@ title: AggregationMergeContext # Interface: AggregationMergeContext\ -Defined in: [features/aggregation/aggregationFeature.types.ts:41](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L41) +Defined in: [features/aggregation/aggregationFeature.types.ts:49](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L49) Additional values available when merging nested grouped results. @@ -33,30 +33,6 @@ Additional values available when merging nested grouped results. ## Properties -### childResults - -```ts -childResults: readonly TResult[]; -``` - -Defined in: [features/aggregation/aggregationFeature.types.ts:48](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L48) - -Results produced for each immediate child group, in child-row order. - -*** - -### childRows - -```ts -childRows: readonly Row[]; -``` - -Defined in: [features/aggregation/aggregationFeature.types.ts:50](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L50) - -Immediate child group rows corresponding to `childResults`. - -*** - ### column ```ts @@ -95,7 +71,7 @@ Convenience alias for `column.id`. getValue: (row) => TValue; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L24) +Defined in: [features/aggregation/aggregationFeature.types.ts:32](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L32) Reads this column's value from one of `rows`. @@ -121,7 +97,7 @@ Reads this column's value from one of `rows`. optional groupingRow: Row; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:30](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L30) +Defined in: [features/aggregation/aggregationFeature.types.ts:38](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L38) The synthetic grouped row receiving this result. This property is omitted for root or caller-supplied-row aggregation. Its `depth` identifies the @@ -133,16 +109,32 @@ grouping level when grouped aggregation needs that distinction. *** +### maxDepth + +```ts +maxDepth: number; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:24](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L24) + +Maximum relative sub-row depth used to select `rows`. + +#### Inherited from + +[`AggregationContext`](AggregationContext.md).[`maxDepth`](AggregationContext.md#maxdepth) + +*** + ### rows ```ts rows: readonly Row[]; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:35](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L35) +Defined in: [features/aggregation/aggregationFeature.types.ts:43](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L43) -Terminal leaf rows included in this aggregation. The executor normalizes -hierarchical and duplicate row inputs before invoking the definition. +Unique rows selected at `maxDepth`. Branches that end before `maxDepth` +contribute their deepest available row. #### Inherited from @@ -150,13 +142,41 @@ hierarchical and duplicate row inputs before invoking the definition. *** +### subRowResults + +```ts +subRowResults: readonly TResult[]; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:56](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L56) + +Results produced for each immediate sub-row group, in sub-row order. + +*** + +### subRows + +```ts +subRows: readonly Row[]; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:58](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L58) + +Immediate sub-row groups corresponding to `subRowResults`. + +#### Overrides + +[`AggregationContext`](AggregationContext.md).[`subRows`](AggregationContext.md#subrows) + +*** + ### table ```ts table: Table; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:37](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L37) +Defined in: [features/aggregation/aggregationFeature.types.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L45) The table that owns the column and rows. diff --git a/docs/reference/index/interfaces/AggregationValueContext.md b/docs/reference/index/interfaces/AggregationValueContext.md index 5e07ccef91..1d6d069fb8 100644 --- a/docs/reference/index/interfaces/AggregationValueContext.md +++ b/docs/reference/index/interfaces/AggregationValueContext.md @@ -5,7 +5,7 @@ title: AggregationValueContext # Interface: AggregationValueContext\ -Defined in: [features/aggregation/aggregationFeature.types.ts:285](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L285) +Defined in: [features/aggregation/aggregationFeature.types.ts:310](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L310) Values passed to a column-level aggregation-value provider. @@ -31,19 +31,31 @@ Values passed to a column-level aggregation-value provider. column: Column; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:291](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L291) +Defined in: [features/aggregation/aggregationFeature.types.ts:316](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L316) The column whose value was requested. *** +### maxDepth + +```ts +maxDepth: number; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:318](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L318) + +Maximum relative sub-row depth used for the request. + +*** + ### rows? ```ts optional rows: readonly Row[]; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:293](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L293) +Defined in: [features/aggregation/aggregationFeature.types.ts:320](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L320) Caller-provided rows, or `undefined` for the default row model. @@ -55,6 +67,6 @@ Caller-provided rows, or `undefined` for the default row model. table: Table; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:295](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L295) +Defined in: [features/aggregation/aggregationFeature.types.ts:322](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L322) The table that owns the column. diff --git a/docs/reference/index/interfaces/AggregationValueOptions.md b/docs/reference/index/interfaces/AggregationValueOptions.md new file mode 100644 index 0000000000..42214e47c9 --- /dev/null +++ b/docs/reference/index/interfaces/AggregationValueOptions.md @@ -0,0 +1,44 @@ +--- +id: AggregationValueOptions +title: AggregationValueOptions +--- + +# Interface: AggregationValueOptions\ + +Defined in: [features/aggregation/aggregationFeature.types.ts:287](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L287) + +Options for a caller-requested column aggregation value. + +## Type Parameters + +### TFeatures + +`TFeatures` *extends* [`TableFeatures`](TableFeatures.md) + +### TData + +`TData` *extends* [`RowData`](../type-aliases/RowData.md) + +## Properties + +### maxDepth? + +```ts +optional maxDepth: number; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:292](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L292) + +Overrides the column's `maxAggregationDepth` for this request. + +*** + +### rows? + +```ts +optional rows: readonly Row[]; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:294](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L294) + +Rows to aggregate instead of the default pre-grouped row model. diff --git a/docs/reference/index/interfaces/AggregationValueResult.md b/docs/reference/index/interfaces/AggregationValueResult.md index 1e13229a44..0b56c9aff7 100644 --- a/docs/reference/index/interfaces/AggregationValueResult.md +++ b/docs/reference/index/interfaces/AggregationValueResult.md @@ -5,7 +5,7 @@ title: AggregationValueResult # Interface: AggregationValueResult\ -Defined in: [features/aggregation/aggregationFeature.types.ts:299](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L299) +Defined in: [features/aggregation/aggregationFeature.types.ts:326](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L326) Marks an aggregation-value override as handled. @@ -23,6 +23,6 @@ Marks an aggregation-value override as handled. value: TResult; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:301](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L301) +Defined in: [features/aggregation/aggregationFeature.types.ts:328](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L328) The supplied value. `undefined` is still a handled result. diff --git a/docs/reference/index/interfaces/Cell_Aggregation.md b/docs/reference/index/interfaces/Cell_Aggregation.md index 1579b3c135..18b399208c 100644 --- a/docs/reference/index/interfaces/Cell_Aggregation.md +++ b/docs/reference/index/interfaces/Cell_Aggregation.md @@ -5,7 +5,7 @@ title: Cell_Aggregation # Interface: Cell\_Aggregation -Defined in: [features/aggregation/aggregationFeature.types.ts:273](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L273) +Defined in: [features/aggregation/aggregationFeature.types.ts:298](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L298) Cell instance APIs installed by `aggregationFeature`. @@ -17,7 +17,7 @@ Cell instance APIs installed by `aggregationFeature`. getIsAggregated: () => boolean; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:275](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L275) +Defined in: [features/aggregation/aggregationFeature.types.ts:300](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L300) Whether this cell displays an aggregate on a synthetic grouped row. diff --git a/docs/reference/index/interfaces/ColumnDef_Aggregation.md b/docs/reference/index/interfaces/ColumnDef_Aggregation.md index edc8edd442..e60a36caca 100644 --- a/docs/reference/index/interfaces/ColumnDef_Aggregation.md +++ b/docs/reference/index/interfaces/ColumnDef_Aggregation.md @@ -5,7 +5,7 @@ title: ColumnDef_Aggregation # Interface: ColumnDef\_Aggregation\ -Defined in: [features/aggregation/aggregationFeature.types.ts:225](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L225) +Defined in: [features/aggregation/aggregationFeature.types.ts:233](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L233) Column-definition options installed by `aggregationFeature`. @@ -31,7 +31,7 @@ Column-definition options installed by `aggregationFeature`. optional aggregatedCell: ColumnDefTemplate["getContext"]>>; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:231](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L231) +Defined in: [features/aggregation/aggregationFeature.types.ts:239](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L239) Renderer used for a grouped row's aggregated cell. @@ -43,7 +43,7 @@ Renderer used for a grouped row's aggregated cell. optional aggregationFn: AggregationFnOption; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:238](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L238) +Defined in: [features/aggregation/aggregationFeature.types.ts:246](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L246) One aggregation reference for a scalar result, or an array for a keyed result object. Inline definitions in an array require an explicit `id`. @@ -58,7 +58,7 @@ optional getAggregationValue: (context) => | undefined; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:244](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L244) +Defined in: [features/aggregation/aggregationFeature.types.ts:258](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L258) Optionally supplies a precomputed aggregation value for this column. Return `{ value }` to handle the request, including `{ value: undefined }`; @@ -74,3 +74,17 @@ return `undefined` to use the local aggregation fallback. \| [`AggregationValueResult`](AggregationValueResult.md)\<`unknown`\> \| `undefined` + +*** + +### maxAggregationDepth? + +```ts +optional maxAggregationDepth: number; +``` + +Defined in: [features/aggregation/aggregationFeature.types.ts:252](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L252) + +Maximum relative sub-row depth used for grouped aggregation and cached +default totals. `0` selects the supplied root rows, `1` their direct +sub-rows, and so on. Defaults to `0`. diff --git a/docs/reference/index/interfaces/Column_Aggregation.md b/docs/reference/index/interfaces/Column_Aggregation.md index 8fb868302f..7d7eace791 100644 --- a/docs/reference/index/interfaces/Column_Aggregation.md +++ b/docs/reference/index/interfaces/Column_Aggregation.md @@ -5,7 +5,7 @@ title: Column_Aggregation # Interface: Column\_Aggregation\ -Defined in: [features/aggregation/aggregationFeature.types.ts:250](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L250) +Defined in: [features/aggregation/aggregationFeature.types.ts:264](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L264) Column instance APIs installed by `aggregationFeature`. @@ -27,7 +27,7 @@ Column instance APIs installed by `aggregationFeature`. getAggregationFns: () => readonly ResolvedAggregationFn[]; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:255](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L255) +Defined in: [features/aggregation/aggregationFeature.types.ts:269](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L269) Resolves the configured scalar or multiple aggregation definitions. @@ -40,14 +40,14 @@ readonly [`ResolvedAggregationFn`](ResolvedAggregationFn.md)\<`TFeatures`, `TDat ### getAggregationValue() ```ts -getAggregationValue: (rows?) => TResult; +getAggregationValue: (options?) => TResult; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:263](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L263) +Defined in: [features/aggregation/aggregationFeature.types.ts:277](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L277) Aggregates this column over the default pre-grouped row model, or over a -caller-provided array of rows. Explicit rows are normalized to unique -terminal leaves and are intentionally not cached. +caller-provided array of rows. `options.maxDepth` overrides the column's +`maxAggregationDepth`. Explicit-row calls are intentionally not cached. #### Type Parameters @@ -57,9 +57,9 @@ terminal leaves and are intentionally not cached. #### Parameters -##### rows? +##### options? -readonly [`Row`](../type-aliases/Row.md)\<`TFeatures`, `TData`\>[] +[`AggregationValueOptions`](AggregationValueOptions.md)\<`TFeatures`, `TData`\> #### Returns @@ -75,7 +75,7 @@ getAutoAggregationFn: () => | undefined; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:267](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L267) +Defined in: [features/aggregation/aggregationFeature.types.ts:281](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L281) Infers `sum` for a numeric first row and `extent` for a Date first row. diff --git a/docs/reference/index/interfaces/ResolvedAggregationFn.md b/docs/reference/index/interfaces/ResolvedAggregationFn.md index 0552faae69..5041d01e95 100644 --- a/docs/reference/index/interfaces/ResolvedAggregationFn.md +++ b/docs/reference/index/interfaces/ResolvedAggregationFn.md @@ -5,7 +5,7 @@ title: ResolvedAggregationFn # Interface: ResolvedAggregationFn\ -Defined in: [features/aggregation/aggregationFeature.types.ts:214](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L214) +Defined in: [features/aggregation/aggregationFeature.types.ts:222](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L222) A validated aggregation entry returned by `column.getAggregationFns()`. @@ -29,7 +29,7 @@ aggregationFn: | undefined; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:219](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L219) +Defined in: [features/aggregation/aggregationFeature.types.ts:227](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L227) Resolved definition, or `undefined` when configuration is invalid. @@ -41,6 +41,6 @@ Resolved definition, or `undefined` when configuration is invalid. id: string | undefined; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:221](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L221) +Defined in: [features/aggregation/aggregationFeature.types.ts:229](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L229) Key used for a multiple result; scalar inline definitions have no id. diff --git a/docs/reference/index/interfaces/RowModelFns_Aggregation.md b/docs/reference/index/interfaces/RowModelFns_Aggregation.md index 84f365407d..7f0a3d8c6d 100644 --- a/docs/reference/index/interfaces/RowModelFns_Aggregation.md +++ b/docs/reference/index/interfaces/RowModelFns_Aggregation.md @@ -5,7 +5,7 @@ title: RowModelFns_Aggregation # Interface: RowModelFns\_Aggregation\ -Defined in: [features/aggregation/aggregationFeature.types.ts:87](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L87) +Defined in: [features/aggregation/aggregationFeature.types.ts:95](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L95) Aggregation-definition registry carried by a table feature set. @@ -27,4 +27,4 @@ Aggregation-definition registry carried by a table feature set. aggregationFns: Record>; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:91](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L91) +Defined in: [features/aggregation/aggregationFeature.types.ts:99](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L99) diff --git a/docs/reference/index/interfaces/RowModelFns_All.md b/docs/reference/index/interfaces/RowModelFns_All.md index 03db547701..5789ff99d0 100644 --- a/docs/reference/index/interfaces/RowModelFns_All.md +++ b/docs/reference/index/interfaces/RowModelFns_All.md @@ -29,7 +29,7 @@ Defined in: [types/RowModelFns.ts:25](https://github.com/TanStack/table/blob/mai optional aggregationFns: Record>; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:91](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L91) +Defined in: [features/aggregation/aggregationFeature.types.ts:99](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L99) #### Inherited from diff --git a/docs/reference/index/interfaces/Row_Aggregation.md b/docs/reference/index/interfaces/Row_Aggregation.md index 7a0af02a70..8344e345c3 100644 --- a/docs/reference/index/interfaces/Row_Aggregation.md +++ b/docs/reference/index/interfaces/Row_Aggregation.md @@ -5,7 +5,7 @@ title: Row_Aggregation # Interface: Row\_Aggregation -Defined in: [features/aggregation/aggregationFeature.types.ts:279](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L279) +Defined in: [features/aggregation/aggregationFeature.types.ts:304](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L304) Internal per-row cache used while grouped aggregates are evaluated. @@ -17,6 +17,6 @@ Internal per-row cache used while grouped aggregates are evaluated. _aggregationValuesCache: Record; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:281](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L281) +Defined in: [features/aggregation/aggregationFeature.types.ts:306](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L306) Cached aggregate results keyed by column id. diff --git a/docs/reference/index/interfaces/TableOptions_Aggregation.md b/docs/reference/index/interfaces/TableOptions_Aggregation.md index 0e43b9f6ea..5658150dbe 100644 --- a/docs/reference/index/interfaces/TableOptions_Aggregation.md +++ b/docs/reference/index/interfaces/TableOptions_Aggregation.md @@ -5,7 +5,7 @@ title: TableOptions_Aggregation # Interface: TableOptions\_Aggregation -Defined in: [features/aggregation/aggregationFeature.types.ts:305](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L305) +Defined in: [features/aggregation/aggregationFeature.types.ts:332](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L332) Table options installed by `aggregationFeature`. @@ -17,7 +17,7 @@ Table options installed by `aggregationFeature`. optional manualAggregation: boolean; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:311](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L311) +Defined in: [features/aggregation/aggregationFeature.types.ts:338](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L338) Disables local `column.getAggregationValue()` calculation when a column override does not handle the request. Group values supplied by manually diff --git a/docs/reference/index/interfaces/Table_Core.md b/docs/reference/index/interfaces/Table_Core.md index d01de49646..72a2e66a88 100644 --- a/docs/reference/index/interfaces/Table_Core.md +++ b/docs/reference/index/interfaces/Table_Core.md @@ -580,6 +580,27 @@ Collects only leaf headers, excluding parent/group headers. *** +### getMaxSubRowDepth() + +```ts +getMaxSubRowDepth: () => number; +``` + +Defined in: [core/rows/coreRowsFeature.types.ts:138](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L138) + +Returns the deepest structural row depth in the core row model. +Root rows are depth `0`, direct sub-rows are depth `1`, and so on. + +#### Returns + +`number` + +#### Inherited from + +[`Table_Rows`](Table_Rows.md).[`getMaxSubRowDepth`](Table_Rows.md#getmaxsubrowdepth) + +*** + ### getPaginatedRowModel() ```ts @@ -718,7 +739,7 @@ Table_RowModels.getPreSortedRowModel getRow: (id, searchAll?) => Row; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L145) +Defined in: [core/rows/coreRowsFeature.types.ts:153](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L153) Returns the row with the given ID. @@ -748,7 +769,9 @@ Returns the row with the given ID. getRowId: (_, index, parent?) => string; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L141) +Defined in: [core/rows/coreRowsFeature.types.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L149) + +Returns the row id for a given row. #### Parameters @@ -802,7 +825,7 @@ Table_RowModels.getRowModel getRowsInDisplayOrder: () => Row[]; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L140) +Defined in: [core/rows/coreRowsFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L145) Returns the rows in the current display order and assigns their display indexes. When expanded rows bypass pagination, expanded descendants are diff --git a/docs/reference/index/interfaces/Table_Internal.md b/docs/reference/index/interfaces/Table_Internal.md index ea45b6dca1..1e9f33a695 100644 --- a/docs/reference/index/interfaces/Table_Internal.md +++ b/docs/reference/index/interfaces/Table_Internal.md @@ -573,6 +573,27 @@ Collects only leaf headers, excluding parent/group headers. *** +### getMaxSubRowDepth() + +```ts +getMaxSubRowDepth: () => number; +``` + +Defined in: [core/rows/coreRowsFeature.types.ts:138](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L138) + +Returns the deepest structural row depth in the core row model. +Root rows are depth `0`, direct sub-rows are depth `1`, and so on. + +#### Returns + +`number` + +#### Inherited from + +[`Table_Rows`](Table_Rows.md).[`getMaxSubRowDepth`](Table_Rows.md#getmaxsubrowdepth) + +*** + ### getPaginatedRowModel() ```ts @@ -711,7 +732,7 @@ Table_RowModels.getPreSortedRowModel getRow: (id, searchAll?) => Row; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L145) +Defined in: [core/rows/coreRowsFeature.types.ts:153](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L153) Returns the row with the given ID. @@ -741,7 +762,9 @@ Returns the row with the given ID. getRowId: (_, index, parent?) => string; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L141) +Defined in: [core/rows/coreRowsFeature.types.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L149) + +Returns the row id for a given row. #### Parameters @@ -795,7 +818,7 @@ Table_RowModels.getRowModel getRowsInDisplayOrder: () => Row[]; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L140) +Defined in: [core/rows/coreRowsFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L145) Returns the rows in the current display order and assigns their display indexes. When expanded rows bypass pagination, expanded descendants are diff --git a/docs/reference/index/interfaces/Table_Rows.md b/docs/reference/index/interfaces/Table_Rows.md index a2b117bba4..2f0fde147c 100644 --- a/docs/reference/index/interfaces/Table_Rows.md +++ b/docs/reference/index/interfaces/Table_Rows.md @@ -24,13 +24,30 @@ Defined in: [core/rows/coreRowsFeature.types.ts:130](https://github.com/TanStack ## Properties +### getMaxSubRowDepth() + +```ts +getMaxSubRowDepth: () => number; +``` + +Defined in: [core/rows/coreRowsFeature.types.ts:138](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L138) + +Returns the deepest structural row depth in the core row model. +Root rows are depth `0`, direct sub-rows are depth `1`, and so on. + +#### Returns + +`number` + +*** + ### getRow() ```ts getRow: (id, searchAll?) => Row; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L145) +Defined in: [core/rows/coreRowsFeature.types.ts:153](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L153) Returns the row with the given ID. @@ -56,7 +73,9 @@ Returns the row with the given ID. getRowId: (_, index, parent?) => string; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L141) +Defined in: [core/rows/coreRowsFeature.types.ts:149](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L149) + +Returns the row id for a given row. #### Parameters @@ -84,7 +103,7 @@ Defined in: [core/rows/coreRowsFeature.types.ts:141](https://github.com/TanStack getRowsInDisplayOrder: () => Row[]; ``` -Defined in: [core/rows/coreRowsFeature.types.ts:140](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L140) +Defined in: [core/rows/coreRowsFeature.types.ts:145](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.types.ts#L145) Returns the rows in the current display order and assigns their display indexes. When expanded rows bypass pagination, expanded descendants are diff --git a/docs/reference/index/type-aliases/AggregationFnListItem.md b/docs/reference/index/type-aliases/AggregationFnListItem.md index d9646f338b..ef6d040c9f 100644 --- a/docs/reference/index/type-aliases/AggregationFnListItem.md +++ b/docs/reference/index/type-aliases/AggregationFnListItem.md @@ -12,7 +12,7 @@ type AggregationFnListItem = | AggregationFnDescriptor; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:133](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L133) +Defined in: [features/aggregation/aggregationFeature.types.ts:141](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L141) One named or explicitly keyed entry in a multiple aggregation option. diff --git a/docs/reference/index/type-aliases/AggregationFnOption.md b/docs/reference/index/type-aliases/AggregationFnOption.md index 2b469a3a62..136aa9fc24 100644 --- a/docs/reference/index/type-aliases/AggregationFnOption.md +++ b/docs/reference/index/type-aliases/AggregationFnOption.md @@ -11,7 +11,7 @@ type AggregationFnOption = | ReadonlyArray>; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:143](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L143) +Defined in: [features/aggregation/aggregationFeature.types.ts:151](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L151) A scalar aggregation reference or a list that produces a keyed object. diff --git a/docs/reference/index/type-aliases/AggregationFnRef.md b/docs/reference/index/type-aliases/AggregationFnRef.md index 45e7769558..e19012a8c1 100644 --- a/docs/reference/index/type-aliases/AggregationFnRef.md +++ b/docs/reference/index/type-aliases/AggregationFnRef.md @@ -12,7 +12,7 @@ type AggregationFnRef = | AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L109) +Defined in: [features/aggregation/aggregationFeature.types.ts:117](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L117) A registered name, automatic inference, or inline aggregation definition. diff --git a/docs/reference/index/type-aliases/AggregationResult.md b/docs/reference/index/type-aliases/AggregationResult.md index 436d3e0a0c..8e68acda85 100644 --- a/docs/reference/index/type-aliases/AggregationResult.md +++ b/docs/reference/index/type-aliases/AggregationResult.md @@ -9,7 +9,7 @@ title: AggregationResult type AggregationResult = TOption extends ReadonlyArray ? { [TKey in AggregationEntryId]: AggregationResultOfRef>, TFeatures> } : AggregationResultOfRef; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:190](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L190) +Defined in: [features/aggregation/aggregationFeature.types.ts:198](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L198) Infers the scalar or keyed result produced by an aggregation option. diff --git a/docs/reference/index/type-aliases/AggregationResultOf.md b/docs/reference/index/type-aliases/AggregationResultOf.md index 984b05164d..0507d848bd 100644 --- a/docs/reference/index/type-aliases/AggregationResultOf.md +++ b/docs/reference/index/type-aliases/AggregationResultOf.md @@ -9,7 +9,7 @@ title: AggregationResultOf type AggregationResultOf = TDefinition extends AggregationFnDef ? TResult : unknown; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:152](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L152) +Defined in: [features/aggregation/aggregationFeature.types.ts:160](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L160) Extracts the result type produced by an aggregation definition. diff --git a/docs/reference/index/type-aliases/BuiltInAggregationFn.md b/docs/reference/index/type-aliases/BuiltInAggregationFn.md index 66ecc6de69..26e2913ad5 100644 --- a/docs/reference/index/type-aliases/BuiltInAggregationFn.md +++ b/docs/reference/index/type-aliases/BuiltInAggregationFn.md @@ -9,4 +9,4 @@ title: BuiltInAggregationFn type BuiltInAggregationFn = keyof typeof aggregationFns; ``` -Defined in: [features/aggregation/aggregationFns.ts:336](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L336) +Defined in: [features/aggregation/aggregationFns.ts:345](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L345) diff --git a/docs/reference/index/type-aliases/ColumnAggregationValue.md b/docs/reference/index/type-aliases/ColumnAggregationValue.md index ef8b3d4120..b4e5ff782b 100644 --- a/docs/reference/index/type-aliases/ColumnAggregationValue.md +++ b/docs/reference/index/type-aliases/ColumnAggregationValue.md @@ -12,7 +12,7 @@ type ColumnAggregationValue = | undefined; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:208](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L208) +Defined in: [features/aggregation/aggregationFeature.types.ts:216](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L216) Default public result union when a column's precise option is not known. diff --git a/docs/reference/index/type-aliases/CustomAggregationFns.md b/docs/reference/index/type-aliases/CustomAggregationFns.md index d4d26a9c2e..43a58215d1 100644 --- a/docs/reference/index/type-aliases/CustomAggregationFns.md +++ b/docs/reference/index/type-aliases/CustomAggregationFns.md @@ -9,7 +9,7 @@ title: CustomAggregationFns type CustomAggregationFns = Record>; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:95](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L95) +Defined in: [features/aggregation/aggregationFeature.types.ts:103](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L103) Named context-based aggregation definitions registered on a feature set. diff --git a/docs/reference/index/type-aliases/ExtractAggregationFnKeys.md b/docs/reference/index/type-aliases/ExtractAggregationFnKeys.md index 8ad4888d6d..0607e96b14 100644 --- a/docs/reference/index/type-aliases/ExtractAggregationFnKeys.md +++ b/docs/reference/index/type-aliases/ExtractAggregationFnKeys.md @@ -11,7 +11,7 @@ type ExtractAggregationFnKeys = IsAny extends true ? | BuiltInAggregationFn : TFeatures extends object ? Extract : keyof AggregationFns; ``` -Defined in: [features/aggregation/aggregationFeature.types.ts:101](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L101) +Defined in: [features/aggregation/aggregationFeature.types.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.types.ts#L109) String names available from a feature set's aggregation registry. diff --git a/docs/reference/index/variables/aggregationFn_count.md b/docs/reference/index/variables/aggregationFn_count.md index 4c5314a293..23fc4545a8 100644 --- a/docs/reference/index/variables/aggregationFn_count.md +++ b/docs/reference/index/variables/aggregationFn_count.md @@ -9,6 +9,6 @@ title: aggregationFn_count const aggregationFn_count: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:273](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L273) +Defined in: [features/aggregation/aggregationFns.ts:282](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L282) Counts rows, independently of the column's values. diff --git a/docs/reference/index/variables/aggregationFn_extent.md b/docs/reference/index/variables/aggregationFn_extent.md index e5dd1acb68..67235c6968 100644 --- a/docs/reference/index/variables/aggregationFn_extent.md +++ b/docs/reference/index/variables/aggregationFn_extent.md @@ -9,7 +9,8 @@ title: aggregationFn_extent const aggregationFn_extent: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:143](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L143) +Defined in: [features/aggregation/aggregationFns.ts:146](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L146) -Finds the minimum and maximum numeric or Date values. Empty inputs return +Finds the minimum and maximum numeric or Date values from the selected rows. +Empty inputs return `[undefined, undefined]`, preserving the previous built-in result shape. diff --git a/docs/reference/index/variables/aggregationFn_first.md b/docs/reference/index/variables/aggregationFn_first.md index 1da1cbfa2e..62dae0f6fe 100644 --- a/docs/reference/index/variables/aggregationFn_first.md +++ b/docs/reference/index/variables/aggregationFn_first.md @@ -9,6 +9,6 @@ title: aggregationFn_first const aggregationFn_first: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:291](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L291) +Defined in: [features/aggregation/aggregationFns.ts:300](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L300) Returns the first row's value, including a nullish value. diff --git a/docs/reference/index/variables/aggregationFn_last.md b/docs/reference/index/variables/aggregationFn_last.md index 746e6138f3..e611677421 100644 --- a/docs/reference/index/variables/aggregationFn_last.md +++ b/docs/reference/index/variables/aggregationFn_last.md @@ -9,6 +9,6 @@ title: aggregationFn_last const aggregationFn_last: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:303](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L303) +Defined in: [features/aggregation/aggregationFns.ts:312](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L312) Returns the last row's value, including a nullish value. diff --git a/docs/reference/index/variables/aggregationFn_max.md b/docs/reference/index/variables/aggregationFn_max.md index fa92a6c7c0..50f3977729 100644 --- a/docs/reference/index/variables/aggregationFn_max.md +++ b/docs/reference/index/variables/aggregationFn_max.md @@ -9,7 +9,7 @@ title: aggregationFn_max const aggregationFn_max: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:108](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L108) +Defined in: [features/aggregation/aggregationFns.ts:109](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L109) -Finds the maximum numeric or Date value. Invalid value types are ignored; -`NaN` preserves the legacy numeric seeding behavior. +Finds the maximum numeric or Date value from the selected rows. Invalid value +types are ignored; `NaN` preserves the legacy numeric seeding behavior. diff --git a/docs/reference/index/variables/aggregationFn_mean.md b/docs/reference/index/variables/aggregationFn_mean.md index adb036cbdb..81b3a77462 100644 --- a/docs/reference/index/variables/aggregationFn_mean.md +++ b/docs/reference/index/variables/aggregationFn_mean.md @@ -9,7 +9,7 @@ title: aggregationFn_mean const aggregationFn_mean: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:192](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L192) +Defined in: [features/aggregation/aggregationFns.ts:201](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L201) Averages number and number-like row values. Nullish and non-numeric values are ignored; other values retain the legacy unary-plus coercion behavior. diff --git a/docs/reference/index/variables/aggregationFn_median.md b/docs/reference/index/variables/aggregationFn_median.md index 126213feca..7aa9261c8b 100644 --- a/docs/reference/index/variables/aggregationFn_median.md +++ b/docs/reference/index/variables/aggregationFn_median.md @@ -9,7 +9,7 @@ title: aggregationFn_median const aggregationFn_median: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:218](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L218) +Defined in: [features/aggregation/aggregationFns.ts:227](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L227) Computes the median when every row value is a number. Returns `undefined` for empty inputs or when any value is non-numeric. diff --git a/docs/reference/index/variables/aggregationFn_min.md b/docs/reference/index/variables/aggregationFn_min.md index 11dad0586b..5faac44990 100644 --- a/docs/reference/index/variables/aggregationFn_min.md +++ b/docs/reference/index/variables/aggregationFn_min.md @@ -11,5 +11,5 @@ const aggregationFn_min: AggregationFnDef; Defined in: [features/aggregation/aggregationFns.ts:45](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L45) -Sums numeric row values. Non-number values contribute zero. As in the -previous API, `NaN` is a number and therefore propagates through the sum. +Sums numeric selected-row values. Non-number values contribute zero. As in +the previous API, `NaN` is a number and therefore propagates through the sum. diff --git a/docs/reference/index/variables/aggregationFn_unique.md b/docs/reference/index/variables/aggregationFn_unique.md index 6db3b38bd9..0f2a44a317 100644 --- a/docs/reference/index/variables/aggregationFn_unique.md +++ b/docs/reference/index/variables/aggregationFn_unique.md @@ -9,6 +9,6 @@ title: aggregationFn_unique const aggregationFn_unique: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:241](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L241) +Defined in: [features/aggregation/aggregationFns.ts:250](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L250) Collects distinct row values using JavaScript `Set` semantics. diff --git a/docs/reference/index/variables/aggregationFn_uniqueCount.md b/docs/reference/index/variables/aggregationFn_uniqueCount.md index b290fa7b12..84feb77f1c 100644 --- a/docs/reference/index/variables/aggregationFn_uniqueCount.md +++ b/docs/reference/index/variables/aggregationFn_uniqueCount.md @@ -9,6 +9,6 @@ title: aggregationFn_uniqueCount const aggregationFn_uniqueCount: AggregationFnDef; ``` -Defined in: [features/aggregation/aggregationFns.ts:257](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L257) +Defined in: [features/aggregation/aggregationFns.ts:266](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L266) Counts distinct row values using JavaScript `Set` semantics. diff --git a/docs/reference/index/variables/aggregationFns.md b/docs/reference/index/variables/aggregationFns.md index 607abc59b5..3a6af75044 100644 --- a/docs/reference/index/variables/aggregationFns.md +++ b/docs/reference/index/variables/aggregationFns.md @@ -9,7 +9,7 @@ title: aggregationFns const aggregationFns: object; ``` -Defined in: [features/aggregation/aggregationFns.ts:322](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L322) +Defined in: [features/aggregation/aggregationFns.ts:331](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFns.ts#L331) Full built-in registry. Register individual definitions for tree-shaking. diff --git a/docs/reference/index/variables/coreRowsFeature.md b/docs/reference/index/variables/coreRowsFeature.md index d582ba459b..9bf5d3e362 100644 --- a/docs/reference/index/variables/coreRowsFeature.md +++ b/docs/reference/index/variables/coreRowsFeature.md @@ -9,6 +9,6 @@ title: coreRowsFeature const coreRowsFeature: TableFeature; ``` -Defined in: [core/rows/coreRowsFeature.ts:21](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.ts#L21) +Defined in: [core/rows/coreRowsFeature.ts:22](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.ts#L22) Core feature that creates row APIs for values, cells, and tree traversal. diff --git a/docs/reference/static-functions/functions/aggregateColumnValue.md b/docs/reference/static-functions/functions/aggregateColumnValue.md index f6da9a4580..73a835d98f 100644 --- a/docs/reference/static-functions/functions/aggregateColumnValue.md +++ b/docs/reference/static-functions/functions/aggregateColumnValue.md @@ -9,9 +9,9 @@ title: aggregateColumnValue function aggregateColumnValue(args): unknown; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:248](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L248) +Defined in: [features/aggregation/aggregationFeature.utils.ts:261](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L261) -Executes every configured aggregation for a column over normalized rows. +Executes every configured aggregation over a depth-selected row frontier. ## Type Parameters @@ -27,10 +27,6 @@ Executes every configured aggregation for a column over normalized rows. ### args -#### childRows? - -readonly [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] - #### column [`Column`](../../index/type-aliases/Column.md)\<`TFeatures`, `TData`, `unknown`\> @@ -39,10 +35,18 @@ readonly [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\> +#### maxDepth? + +`number` + #### rows readonly [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] +#### subRows? + +readonly [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] + ## Returns `unknown` diff --git a/docs/reference/static-functions/functions/cell_getIsAggregated.md b/docs/reference/static-functions/functions/cell_getIsAggregated.md index 809a2fabee..e7cb3e1ab2 100644 --- a/docs/reference/static-functions/functions/cell_getIsAggregated.md +++ b/docs/reference/static-functions/functions/cell_getIsAggregated.md @@ -9,7 +9,7 @@ title: cell_getIsAggregated function cell_getIsAggregated(cell): boolean; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:364](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L364) +Defined in: [features/aggregation/aggregationFeature.utils.ts:393](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L393) Implements `cell.getIsAggregated()` for synthetic grouped rows. diff --git a/docs/reference/static-functions/functions/column_getAggregationFns.md b/docs/reference/static-functions/functions/column_getAggregationFns.md index eba6cf7164..f8d136f0a7 100644 --- a/docs/reference/static-functions/functions/column_getAggregationFns.md +++ b/docs/reference/static-functions/functions/column_getAggregationFns.md @@ -9,7 +9,7 @@ title: column_getAggregationFns function column_getAggregationFns(column): readonly ResolvedAggregationFn[]; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:142](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L142) +Defined in: [features/aggregation/aggregationFeature.utils.ts:155](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L155) Resolves and validates a column's scalar or multiple aggregation option. diff --git a/docs/reference/static-functions/functions/column_getAggregationValue.md b/docs/reference/static-functions/functions/column_getAggregationValue.md index a2b7572d97..3beed6b69b 100644 --- a/docs/reference/static-functions/functions/column_getAggregationValue.md +++ b/docs/reference/static-functions/functions/column_getAggregationValue.md @@ -6,12 +6,12 @@ title: column_getAggregationValue # Function: column\_getAggregationValue() ```ts -function column_getAggregationValue(column, rows?): ColumnAggregationValue; +function column_getAggregationValue(column, options?): ColumnAggregationValue; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:310](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L310) +Defined in: [features/aggregation/aggregationFeature.utils.ts:330](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L330) -Implements `column.getAggregationValue(rows?)` and its default-value cache. +Implements `column.getAggregationValue(options?)` and its default cache. ## Type Parameters @@ -33,9 +33,9 @@ Implements `column.getAggregationValue(rows?)` and its default-value cache. [`Column_Internal`](../../index/interfaces/Column_Internal.md)\<`TFeatures`, `TData`, `TValue`\> -### rows? +### options? -readonly [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] +[`AggregationValueOptions`](../../index/interfaces/AggregationValueOptions.md)\<`TFeatures`, `TData`\> ## Returns diff --git a/docs/reference/static-functions/functions/column_getAutoAggregationFn.md b/docs/reference/static-functions/functions/column_getAutoAggregationFn.md index 3da3045d12..9ddd8bccc0 100644 --- a/docs/reference/static-functions/functions/column_getAutoAggregationFn.md +++ b/docs/reference/static-functions/functions/column_getAutoAggregationFn.md @@ -11,7 +11,7 @@ function column_getAutoAggregationFn(column): | undefined; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:100](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L100) +Defined in: [features/aggregation/aggregationFeature.utils.ts:113](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L113) Resolves the `sum` or `extent` definition inferred from the first core row. diff --git a/docs/reference/static-functions/functions/formatAggregatedCellValue.md b/docs/reference/static-functions/functions/formatAggregatedCellValue.md index a7dd338d93..5a815296f4 100644 --- a/docs/reference/static-functions/functions/formatAggregatedCellValue.md +++ b/docs/reference/static-functions/functions/formatAggregatedCellValue.md @@ -9,7 +9,7 @@ title: formatAggregatedCellValue function formatAggregatedCellValue(value, option): string | null; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:385](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L385) +Defined in: [features/aggregation/aggregationFeature.utils.ts:414](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L414) Formats the default scalar or keyed aggregated-cell representation. diff --git a/docs/reference/static-functions/functions/normalizeAggregationRows.md b/docs/reference/static-functions/functions/normalizeAggregationRows.md index 90a3933284..9d0b4520fd 100644 --- a/docs/reference/static-functions/functions/normalizeAggregationRows.md +++ b/docs/reference/static-functions/functions/normalizeAggregationRows.md @@ -6,13 +6,13 @@ title: normalizeAggregationRows # Function: normalizeAggregationRows() ```ts -function normalizeAggregationRows(rows): Row[]; +function normalizeAggregationRows(rows, maxDepth): Row[]; ``` -Defined in: [features/aggregation/aggregationFeature.utils.ts:57](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L57) +Defined in: [features/aggregation/aggregationFeature.utils.ts:66](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts#L66) -Flattens hierarchical row inputs to unique terminal leaves in encounter -order. This is the normalization used by public aggregation-value calls. +Selects unique rows at a maximum relative depth in encounter order. +Branches that end before the requested depth contribute their deepest row. ## Type Parameters @@ -30,6 +30,10 @@ order. This is the normalization used by public aggregation-value calls. readonly [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] +### maxDepth + +`number` = `0` + ## Returns [`Row`](../../index/type-aliases/Row.md)\<`TFeatures`, `TData`\>[] diff --git a/docs/reference/static-functions/functions/row_getAllCells.md b/docs/reference/static-functions/functions/row_getAllCells.md index 880be52dcb..5ace4e5f69 100644 --- a/docs/reference/static-functions/functions/row_getAllCells.md +++ b/docs/reference/static-functions/functions/row_getAllCells.md @@ -9,7 +9,7 @@ title: row_getAllCells function row_getAllCells(row): Cell[]; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:225](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L225) +Defined in: [core/rows/coreRowsFeature.utils.ts:243](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L243) Constructs one cell for each leaf column in this row. diff --git a/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md b/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md index f9fd6b4237..fb963d2efc 100644 --- a/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md +++ b/docs/reference/static-functions/functions/row_getAllCellsByColumnId.md @@ -9,7 +9,7 @@ title: row_getAllCellsByColumnId function row_getAllCellsByColumnId(row): Record>; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:261](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L261) +Defined in: [core/rows/coreRowsFeature.utils.ts:279](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L279) Builds a lookup map of this row's cells keyed by column id. diff --git a/docs/reference/static-functions/functions/row_getParentRow.md b/docs/reference/static-functions/functions/row_getParentRow.md index b5c9301fd9..c72a0c5ddf 100644 --- a/docs/reference/static-functions/functions/row_getParentRow.md +++ b/docs/reference/static-functions/functions/row_getParentRow.md @@ -11,7 +11,7 @@ function row_getParentRow(row): | undefined; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:181](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L181) +Defined in: [core/rows/coreRowsFeature.utils.ts:199](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L199) Looks up this row's direct parent, if it has one. diff --git a/docs/reference/static-functions/functions/row_getParentRows.md b/docs/reference/static-functions/functions/row_getParentRows.md index 365e585f53..02a23f54ba 100644 --- a/docs/reference/static-functions/functions/row_getParentRows.md +++ b/docs/reference/static-functions/functions/row_getParentRows.md @@ -9,7 +9,7 @@ title: row_getParentRows function row_getParentRows(row): Row[]; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:198](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L198) +Defined in: [core/rows/coreRowsFeature.utils.ts:216](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L216) Collects this row's ancestor chain from root to direct parent. diff --git a/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md b/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md new file mode 100644 index 0000000000..33294beb28 --- /dev/null +++ b/docs/reference/static-functions/functions/table_getMaxSubRowDepth.md @@ -0,0 +1,35 @@ +--- +id: table_getMaxSubRowDepth +title: table_getMaxSubRowDepth +--- + +# Function: table\_getMaxSubRowDepth() + +```ts +function table_getMaxSubRowDepth(table): number; +``` + +Defined in: [core/rows/coreRowsFeature.utils.ts:174](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L174) + +Returns the deepest structural row depth in the core row model. +Root rows are depth `0`, their direct sub-rows are depth `1`, and so on. + +## Type Parameters + +### TFeatures + +`TFeatures` *extends* [`TableFeatures`](../../index/interfaces/TableFeatures.md) + +### TData + +`TData` *extends* [`RowData`](../../index/type-aliases/RowData.md) + +## Parameters + +### table + +[`Table_Internal`](../../index/interfaces/Table_Internal.md)\<`TFeatures`, `TData`\> + +## Returns + +`number` diff --git a/docs/reference/static-functions/functions/table_getRow.md b/docs/reference/static-functions/functions/table_getRow.md index 9bc9b608b6..35ef0c743f 100644 --- a/docs/reference/static-functions/functions/table_getRow.md +++ b/docs/reference/static-functions/functions/table_getRow.md @@ -12,7 +12,7 @@ function table_getRow( searchAll?): Row; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:311](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L311) +Defined in: [core/rows/coreRowsFeature.utils.ts:329](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L329) Looks up a row by id from the current or full row model. diff --git a/docs/reference/static-functions/functions/table_getRowId.md b/docs/reference/static-functions/functions/table_getRowId.md index 3f67eda1dd..aba1bf2648 100644 --- a/docs/reference/static-functions/functions/table_getRowId.md +++ b/docs/reference/static-functions/functions/table_getRowId.md @@ -13,7 +13,7 @@ function table_getRowId( parent?): string; ``` -Defined in: [core/rows/coreRowsFeature.utils.ts:285](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L285) +Defined in: [core/rows/coreRowsFeature.utils.ts:303](https://github.com/TanStack/table/blob/main/packages/table-core/src/core/rows/coreRowsFeature.utils.ts#L303) Resolves the stable id for a row. diff --git a/docs/reference/static-functions/index.md b/docs/reference/static-functions/index.md index 6dc6bb20fc..834e880057 100644 --- a/docs/reference/static-functions/index.md +++ b/docs/reference/static-functions/index.md @@ -181,6 +181,7 @@ title: static-functions - [table\_getIsSomeRowsPinned](functions/table_getIsSomeRowsPinned.md) - [table\_getIsSomeRowsSelected](functions/table_getIsSomeRowsSelected.md) - [table\_getLeafHeaders](functions/table_getLeafHeaders.md) +- [table\_getMaxSubRowDepth](functions/table_getMaxSubRowDepth.md) - [table\_getOrderColumnsFn](functions/table_getOrderColumnsFn.md) - [table\_getPageCount](functions/table_getPageCount.md) - [table\_getPageOptions](functions/table_getPageOptions.md) diff --git a/examples/alpine/aggregation/src/main.ts b/examples/alpine/aggregation/src/main.ts index 1a334cd948..e8491233d7 100644 --- a/examples/alpine/aggregation/src/main.ts +++ b/examples/alpine/aggregation/src/main.ts @@ -74,13 +74,17 @@ const columns = columnHelper.columns([ aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), columnHelper.accessor('score', { header: 'Score', aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), ]) diff --git a/examples/angular/aggregation/src/app/app.ts b/examples/angular/aggregation/src/app/app.ts index 4bf2e85d4a..1637dda3bd 100644 --- a/examples/angular/aggregation/src/app/app.ts +++ b/examples/angular/aggregation/src/app/app.ts @@ -70,14 +70,18 @@ const columns: Array> = [ aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }, { accessorKey: 'score', header: 'Score', aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }, ] diff --git a/examples/ember/aggregation/app/templates/application.gts b/examples/ember/aggregation/app/templates/application.gts index e8d4ad805e..de485240e5 100644 --- a/examples/ember/aggregation/app/templates/application.gts +++ b/examples/ember/aggregation/app/templates/application.gts @@ -85,7 +85,7 @@ const columns = columnHelper.columns([ cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => formatAggregationValue( - column.getAggregationValue(getAggregationRows(table)), + column.getAggregationValue({ rows: getAggregationRows(table) }), ), }), columnHelper.accessor('score', { @@ -93,7 +93,7 @@ const columns = columnHelper.columns([ aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => formatAggregationValue( - column.getAggregationValue(getAggregationRows(table)), + column.getAggregationValue({ rows: getAggregationRows(table) }), ), }), ]) diff --git a/examples/lit/aggregation/src/main.ts b/examples/lit/aggregation/src/main.ts index 2704b569bd..3dee2691da 100644 --- a/examples/lit/aggregation/src/main.ts +++ b/examples/lit/aggregation/src/main.ts @@ -82,7 +82,7 @@ const columns = columnHelper.columns([ cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => formatAggregationValue( - column.getAggregationValue(getAggregationRows(table)), + column.getAggregationValue({ rows: getAggregationRows(table) }), ), }), columnHelper.accessor('score', { @@ -90,7 +90,7 @@ const columns = columnHelper.columns([ aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => formatAggregationValue( - column.getAggregationValue(getAggregationRows(table)), + column.getAggregationValue({ rows: getAggregationRows(table) }), ), }), ]) diff --git a/examples/preact/aggregation/src/main.tsx b/examples/preact/aggregation/src/main.tsx index 673d14fdd5..6cc952f6bb 100644 --- a/examples/preact/aggregation/src/main.tsx +++ b/examples/preact/aggregation/src/main.tsx @@ -101,7 +101,9 @@ function App() { aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), columnHelper.accessor('score', { header: 'Score', @@ -111,7 +113,9 @@ function App() { { id: 'range', aggregationFn: 'extent' }, ], footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), ]), [], diff --git a/examples/react/aggregation/src/main.tsx b/examples/react/aggregation/src/main.tsx index 20966700d9..ef7409a624 100644 --- a/examples/react/aggregation/src/main.tsx +++ b/examples/react/aggregation/src/main.tsx @@ -108,8 +108,12 @@ function App() { aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => - // formatValue(column.getAggregationValue()), // default - accounts for filtering - formatValue(column.getAggregationValue(getAggregationRows(table))), // or pass in whatever array of rows you want to aggregate + formatValue( + column.getAggregationValue({ + // Omit `rows` to use the filtered, pre-grouped rows by default. + rows: getAggregationRows(table), + }), + ), }), columnHelper.accessor('score', { header: 'Score', @@ -119,8 +123,12 @@ function App() { { id: 'range', aggregationFn: 'extent' }, ], footer: ({ column, table }) => - // formatValue(column.getAggregationValue()), // default - accounts for filtering - formatValue(column.getAggregationValue(getAggregationRows(table))), // or pass in whatever array of rows you want to aggregate + formatValue( + column.getAggregationValue({ + // Any row model or custom subset can define the total's roots. + rows: getAggregationRows(table), + }), + ), }), ]), [], diff --git a/examples/solid/aggregation/src/App.tsx b/examples/solid/aggregation/src/App.tsx index 8902d01187..88a23979e6 100644 --- a/examples/solid/aggregation/src/App.tsx +++ b/examples/solid/aggregation/src/App.tsx @@ -95,7 +95,9 @@ function App() { cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => formatValue( - column.getAggregationValue(getAggregationRows(table, rowSource())), + column.getAggregationValue({ + rows: getAggregationRows(table, rowSource()), + }), ), }), columnHelper.accessor('score', { @@ -107,7 +109,9 @@ function App() { ], footer: ({ column, table }) => formatValue( - column.getAggregationValue(getAggregationRows(table, rowSource())), + column.getAggregationValue({ + rows: getAggregationRows(table, rowSource()), + }), ), }), ]) @@ -232,9 +236,9 @@ function App() { ) : header.column.id === 'amount' || header.column.id === 'score' ? ( formatValue( - header.column.getAggregationValue( - getAggregationRows(table, rowSource()), - ), + header.column.getAggregationValue({ + rows: getAggregationRows(table, rowSource()), + }), ) ) : ( diff --git a/examples/svelte/aggregation/src/App.svelte b/examples/svelte/aggregation/src/App.svelte index 8d55707e4e..9dd9a358a5 100644 --- a/examples/svelte/aggregation/src/App.svelte +++ b/examples/svelte/aggregation/src/App.svelte @@ -34,8 +34,8 @@ columnHelper.display({ id: 'select' }), columnHelper.accessor('category', { header: 'Category', filterFn: 'includesString' }), columnHelper.accessor('item', { header: 'Item', footer: ({ table }) => `${table.options.meta?.rowSource} total` }), - columnHelper.accessor('amount', { header: 'Amount', aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => formatValue(column.getAggregationValue(getAggregationRows(table))) }), - columnHelper.accessor('score', { header: 'Score', aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => formatValue(column.getAggregationValue(getAggregationRows(table))) }), + columnHelper.accessor('amount', { header: 'Amount', aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => formatValue(column.getAggregationValue({ rows: getAggregationRows(table) })) }), + columnHelper.accessor('score', { header: 'Score', aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => formatValue(column.getAggregationValue({ rows: getAggregationRows(table) })) }), ]) const table = createTable({ features, columns, diff --git a/examples/vanilla/aggregation/src/main.ts b/examples/vanilla/aggregation/src/main.ts index efbc02546e..e7e5e7cd09 100644 --- a/examples/vanilla/aggregation/src/main.ts +++ b/examples/vanilla/aggregation/src/main.ts @@ -77,13 +77,17 @@ const columns = columnHelper.columns([ aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), columnHelper.accessor('score', { header: 'Score', aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), ]) const el = (tag: K, text?: string) => { diff --git a/examples/vue/aggregation/src/App.vue b/examples/vue/aggregation/src/App.vue index a7aab75107..e37f58e482 100644 --- a/examples/vue/aggregation/src/App.vue +++ b/examples/vue/aggregation/src/App.vue @@ -76,13 +76,17 @@ const columns = columnHelper.columns([ aggregationFn: 'sum', cell: ({ getValue }) => getValue().toLocaleString(), footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), columnHelper.accessor('score', { header: 'Score', aggregationFn: ['count', 'mean', { id: 'range', aggregationFn: 'extent' }], footer: ({ column, table }) => - formatValue(column.getAggregationValue(getAggregationRows(table))), + formatValue( + column.getAggregationValue({ rows: getAggregationRows(table) }), + ), }), ]) const table = useTable({ diff --git a/packages/table-core/skills/aggregation/SKILL.md b/packages/table-core/skills/aggregation/SKILL.md index 788491e13b..b3ca89be96 100644 --- a/packages/table-core/skills/aggregation/SKILL.md +++ b/packages/table-core/skills/aggregation/SKILL.md @@ -48,15 +48,22 @@ export const features = tableFeatures({ ```ts const grandTotal = salaryColumn.getAggregationValue() -const filteredTotal = salaryColumn.getAggregationValue( - table.getFilteredRowModel().rows, -) +const filteredTotal = salaryColumn.getAggregationValue({ + rows: table.getFilteredRowModel().rows, +}) +const childTotal = salaryColumn.getAggregationValue({ + rows: table.getCoreRowModel().rows, + maxDepth: 1, +}) ``` The default uses the pre-grouped row model. Explicit rows can come from any row -model or caller-selected subset. Hierarchical inputs are normalized to unique -terminal rows. Default calls are cached; explicit-row calls intentionally are -not because array identity and contents are caller-owned. +model or caller-selected subset. `maxAggregationDepth` defaults to `0`, which +selects the supplied roots; `1` selects direct sub-rows, and `Infinity` selects +terminal rows. Branches that end early contribute their deepest available row. +Default calls are cached; explicit-row calls intentionally are not because array +identity and contents are caller-owned. `table.getMaxSubRowDepth()` returns the +deepest structural depth in the core row model. ### Multiple aggregations @@ -86,10 +93,12 @@ const weightedMean = constructAggregationFn({ }) ``` -The context provides `rows`, `getValue`, `column`, `columnId`, `table`, and an -optional `groupingRow`. Add `merge({ childResults, childRows, ...context })` -when nested groups can efficiently combine child results; otherwise the engine -re-runs `aggregate` over normalized terminal rows. +The context provides depth-selected `rows`, `maxDepth`, `getValue`, `column`, +`columnId`, `table`, and optional grouped-only `groupingRow` and `subRows`. +Every aggregation configured on a column receives the same row frontier. Add +`merge({ subRowResults, subRows, ...context })` when nested groups can more +efficiently combine already-computed sub-row results; otherwise the engine calls +`aggregate` with both row sets. `subRowResults[i]` corresponds to `subRows[i]`. ### Manual or remote values @@ -109,19 +118,20 @@ Correct: register `aggregationFeature` and call ### [HIGH] Passing a scope label and rows -There is no scope option. Call `getAggregationValue()` for the default or pass -the exact rows from the desired row model. +There is no scope option. Call `getAggregationValue()` for the cached default, +or pass a single options object containing rows from the desired row model and +`maxDepth` when the desired frontier is below those rows. ### [HIGH] Reusing the legacy callable signature Wrong: `(columnId, leafRows, childRows) => result`. -Correct: `constructAggregationFn({ aggregate: ({ rows, getValue }) => result })`. +Correct: `constructAggregationFn({ aggregate: ({ rows, subRows, getValue }) => result })`. ### [MEDIUM] Assuming arbitrary totals run in the worker The experimental worker computes grouped row-model aggregates. Public -`getAggregationValue(rows?)` totals execute on the main thread, and custom +`getAggregationValue(options?)` totals execute on the main thread, and custom grouped results sent by the worker must be structured-cloneable. ## API Discovery diff --git a/packages/table-core/skills/migrate-v8-to-v9/SKILL.md b/packages/table-core/skills/migrate-v8-to-v9/SKILL.md index 1a3ebdd052..0fa99f83b4 100644 --- a/packages/table-core/skills/migrate-v8-to-v9/SKILL.md +++ b/packages/table-core/skills/migrate-v8-to-v9/SKILL.md @@ -123,14 +123,22 @@ Move registries from table options or factory arguments into these feature slots Register only the built-ins the table references by string name, importing each individually (`filterFn_includesString`, `sortFn_alphanumeric`, `aggregationFn_sum`, and so on) alongside any custom functions. The full registry objects (`filterFns`, `sortFns`, `aggregationFns` exports) still work but bundle every built-in. A slot's keys become the valid string names in column definitions, and `'auto'` resolves only registered functions. Aggregation is independent from grouping. Add `aggregationFeature` for -`aggregationFn`, `aggregatedCell`, `column.getAggregationValue(rows?)`, and +`aggregationFn`, `aggregatedCell`, `column.getAggregationValue(options?)`, and `cell.getIsAggregated`. A root total does not require grouping. Convert legacy custom callables `(columnId, leafRows, childRows) => result` to `constructAggregationFn({ aggregate: (context) => result, merge? })` definitions. Replace `column.getAggregationFn()` with `column.getAggregationFns()`; arrays in `aggregationFn` return keyed objects. Replace the old `AggregationFn` and `CreatedAggregationFn` types with -`AggregationFnDef`. +`AggregationFnDef`. Aggregation row selection is shared across every definition +on a column: `maxAggregationDepth` defaults to `0`, while `1` selects direct +sub-rows and `Infinity` selects terminal rows. Explicit totals can override it +with the single object signature +`column.getAggregationValue({ rows, maxDepth })`; positional row and depth +arguments are not supported. All built-ins consume the same selected `rows`. +Custom definitions can inspect grouped `subRows`, and `merge` receives matching +`subRowResults`. Use `table.getMaxSubRowDepth()` when a depth should derive from +the deepest structural row in the core model. ### 3. Migrate state reads and whole-state observation diff --git a/packages/table-core/src/core/rows/coreRowsFeature.ts b/packages/table-core/src/core/rows/coreRowsFeature.ts index 01701f876a..5c96a05522 100644 --- a/packages/table-core/src/core/rows/coreRowsFeature.ts +++ b/packages/table-core/src/core/rows/coreRowsFeature.ts @@ -9,6 +9,7 @@ import { row_getUniqueValues, row_getValue, row_renderValue, + table_getMaxSubRowDepth, table_getRow, table_getRowId, table_getRowsInDisplayOrder, @@ -73,6 +74,10 @@ export const coreRowsFeature: TableFeature = { fn: (id: string, searchAll?: boolean) => table_getRow(table, id, searchAll), }, + table_getMaxSubRowDepth: { + fn: () => table_getMaxSubRowDepth(table), + memoDeps: () => [table.getCoreRowModel()], + }, }) }, } diff --git a/packages/table-core/src/core/rows/coreRowsFeature.types.ts b/packages/table-core/src/core/rows/coreRowsFeature.types.ts index a060861b50..fd9956c683 100644 --- a/packages/table-core/src/core/rows/coreRowsFeature.types.ts +++ b/packages/table-core/src/core/rows/coreRowsFeature.types.ts @@ -131,6 +131,11 @@ export interface Table_Rows< in out TFeatures extends TableFeatures, in out TData extends RowData, > { + /** + * Returns the deepest structural row depth in the core row model. + * Root rows are depth `0`, direct sub-rows are depth `1`, and so on. + */ + getMaxSubRowDepth: () => number /** * Returns the rows in the current display order and assigns their display * indexes. When expanded rows bypass pagination, expanded descendants are @@ -138,6 +143,9 @@ export interface Table_Rows< * `row.getDisplayIndex()`. */ getRowsInDisplayOrder: () => Array> + /** + * Returns the row id for a given row. + */ getRowId: (_: TData, index: number, parent?: Row) => string /** * Returns the row with the given ID. diff --git a/packages/table-core/src/core/rows/coreRowsFeature.utils.ts b/packages/table-core/src/core/rows/coreRowsFeature.utils.ts index 06b8f0ad6c..cf41cf7d67 100644 --- a/packages/table-core/src/core/rows/coreRowsFeature.utils.ts +++ b/packages/table-core/src/core/rows/coreRowsFeature.utils.ts @@ -167,6 +167,24 @@ export function row_getLeafRows< return flattenBy(row.subRows, (d) => d.subRows) } +/** + * Returns the deepest structural row depth in the core row model. + * Root rows are depth `0`, their direct sub-rows are depth `1`, and so on. + */ +export function table_getMaxSubRowDepth< + TFeatures extends TableFeatures, + TData extends RowData, +>(table: Table_Internal): number { + const rows = table.getCoreRowModel().flatRows + let maxDepth = 0 + + for (let i = 0; i < rows.length; i++) { + maxDepth = Math.max(maxDepth, rows[i]!.depth) + } + + return maxDepth +} + /** * Looks up this row's direct parent, if it has one. * diff --git a/packages/table-core/src/features/aggregation/aggregationFeature.ts b/packages/table-core/src/features/aggregation/aggregationFeature.ts index c14f1330cf..6ead164c66 100644 --- a/packages/table-core/src/features/aggregation/aggregationFeature.ts +++ b/packages/table-core/src/features/aggregation/aggregationFeature.ts @@ -16,6 +16,7 @@ export const aggregationFeature: TableFeature = { aggregatedCell: ({ column, getValue }: any) => formatAggregatedCellValue(getValue(), column.columnDef.aggregationFn), aggregationFn: 'auto', + maxAggregationDepth: 0, }), getDefaultTableOptions: () => ({ @@ -36,7 +37,7 @@ export const aggregationFeature: TableFeature = { fn: (column) => column_getAggregationFns(column), }, column_getAggregationValue: { - fn: (column, rows) => column_getAggregationValue(column, rows), + fn: (column, options) => column_getAggregationValue(column, options), }, column_getAutoAggregationFn: { fn: (column) => column_getAutoAggregationFn(column), diff --git a/packages/table-core/src/features/aggregation/aggregationFeature.types.ts b/packages/table-core/src/features/aggregation/aggregationFeature.types.ts index 4bc56ace0e..f739257a4d 100644 --- a/packages/table-core/src/features/aggregation/aggregationFeature.types.ts +++ b/packages/table-core/src/features/aggregation/aggregationFeature.types.ts @@ -20,6 +20,14 @@ export interface AggregationContext< column: Column /** Convenience alias for `column.id`. */ columnId: string + /** Maximum relative sub-row depth used to select `rows`. */ + maxDepth: number + /** + * Immediate sub-rows for grouped aggregation. This property is omitted + * for root or caller-supplied-row aggregation. At a terminal grouping level + * these are the direct data rows; at a nested level they are sub-row groups. + */ + subRows?: ReadonlyArray> /** Reads this column's value from one of `rows`. */ getValue: (row: Row) => TValue /** @@ -29,8 +37,8 @@ export interface AggregationContext< */ groupingRow?: Row /** - * Terminal leaf rows included in this aggregation. The executor normalizes - * hierarchical and duplicate row inputs before invoking the definition. + * Unique rows selected at `maxDepth`. Branches that end before `maxDepth` + * contribute their deepest available row. */ rows: ReadonlyArray> /** The table that owns the column and rows. */ @@ -44,10 +52,10 @@ export interface AggregationMergeContext< TValue, TResult, > extends AggregationContext { - /** Results produced for each immediate child group, in child-row order. */ - childResults: ReadonlyArray - /** Immediate child group rows corresponding to `childResults`. */ - childRows: ReadonlyArray> + /** Results produced for each immediate sub-row group, in sub-row order. */ + subRowResults: ReadonlyArray + /** Immediate sub-row groups corresponding to `subRowResults`. */ + subRows: ReadonlyArray> } /** A context-based aggregation definition and optional grouped-result merge. */ @@ -57,11 +65,11 @@ export interface AggregationFnDef< TValue = unknown, TResult = unknown, > { - /** Computes a result directly from normalized terminal rows. */ + /** Computes a result directly from the selected `rows`. */ aggregate: (context: AggregationContext) => TResult /** - * Combines already-computed immediate child-group results. When omitted, - * nested grouping falls back to `aggregate` over the group's terminal rows. + * Combines already-computed immediate sub-row results. When omitted, + * nested grouping falls back to `aggregate` over the group's selected rows. */ merge?: ( context: AggregationMergeContext, @@ -236,6 +244,12 @@ export interface ColumnDef_Aggregation< * result object. Inline definitions in an array require an explicit `id`. */ aggregationFn?: AggregationFnOption + /** + * Maximum relative sub-row depth used for grouped aggregation and cached + * default totals. `0` selects the supplied root rows, `1` their direct + * sub-rows, and so on. Defaults to `0`. + */ + maxAggregationDepth?: number /** * Optionally supplies a precomputed aggregation value for this column. * Return `{ value }` to handle the request, including `{ value: undefined }`; @@ -257,11 +271,11 @@ export interface Column_Aggregation< > /** * Aggregates this column over the default pre-grouped row model, or over a - * caller-provided array of rows. Explicit rows are normalized to unique - * terminal leaves and are intentionally not cached. + * caller-provided array of rows. `options.maxDepth` overrides the column's + * `maxAggregationDepth`. Explicit-row calls are intentionally not cached. */ getAggregationValue: >( - rows?: ReadonlyArray>, + options?: AggregationValueOptions, ) => TResult /** Infers `sum` for a numeric first row and `extent` for a Date first row. */ getAutoAggregationFn: () => @@ -269,6 +283,17 @@ export interface Column_Aggregation< | undefined } +/** Options for a caller-requested column aggregation value. */ +export interface AggregationValueOptions< + in out TFeatures extends TableFeatures, + in out TData extends RowData, +> { + /** Overrides the column's `maxAggregationDepth` for this request. */ + maxDepth?: number + /** Rows to aggregate instead of the default pre-grouped row model. */ + rows?: ReadonlyArray> +} + /** Cell instance APIs installed by `aggregationFeature`. */ export interface Cell_Aggregation { /** Whether this cell displays an aggregate on a synthetic grouped row. */ @@ -289,6 +314,8 @@ export interface AggregationValueContext< > { /** The column whose value was requested. */ column: Column + /** Maximum relative sub-row depth used for the request. */ + maxDepth: number /** Caller-provided rows, or `undefined` for the default row model. */ rows?: ReadonlyArray> /** The table that owns the column. */ diff --git a/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts b/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts index 8c85a053ac..78c142f82c 100644 --- a/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts +++ b/packages/table-core/src/features/aggregation/aggregationFeature.utils.ts @@ -5,9 +5,11 @@ import type { Row } from '../../types/Row' import type { TableFeatures } from '../../types/TableFeatures' import type { CellData, RowData } from '../../types/type-utils' import type { + AggregationContext, AggregationFnDef, AggregationFnDescriptor, AggregationFnRef, + AggregationValueOptions, ColumnAggregationValue, ResolvedAggregationFn, } from './aggregationFeature.types' @@ -15,6 +17,7 @@ import type { interface AggregationCacheEntry { aggregationFnOption: unknown dependency: unknown + maxDepth: number registry: unknown value: unknown } @@ -50,21 +53,31 @@ function warn(message: string) { } } +function resolveMaxAggregationDepth(maxDepth: number | undefined) { + return maxDepth === undefined || Number.isNaN(maxDepth) + ? 0 + : Math.max(0, Math.floor(maxDepth)) +} + /** - * Flattens hierarchical row inputs to unique terminal leaves in encounter - * order. This is the normalization used by public aggregation-value calls. + * Selects unique rows at a maximum relative depth in encounter order. + * Branches that end before the requested depth contribute their deepest row. */ export function normalizeAggregationRows< TFeatures extends TableFeatures, TData extends RowData, ->(rows: ReadonlyArray>): Array> { +>( + rows: ReadonlyArray>, + maxDepth = 0, +): Array> { const result: Array> = [] const seen = new Set() + const normalizedMaxDepth = resolveMaxAggregationDepth(maxDepth) - const visit = (row: Row) => { - if (row.subRows.length) { + const visit = (row: Row, depth: number) => { + if (row.subRows.length && depth < normalizedMaxDepth) { for (let i = 0; i < row.subRows.length; i++) { - visit(row.subRows[i]!) + visit(row.subRows[i]!, depth + 1) } return } @@ -76,7 +89,7 @@ export function normalizeAggregationRows< } for (let i = 0; i < rows.length; i++) { - visit(rows[i]!) + visit(rows[i]!, 0) } return result @@ -232,35 +245,40 @@ export function column_getAggregationFns< return finish(resolved) } -function getChildResult( - childValue: unknown, +function getSubRowResult( + subRowValue: unknown, isMultiple: boolean, id: string | undefined, ) { - if (!isMultiple) return childValue - if (!id || !childValue || typeof childValue !== 'object') return undefined - return hasOwn(childValue, id) - ? (childValue as Record)[id] + if (!isMultiple) return subRowValue + if (!id || !subRowValue || typeof subRowValue !== 'object') return undefined + return hasOwn(subRowValue, id) + ? (subRowValue as Record)[id] : undefined } -/** Executes every configured aggregation for a column over normalized rows. */ +/** Executes every configured aggregation over a depth-selected row frontier. */ export function aggregateColumnValue< TFeatures extends TableFeatures, TData extends RowData, >(args: { - childRows?: ReadonlyArray> + maxDepth?: number + subRows?: ReadonlyArray> column: Column groupingRow?: Row rows: ReadonlyArray> }): unknown { - const { childRows, column, groupingRow, rows } = args + const { subRows, column, groupingRow, rows } = args const internalColumn = column as Column_Internal + const maxDepth = resolveMaxAggregationDepth( + args.maxDepth ?? internalColumn.columnDef.maxAggregationDepth, + ) + const aggregationRows = normalizeAggregationRows(rows, maxDepth) const entries = column_getAggregationFns(internalColumn) const isMultiple = Array.isArray(internalColumn.columnDef.aggregationFn) const canMerge = - !!childRows?.length && - childRows.every( + !!subRows?.length && + subRows.every( (row) => !!(row as any).groupingColumnId && (row as any).groupingColumnId !== column.id, @@ -270,22 +288,24 @@ export function aggregateColumnValue< const definition = entry.aggregationFn if (!definition) return undefined - const context = { + const context: AggregationContext = { + ...(subRows ? { subRows } : {}), column, columnId: column.id, getValue: (row: Row) => row.getValue(column.id), ...(groupingRow ? { groupingRow } : {}), - rows, + maxDepth, + rows: aggregationRows, table: column.table as any, } if (canMerge && definition.merge) { return definition.merge({ ...context, - childResults: childRows.map((row) => - getChildResult(row.getValue(column.id), isMultiple, entry.id), + subRowResults: subRows.map((row) => + getSubRowResult(row.getValue(column.id), isMultiple, entry.id), ), - childRows: childRows, + subRows, }) } @@ -306,17 +326,22 @@ export function aggregateColumnValue< return result } -/** Implements `column.getAggregationValue(rows?)` and its default-value cache. */ +/** Implements `column.getAggregationValue(options?)` and its default cache. */ export function column_getAggregationValue< TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData = CellData, >( column: Column_Internal, - rows?: ReadonlyArray>, + options?: AggregationValueOptions, ): ColumnAggregationValue { + const rows = options?.rows + const resolvedMaxDepth = resolveMaxAggregationDepth( + options?.maxDepth ?? column.columnDef.maxAggregationDepth, + ) const providedResult = column.columnDef.getAggregationValue?.({ column: column as any, + maxDepth: resolvedMaxDepth, rows, table: column.table as any, }) @@ -327,7 +352,8 @@ export function column_getAggregationValue< if (rows !== undefined) { return aggregateColumnValue({ column: column as any, - rows: normalizeAggregationRows(rows), + maxDepth: resolvedMaxDepth, + rows, }) as any } @@ -341,6 +367,7 @@ export function column_getAggregationValue< if ( previous && previous.dependency === model && + previous.maxDepth === resolvedMaxDepth && previous.registry === registry && previous.aggregationFnOption === aggregationFnOption ) { @@ -349,11 +376,13 @@ export function column_getAggregationValue< const value = aggregateColumnValue({ column: column as any, - rows: normalizeAggregationRows(model.rows), + maxDepth: resolvedMaxDepth, + rows: model.rows, }) ;(column as any)._aggregationValueCache = { aggregationFnOption, dependency: model, + maxDepth: resolvedMaxDepth, registry, value, } satisfies AggregationCacheEntry diff --git a/packages/table-core/src/features/aggregation/aggregationFns.ts b/packages/table-core/src/features/aggregation/aggregationFns.ts index 84f34f97eb..207db8903a 100755 --- a/packages/table-core/src/features/aggregation/aggregationFns.ts +++ b/packages/table-core/src/features/aggregation/aggregationFns.ts @@ -39,8 +39,8 @@ function collectRangeValues(context: AggregationContext) { } /** - * Sums numeric row values. Non-number values contribute zero. As in the - * previous API, `NaN` is a number and therefore propagates through the sum. + * Sums numeric selected-row values. Non-number values contribute zero. As in + * the previous API, `NaN` is a number and therefore propagates through the sum. */ export const aggregationFn_sum = constructAggregationFn< any, @@ -56,10 +56,10 @@ export const aggregationFn_sum = constructAggregationFn< } return sum }, - merge: ({ childResults }) => { + merge: ({ subRowResults }) => { let sum = 0 - for (let i = 0; i < childResults.length; i++) { - const value = childResults[i] + for (let i = 0; i < subRowResults.length; i++) { + const value = subRowResults[i] if (isNumber(value)) sum += value } return sum @@ -67,8 +67,8 @@ export const aggregationFn_sum = constructAggregationFn< }) /** - * Finds the minimum numeric or Date value. Invalid value types are ignored; - * `NaN` preserves the legacy numeric seeding behavior. + * Finds the minimum numeric or Date value from the selected rows. Invalid value + * types are ignored; `NaN` preserves the legacy numeric seeding behavior. */ export const aggregationFn_min = constructAggregationFn< any, @@ -84,16 +84,17 @@ export const aggregationFn_min = constructAggregationFn< } return result }, - merge: ({ childResults }) => { + merge: ({ subRowResults }) => { let result: RangeValue | undefined let kind: 'date' | 'number' | undefined - for (let i = 0; i < childResults.length; i++) { - const value = childResults[i] + for (let i = 0; i < subRowResults.length; i++) { + const value = subRowResults[i] const valueKind = getRangeKind(value) if (!valueKind) continue + if (value === undefined) continue kind ??= valueKind if (kind !== valueKind) continue - if (result === undefined || compareRangeValues(value!, result) < 0) { + if (result === undefined || compareRangeValues(value, result) < 0) { result = value } } @@ -102,8 +103,8 @@ export const aggregationFn_min = constructAggregationFn< }) /** - * Finds the maximum numeric or Date value. Invalid value types are ignored; - * `NaN` preserves the legacy numeric seeding behavior. + * Finds the maximum numeric or Date value from the selected rows. Invalid value + * types are ignored; `NaN` preserves the legacy numeric seeding behavior. */ export const aggregationFn_max = constructAggregationFn< any, @@ -119,16 +120,17 @@ export const aggregationFn_max = constructAggregationFn< } return result }, - merge: ({ childResults }) => { + merge: ({ subRowResults }) => { let result: RangeValue | undefined let kind: 'date' | 'number' | undefined - for (let i = 0; i < childResults.length; i++) { - const value = childResults[i] + for (let i = 0; i < subRowResults.length; i++) { + const value = subRowResults[i] const valueKind = getRangeKind(value) if (!valueKind) continue + if (value === undefined) continue kind ??= valueKind if (kind !== valueKind) continue - if (result === undefined || compareRangeValues(value!, result) > 0) { + if (result === undefined || compareRangeValues(value, result) > 0) { result = value } } @@ -137,7 +139,8 @@ export const aggregationFn_max = constructAggregationFn< }) /** - * Finds the minimum and maximum numeric or Date values. Empty inputs return + * Finds the minimum and maximum numeric or Date values from the selected rows. + * Empty inputs return * `[undefined, undefined]`, preserving the previous built-in result shape. */ export const aggregationFn_extent = constructAggregationFn< @@ -158,26 +161,32 @@ export const aggregationFn_extent = constructAggregationFn< } return [min, max] }, - merge: ({ childResults }) => { + merge: ({ subRowResults }) => { let result: [RangeValue | undefined, RangeValue | undefined] = [ undefined, undefined, ] let kind: 'date' | 'number' | undefined - for (let i = 0; i < childResults.length; i++) { - const extent = childResults[i]! - const valueKind = getRangeKind(extent[0]) - if (!valueKind) continue + for (let i = 0; i < subRowResults.length; i++) { + const extent = subRowResults[i]! + const min = extent[0] + const max = extent[1] + const valueKind = getRangeKind(min) + if (!valueKind || min === undefined || max === undefined) continue kind ??= valueKind if (kind !== valueKind) continue if (result[0] === undefined) { - result = [extent[0], extent[1]] + result = [min, max] } else { - if (compareRangeValues(extent[0]!, result[0]) < 0) { - result[0] = extent[0] + if (compareRangeValues(min, result[0]) < 0) { + result[0] = min } - if (compareRangeValues(extent[1]!, result[1]!) > 0) { - result[1] = extent[1] + const currentMax = result[1] + if ( + currentMax === undefined || + compareRangeValues(max, currentMax) > 0 + ) { + result[1] = max } } } @@ -277,10 +286,10 @@ export const aggregationFn_count = constructAggregationFn< number >({ aggregate: ({ rows }) => rows.length, - merge: ({ childResults }) => { + merge: ({ subRowResults }) => { let count = 0 - for (let i = 0; i < childResults.length; i++) { - const value = childResults[i] + for (let i = 0; i < subRowResults.length; i++) { + const value = subRowResults[i] if (isNumber(value)) count += value } return count @@ -296,7 +305,7 @@ export const aggregationFn_first = constructAggregationFn< >({ aggregate: (context) => context.rows[0] ? context.getValue(context.rows[0]) : undefined, - merge: ({ childResults }) => childResults[0], + merge: ({ subRowResults }) => subRowResults[0], }) /** Returns the last row's value, including a nullish value. */ @@ -310,7 +319,7 @@ export const aggregationFn_last = constructAggregationFn< const row = context.rows[context.rows.length - 1] return row ? context.getValue(row) : undefined }, - merge: ({ childResults }) => childResults[childResults.length - 1], + merge: ({ subRowResults }) => subRowResults[subRowResults.length - 1], }) /** diff --git a/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts b/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts index ebf7241ba8..033e36dab5 100644 --- a/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts +++ b/packages/table-core/src/features/column-grouping/createGroupedRowModel.ts @@ -118,7 +118,7 @@ function _createGroupedRowModel< subRow.parentId = id }) - const leafRows = normalizeAggregationRows(groupedRows) + const leafRows = normalizeAggregationRows(groupedRows, Infinity) const row = constructRow( table, @@ -167,10 +167,10 @@ function _createGroupedRowModel< const cache = ((row as any)._aggregationValuesCache ??= makeObjectMap()) cache[colId] = aggregateColumnValue({ - childRows: subRows, + subRows, column, groupingRow: row, - rows: leafRows, + rows: groupedRows, }) return cache[colId] }, diff --git a/packages/table-core/tests/implementation/features/aggregation/aggregationFeature.test.ts b/packages/table-core/tests/implementation/features/aggregation/aggregationFeature.test.ts index 74fe2bde73..f226301cb4 100644 --- a/packages/table-core/tests/implementation/features/aggregation/aggregationFeature.test.ts +++ b/packages/table-core/tests/implementation/features/aggregation/aggregationFeature.test.ts @@ -45,7 +45,7 @@ describe('aggregationFeature', () => { const table = constructTable({ features, data, columns }) expect(table.getColumn('scalar')!.getAggregationValue()).toBe(30) - expect(table.getColumn('scalar')!.getAggregationValue([])).toBe(0) + expect(table.getColumn('scalar')!.getAggregationValue({ rows: [] })).toBe(0) expect(table.getColumn('multiple')!.getAggregationValue()).toEqual({ count: 3, mean: 15, @@ -107,8 +107,8 @@ describe('aggregationFeature', () => { expect(aggregate).toHaveBeenCalledTimes(1) const rows = table.getCoreRowModel().rows - expect(column.getAggregationValue(rows)).toBe(2) - expect(column.getAggregationValue(rows)).toBe(2) + expect(column.getAggregationValue({ rows })).toBe(2) + expect(column.getAggregationValue({ rows })).toBe(2) expect(aggregate).toHaveBeenCalledTimes(3) table.setOptions((old) => ({ ...old, data: [...old.data, { value: 3 }] })) @@ -116,6 +116,36 @@ describe('aggregationFeature', () => { expect(aggregate).toHaveBeenCalledTimes(4) }) + it('includes aggregation depth in the default-row cache key', () => { + type Node = { value: number; subRows?: Array } + const aggregate = vi.fn(({ rows }) => rows.length) + const sized = constructAggregationFn({ + aggregate, + }) + const features = testFeatures({ + aggregationFeature, + aggregationFns: { sized }, + }) + const table = constructTable({ + features, + data: [{ value: 10, subRows: [{ value: 1 }, { value: 2 }] }], + columns: [{ accessorKey: 'value', aggregationFn: 'sized' }], + getSubRows: (row: Node) => row.subRows, + }) + const column = table.getColumn('value')! + + expect(column.getAggregationValue()).toBe(1) + expect(column.getAggregationValue()).toBe(1) + expect(aggregate).toHaveBeenCalledTimes(1) + + expect(column.getAggregationValue({ maxDepth: 1 })).toBe(2) + expect(column.getAggregationValue({ maxDepth: 1 })).toBe(2) + expect(aggregate).toHaveBeenCalledTimes(2) + + expect(column.getAggregationValue()).toBe(1) + expect(aggregate).toHaveBeenCalledTimes(3) + }) + it('accepts rows from any row model or custom selection', () => { const features = testFeatures({ aggregationFeature, @@ -152,17 +182,25 @@ describe('aggregationFeature', () => { const column = table.getColumn('amount')! expect(column.getAggregationValue()).toBe(11) - expect(column.getAggregationValue(table.getCoreRowModel().rows)).toBe(15) - expect(column.getAggregationValue(table.getRowModel().rows)).toBe(3) expect( - column.getAggregationValue(table.getFilteredSelectedRowModel().rows), - ).toBe(2) - expect(column.getAggregationValue([table.getCoreRowModel().rows[2]!])).toBe( - 4, + column.getAggregationValue({ rows: table.getCoreRowModel().rows }), + ).toBe(15) + expect(column.getAggregationValue({ rows: table.getRowModel().rows })).toBe( + 3, ) + expect( + column.getAggregationValue({ + rows: table.getFilteredSelectedRowModel().rows, + }), + ).toBe(2) + expect( + column.getAggregationValue({ + rows: [table.getCoreRowModel().rows[2]!], + }), + ).toBe(4) }) - it('normalizes hierarchical and duplicate explicit rows to terminal leaves', () => { + it('selects a unique depth frontier and keeps shorter ragged branches', () => { type Node = { amount: number; subRows?: Array } const features = testFeatures({ aggregationFeature, aggregationFns }) const data: Array = [ @@ -170,6 +208,7 @@ describe('aggregationFeature', () => { amount: 100, subRows: [{ amount: 2 }, { amount: 3 }], }, + { amount: 200 }, ] const table = constructTable({ features, @@ -177,14 +216,20 @@ describe('aggregationFeature', () => { columns: [{ accessorKey: 'amount', aggregationFn: 'sum' }], getSubRows: (row) => row.subRows, }) - const parent = table.getCoreRowModel().rows[0]! + const rows = table.getCoreRowModel().rows + const parent = rows[0]! + const column = table.getColumn('amount')! - expect(table.getColumn('amount')!.getAggregationValue()).toBe(5) + expect(column.getAggregationValue()).toBe(300) + expect(column.getAggregationValue({ maxDepth: 1 })).toBe(205) + expect(column.getAggregationValue({ maxDepth: Infinity })).toBe(205) expect( - table - .getColumn('amount')! - .getAggregationValue([parent, parent.subRows[0]!]), + column.getAggregationValue({ + maxDepth: 1, + rows: [parent, parent.subRows[0]!], + }), ).toBe(5) + expect(table.getMaxSubRowDepth()).toBe(1) }) it('uses handled column values and configurable local fallback', () => { @@ -205,7 +250,9 @@ describe('aggregationFeature', () => { }) const column = table.getColumn('amount')! - expect(column.getAggregationValue(table.getCoreRowModel().rows)).toBe(99) + expect( + column.getAggregationValue({ rows: table.getCoreRowModel().rows }), + ).toBe(99) expect(column.getAggregationValue()).toBe(3) table.setOptions((old) => ({ ...old, manualAggregation: true })) @@ -293,17 +340,145 @@ describe('aggregation and grouping integration', () => { expect(column.getAggregationValue()).toBe(2) const rootContext = aggregate.mock.calls[0]![0] + expect(rootContext).not.toHaveProperty('subRows') expect(rootContext).not.toHaveProperty('groupingRow') expect(rootContext).not.toHaveProperty('source') const groupingRow = table.getGroupedRowModel().rows[0]! expect(groupingRow.getValue('amount')).toBe(2) const groupedContext = aggregate.mock.calls[1]![0] + expect(groupedContext.subRows).toBe(groupingRow.subRows) expect(groupedContext.groupingRow).toBe(groupingRow) expect(groupedContext.groupingRow!.depth).toBe(0) expect(groupedContext).not.toHaveProperty('source') }) + it('lets aggregate choose immediate sub-rows instead of terminal rows', () => { + const aggregate = vi.fn(({ subRows, rows }) => + subRows ? subRows.length : rows.length, + ) + const childCount = constructAggregationFn({ + aggregate, + }) + const features = testFeatures({ + aggregationFeature, + aggregationFns: { childCount }, + columnGroupingFeature, + groupedRowModel: createGroupedRowModel(), + }) + const table = constructTable({ + features, + data: [ + { region: 'a', team: 'x', amount: 1 }, + { region: 'a', team: 'x', amount: 2 }, + { region: 'a', team: 'y', amount: 3 }, + ], + columns: [ + { accessorKey: 'region' }, + { accessorKey: 'team' }, + { accessorKey: 'amount', aggregationFn: 'childCount' }, + ], + initialState: { grouping: ['region', 'team'] }, + }) + + const region = table.getGroupedRowModel().rows[0]! + const team = region.subRows[0]! + + expect(team.getValue('amount')).toBe(2) + expect(region.getValue('amount')).toBe(2) + + const terminalContext = aggregate.mock.calls[0]![0] + expect(terminalContext.subRows).toBe(team.subRows) + expect(terminalContext.rows).toHaveLength(2) + + const nestedContext = aggregate.mock.calls[1]![0] + expect(nestedContext.subRows).toBe(region.subRows) + expect(nestedContext.subRows).toHaveLength(2) + expect(nestedContext.rows).toHaveLength(3) + }) + + it('preserves direct sub-row semantics for reaggregatable built-ins', () => { + type Node = { + amount: number + region?: string + subRows?: Array + team?: string + } + const features = testFeatures({ + aggregationFeature, + aggregationFns, + columnGroupingFeature, + groupedRowModel: createGroupedRowModel(), + }) + const data: Array = [ + { + amount: 100, + region: 'a', + team: 'x', + subRows: [{ amount: 1 }, { amount: 2 }], + }, + { + amount: 200, + region: 'a', + team: 'y', + subRows: [{ amount: 3 }, { amount: 4 }], + }, + ] + const table = constructTable({ + features, + data, + columns: [ + { accessorKey: 'region' }, + { accessorKey: 'team' }, + { accessorFn: (row) => row.amount, id: 'sum', aggregationFn: 'sum' }, + { accessorFn: (row) => row.amount, id: 'min', aggregationFn: 'min' }, + { accessorFn: (row) => row.amount, id: 'max', aggregationFn: 'max' }, + { + accessorFn: (row) => row.amount, + id: 'extent', + aggregationFn: 'extent', + }, + { + accessorFn: (row) => row.amount, + id: 'stats', + aggregationFn: ['sum', 'mean', 'count'], + }, + { + accessorFn: (row) => row.amount, + id: 'subRowStats', + aggregationFn: ['sum', 'mean', 'count'], + maxAggregationDepth: 1, + }, + ], + getSubRows: (row) => row.subRows, + initialState: { grouping: ['region', 'team'] }, + }) + + const region = table.getGroupedRowModel().rows[0]! + const teams = region.subRows + + expect(teams.map((row) => row.getValue('sum'))).toEqual([100, 200]) + expect(region.getValue('sum')).toBe(300) + expect(region.getValue('min')).toBe(100) + expect(region.getValue('max')).toBe(200) + expect(region.getValue('extent')).toEqual([100, 200]) + expect(region.getValue('stats')).toEqual({ + count: 2, + mean: 150, + sum: 300, + }) + expect(region.getValue('subRowStats')).toEqual({ + count: 4, + mean: 2.5, + sum: 10, + }) + + expect(table.getColumn('sum')!.getAggregationValue()).toBe(300) + expect(table.getColumn('sum')!.getAggregationValue({ maxDepth: 1 })).toBe( + 10, + ) + }) + it('keeps grouping structural when aggregationFeature is absent', () => { const features = testFeatures({ columnGroupingFeature, @@ -390,11 +565,15 @@ describe('aggregation and grouping integration', () => { ).toBe(false) }) - it('caches grouped values and merges child results without rescanning parent leaves', () => { + it('caches grouped values and merges sub-row results without rescanning parent leaves', () => { const aggregate = vi.fn(({ rows }) => rows.length) const merge = vi.fn( - ({ childResults }: { childResults: ReadonlyArray }) => - childResults.reduce((total, value) => total + value, 0), + ({ + subRowResults, + }: { + subRowResults: ReadonlyArray + subRows: ReadonlyArray + }) => subRowResults.reduce((total, value) => total + value, 0), ) const sized = constructAggregationFn({ aggregate, @@ -426,6 +605,8 @@ describe('aggregation and grouping integration', () => { expect(region.getValue('amount')).toBe(3) expect(aggregate).toHaveBeenCalledTimes(2) expect(merge).toHaveBeenCalledTimes(1) + expect(merge.mock.calls[0]![0].subRows).toBe(region.subRows) + expect(merge.mock.calls[0]![0].subRowResults).toEqual([2, 1]) }) it('rebuilds grouped aggregation values when column definitions change', () => { @@ -460,7 +641,7 @@ describe('aggregation and grouping integration', () => { expect(countedGroup.getValue('amount')).toBe(2) }) - it('treats supplied hierarchical rows as terminal-leaf subtrees', () => { + it('applies depth selection to supplied grouped and expanded rows', () => { const features = testFeatures({ aggregationFeature, aggregationFns, @@ -483,8 +664,18 @@ describe('aggregation and grouping integration', () => { }) const column = table.getColumn('amount')! - expect(column.getAggregationValue(table.getRowModel().rows)).toBe(3) + expect(column.getAggregationValue({ rows: table.getRowModel().rows })).toBe( + 3, + ) table.setExpanded(true) - expect(column.getAggregationValue(table.getRowModel().rows)).toBe(3) + expect(column.getAggregationValue({ rows: table.getRowModel().rows })).toBe( + 6, + ) + expect( + column.getAggregationValue({ + maxDepth: Infinity, + rows: table.getRowModel().rows, + }), + ).toBe(3) }) }) diff --git a/packages/table-core/tests/unit/core/rows/coreRowsFeature.utils.test.ts b/packages/table-core/tests/unit/core/rows/coreRowsFeature.utils.test.ts index 6317d3bf8e..05d2971736 100644 --- a/packages/table-core/tests/unit/core/rows/coreRowsFeature.utils.test.ts +++ b/packages/table-core/tests/unit/core/rows/coreRowsFeature.utils.test.ts @@ -11,6 +11,7 @@ import { row_renderValue, table_getRow, table_getRowId, + table_getMaxSubRowDepth, } from '../../../../src/core/rows/coreRowsFeature.utils' import { testFeatures } from '../../../fixtures/features' import { generateTestColumnDefs } from '../../../fixtures/data/generateTestColumnDefs' @@ -172,6 +173,21 @@ describe('row_renderValue', () => { }) describe('row tree readers', () => { + it('memoizes the deepest structural sub-row depth on the table', () => { + const table = makeNestedTable([2, 2, 2]) + const coreRowModel = table.getCoreRowModel() + + expect(table_getMaxSubRowDepth(table as any)).toBe(2) + expect(table.getMaxSubRowDepth()).toBe(2) + expect(table.getMaxSubRowDepth()).toBe(2) + expect(table.getCoreRowModel()).toBe(coreRowModel) + }) + + it('returns zero for flat and empty row models', () => { + expect(makeTable(2).getMaxSubRowDepth()).toBe(0) + expect(makeTable(0).getMaxSubRowDepth()).toBe(0) + }) + it('row_getLeafRows should flatten all descendants', () => { const table = makeNestedTable([2, 2, 2]) const row = table.getRow('0') diff --git a/packages/table-core/tests/unit/core/table/rowModelSlots.test.ts b/packages/table-core/tests/unit/core/table/rowModelSlots.test.ts index bae3588323..e2b03d997b 100644 --- a/packages/table-core/tests/unit/core/table/rowModelSlots.test.ts +++ b/packages/table-core/tests/unit/core/table/rowModelSlots.test.ts @@ -369,14 +369,16 @@ describe('row model and fn registry feature slots', () => { }) const column = table.getColumn('age')! column.getAggregationFns() - column.getAggregationValue(table.getCoreRowModel().rows) + column.getAggregationValue({ rows: table.getCoreRowModel().rows }) if (false) { // @ts-expect-error - grouping APIs are absent without columnGroupingFeature column.getCanGroup() // @ts-expect-error - row-selection row models require rowSelectionFeature table.getFilteredSelectedRowModel() - // @ts-expect-error - aggregation values accept rows directly, not options - column.getAggregationValue({ rows: table.getCoreRowModel().rows }) + // @ts-expect-error - aggregation options use known properties + column.getAggregationValue({ scope: 'core' }) + // @ts-expect-error - rows are provided through the options object + column.getAggregationValue(table.getCoreRowModel().rows) } const selectedFeatures = tableFeatures({ @@ -389,9 +391,9 @@ describe('row model and fn registry feature slots', () => { data, columns: [{ accessorKey: 'age', aggregationFn: 'sum' }], }) - selectedTable - .getColumn('age')! - .getAggregationValue(selectedTable.getFilteredSelectedRowModel().rows) + selectedTable.getColumn('age')!.getAggregationValue({ + rows: selectedTable.getFilteredSelectedRowModel().rows, + }) const groupingFeatures = tableFeatures({ columnGroupingFeature, diff --git a/packages/table-core/tests/unit/fns/aggregationFns.test.ts b/packages/table-core/tests/unit/fns/aggregationFns.test.ts index 8a11c7bfad..fc7d58b7cb 100644 --- a/packages/table-core/tests/unit/fns/aggregationFns.test.ts +++ b/packages/table-core/tests/unit/fns/aggregationFns.test.ts @@ -36,8 +36,8 @@ describe('aggregation function definitions', () => { expect( aggregationFn_sum.merge!({ ...context([]), - childResults: [4, undefined, 6], - childRows: [], + subRowResults: [4, undefined, 6], + subRows: [], }), ).toBe(10) })