Uh oh!
There was an error while loading. Please reload this page.
fix(table-core): correct number-range, filter-depth, autoRemove, and custom faceting semantics - #6503
Conversation
…custom faceting semantics Four filtering-semantics bugs from the beta triage. filterFn_inNumberRange matched non-numeric values: JavaScript's loose relational coercion let null, '', and booleans slip into a numeric range (null >= 0 && null <= 20 is true), so the auto-selected number filter leaked empty rows into a [0, max] range on nullable numeric columns. The filter now only matches real numbers. Numeric strings also stop matching; `between`/`betweenInclusive` remain the hybrid string/number range filters. When maxLeafRowFilterDepth stopped the root-down filter recursion, the kept rows' unfiltered descendants stayed visible through row.subRows but never entered flatRows or rowsById, so facet counts and other flat-representation consumers under-counted after filtering. Truncated subtrees now join both. Scoped to the root-down path; the leaf-up path drops truncated subRows entirely (pre-existing behavior) and is left as a possible follow-up. shouldAutoRemoveFilter ORed a hardcoded empty-string check over a custom autoRemove, so a filter function that wanted to keep '' as a filter value could not. A provided autoRemove is now authoritative for defined values; undefined always clears, since it is the universal setFilterValue(undefined) sentinel. Built-ins are unaffected: they all test falsy values themselves. Custom facetedUniqueValues/facetedMinMaxValues/facetedRowModel factories were frozen by a redundant memoization layer in columnFacetingFeature. The stock factories already memoize internally with the same dependencies, so the API-layer memoDeps only served to cache custom implementations against inputs they do not depend on. The API layer is now a plain pass-through like every other row model: stock results stay referentially stable and compute once per invalidation (pinned by Map-identity tests), the no-factory fallback keeps a stable empty Map, and custom factories own their memoization (tableMemo is exported for this). The faceting guides now document the contract and their server-side examples read live data through table.options.meta instead of stale closures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughThe change updates table-core filtering and faceting behavior. It adds tests for numeric ranges, custom ChangesCluster 5 behavior updates
Estimated code review effort: 4 (Complex) | ~45 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
View your CI Pipeline Execution ↗ for commit eed3da9
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@beta-window-triage.md`:
- Around line 114-117: Split the step-4 entry so PR `#6443` remains associated
only with the `#5801` expansion-reset work, and move the Cluster 5 filtering
issues (`#6007`, `#5987`, `#6101`, and `#6081`) into a separate step. If a consolidated
Cluster 5 PR is known, reference it there; otherwise state that its vehicle is
pending.
In `@docs/framework/alpine/guide/column-faceting.md`:
- Around line 286-287: Update the faceting example’s factory functions so they
no longer close over the one-time serverFacets value. Expose current server
facet data through a meta getter, then read table.options.meta?.serverFacets
inside both returned faceting functions so subsequent server responses update
both APIs.
In `@docs/framework/ember/guide/column-faceting.md`:
- Around line 307-308: Update the custom faceting examples so each returned
resolver reads current facet data inside its function rather than capturing a
one-time fetch result in the factory closure. Apply this to
docs/framework/ember/guide/column-faceting.md lines 307-308,
docs/framework/lit/guide/column-faceting.md lines 290-291, and
docs/framework/octane/guide/column-faceting.md lines 268-269: populate
uniqueValueMap and return ranges from table.options.meta, a reactive store, or
another live source, preserving immediate updates to server facets.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7dce26c9-9091-4edf-971f-220b888df3e1
📒 Files selected for processing (31)
beta-window-triage.mddocs/framework/alpine/guide/column-faceting.mddocs/framework/alpine/guide/column-filtering.mddocs/framework/angular/guide/column-faceting.mddocs/framework/angular/guide/column-filtering.mddocs/framework/ember/guide/column-faceting.mddocs/framework/ember/guide/column-filtering.mddocs/framework/lit/guide/column-faceting.mddocs/framework/lit/guide/column-filtering.mddocs/framework/octane/guide/column-faceting.mddocs/framework/octane/guide/column-filtering.mddocs/framework/preact/guide/column-faceting.mddocs/framework/preact/guide/column-filtering.mddocs/framework/react/guide/column-faceting.mddocs/framework/react/guide/column-filtering.mddocs/framework/solid/guide/column-faceting.mddocs/framework/solid/guide/column-filtering.mddocs/framework/svelte/guide/column-faceting.mddocs/framework/svelte/guide/column-filtering.mddocs/framework/vue/guide/column-faceting.mddocs/framework/vue/guide/column-filtering.mdpackages/table-core/src/features/column-faceting/columnFacetingFeature.tspackages/table-core/src/features/column-faceting/columnFacetingFeature.utils.tspackages/table-core/src/features/column-filtering/columnFilteringFeature.types.tspackages/table-core/src/features/column-filtering/columnFilteringFeature.utils.tspackages/table-core/src/features/column-filtering/filterFns.tspackages/table-core/src/features/column-filtering/filterRowsUtils.tspackages/table-core/tests/implementation/features/column-faceting/createFacetedRowModels.test.tspackages/table-core/tests/implementation/features/column-filtering/createFilteredRowModel.test.tspackages/table-core/tests/unit/features/column-filtering/columnFilteringFeature.utils.test.tspackages/table-core/tests/unit/fns/filterFns.test.ts
| 4. **[#6443](https://github.com/TanStack/table/pull/6443)** rebase + merge ([#5801](https://github.com/TanStack/table/issues/5801)). (Cluster 5 — [#6007](https://github.com/TanStack/table/issues/6007), [#5987](https://github.com/TanStack/table/issues/5987), [#6101](https://github.com/TanStack/table/issues/6101), [#6081](https://github.com/TanStack/table/issues/6081) — implemented 2026-08-02, pending PR; close [#6313](https://github.com/TanStack/table/pull/6313)/[#6361](https://github.com/TanStack/table/pull/6361) as superseded when it lands.) | ||
| 5. `_valuesCache`/`defaultColumn` invalidation pair ([#5363](https://github.com/TanStack/table/issues/5363)/[#4485](https://github.com/TanStack/table/issues/4485) + [#5275](https://github.com/TanStack/table/issues/5275)). | ||
| 6. Sorting defaults ([#4946](https://github.com/TanStack/table/issues/4946) one-liner; [#5147](https://github.com/TanStack/table/issues/5147)/[#5832](https://github.com/TanStack/table/issues/5832) auto-dir sampling). | ||
| 7. Remaining semantics decisions: [#5909](https://github.com/TanStack/table/issues/5909) (undefined = uncontrolled), [#5778](https://github.com/TanStack/table/issues/5778), [#6101](https://github.com/TanStack/table/issues/6101), [#6081](https://github.com/TanStack/table/issues/6081). (Cluster 3 — [#6115](https://github.com/TanStack/table/issues/6115), [#5833](https://github.com/TanStack/table/issues/5833), [#4939](https://github.com/TanStack/table/issues/4939), [#6136](https://github.com/TanStack/table/issues/6136) — implemented 2026-08-02, pending PR.) | ||
| 7. Remaining semantics decisions: [#5909](https://github.com/TanStack/table/issues/5909) (undefined = uncontrolled), [#5778](https://github.com/TanStack/table/issues/5778). (Cluster 3 — [#6115](https://github.com/TanStack/table/issues/6115), [#5833](https://github.com/TanStack/table/issues/5833), [#4939](https://github.com/TanStack/table/issues/4939), [#6136](https://github.com/TanStack/table/issues/6136) — implemented 2026-08-02, pending PR.) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bashset -euo pipefail
echo"== file info =="
wc -l beta-window-triage.md
sed -n '1,140p' beta-window-triage.md | nl -ba
echoecho"== occurrences of `#6443`, `#5801`, Cluster 5, step 4 =="
rg -n "(`#6443`|`#5801`|Cluster 5|step 4|filtering|defaultColumn|_valuesCache|sorting|Cluster 3)" beta-window-triage.mdRepository: TanStack/table
Length of output: 234
🏁 Script executed:
#!/bin/bashset -euo pipefail
echo"== file info =="
wc -l beta-window-triage.md
echoecho"== file excerpt =="
python3 - <<'PY'from pathlib import Pathp = Path("beta-window-triage.md")for i, line in enumerate(p.read_text(encoding="utf-8").splitlines(), 1): if 1 <= i <= 140: print(f"{i:4d}: {line}")PYechoecho"== occurrences of key references =="
rg -n "(`#6443`|`#5801`|Cluster 5|step 4|filtering|defaultColumn|_valuesCache|sorting|Cluster 3)" beta-window-triage.md ||trueechoecho"== parse references by line =="
python3 - <<'PY'from pathlib import Pathimport retext = Path("beta-window-triage.md").read_text(encoding="utf-8")for match in re.finditer(r"#(\d{3,4})", text): line = text.count("\n", 0, match.start()) + 1 line_text = text.splitlines()[line-1] print(f"line {line}: #{match.group(1)}: {line_text[:120]}")PYRepository: TanStack/table
Length of output: 50370
Split or relabel the step-4 line.
Step 4 currently merges PR #6443 (#5801 expansion reset) and also describes Cluster 5 filtering fixes (#6007, #5987, #6101, #6081). The filtering fixes do not have a consolidated PR listed, so maintainers may treat the wrong PR as the vehicle for Cluster 5. Split this into separate steps, or replace the parenthetical with the actual Cluster 5 PR when available.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@beta-window-triage.md` around lines 114 - 117, Split the step-4 entry so PR
`#6443` remains associated only with the `#5801` expansion-reset work, and move the
Cluster 5 filtering issues (`#6007`, `#5987`, `#6101`, and `#6081`) into a separate
step. If a consolidated Cluster 5 PR is known, reference it there; otherwise
state that its vehicle is pending.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…ng examples The alpine, ember, lit, and octane guides captured a one-time `await fetch` result in the factory closure, so later server responses could never reach either faceting API. They now read through `table.options.meta` inside the returned functions like the other framework guides, using each framework's own reactive idiom. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four filtering-semantics fixes from the beta-window triage (cluster 5), with new unit/implementation tests and guide updates across all 10 framework docs. No changeset (handled at release assembly).
Changes
filterFn_inNumberRangeonly matches real numbers. JS loose relational coercion letnull,'', and booleans slip into a numeric range (null >= 0 && null <= 20istrue), so the auto-selected number filter leaked empty rows into[0, max]ranges on nullable numeric columns. Numeric strings also stop matching;between/betweenInclusiveremain the hybrid string/number range filters.maxLeafRowFilterDepthkeepsflatRows/rowsByIdcomplete. When the root-down recursion stops at the max depth, the kept rows' unfiltered descendants stay visible throughrow.subRowsbut never entered the flat arrays, under-counting facets after filtering. Truncated subtrees now join both. Scoped to the root-down path like the original PR; the leaf-up path drops truncated subRows entirely (pre-existing behavior) and is left as a possible follow-up.autoRemoveis authoritative.shouldAutoRemoveFilterno longer ORs the hardcoded empty-string check over a customautoRemove, so custom filter functions can keep''as a filter value.undefinedalways clears (the universalsetFilterValue(undefined)sentinel). Built-ins are unaffected: they all test falsy values themselves.memoDepsincolumnFacetingFeatureduplicated the stock factories' internaltableMemo(same dependencies), so for customfacetedUniqueValues/facetedMinMaxValues/facetedRowModelimplementations it only cached them against inputs they do not depend on. The API layer is now a plain pass-through like every other row model: stock results stay referentially stable and compute once per invalidation (pinned by Map-identity tests), the no-factory fallback keeps a stable empty Map, and custom factories own their memoization (tableMemois exported). The faceting guides document the contract, and the server-side examples now read live data throughtable.options.metainstead of stale closures.Closes
nullvalues)getFacetedRowModelinconsistently respectsmaxLeafRowFilterDepth: 0)filterFn.autoRemoveignored for empty strings #6101 (filterFn.autoRemoveignored for empty strings)getFacetedUniqueValuesdoes not update on rerenders #6081 (customgetFacetedUniqueValuesdoes not update on rerenders)Supersedes
constructFilterFnstructure, plus the PR's test matrix ported.maxLeafRowFilterDepth): fix and helper ported to the currentfilterRowsUtils.ts, with tests rewritten against the existing nested fixture.Verification
tsc+ eslint clean.pnpm test:lib(18 projects) green.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
undefinedalways clears the filter.Documentation
Tests