Skip to content

fix(table-core): correct expanded/paginated state contents and sorting toggle defaults - #6501

Merged
KevinVandy merged 1 commit into
betafrom
fix/expanding-sorting-state-contents
Aug 3, 2026
Merged

fix(table-core): correct expanded/paginated state contents and sorting toggle defaults#6501
KevinVandy merged 1 commit into
betafrom
fix/expanding-sorting-state-contents

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Aug 3, 2026

Copy link
Copy Markdown
Member

Clears clusters 3 and 4 from the beta triage: expanded/paginated state contents, and sorting toggle defaults. Both are default-behavior changes, which is why they belong in the beta window rather than a later 9.x.

Expanded and paginated state contents

#6115 — expand-all materializes non-expandable ids. Toggling a row while expanded === true materialized every id in rowsById, including leaf rows that can never expand. That polluted serialized ExpandedState and skewed getExpandedDepth. Materialization now writes only ids where row.getCanExpand() is true. getCanExpand was chosen over subRows.length so that getRowCanExpand lazy-load overrides stay expandable.

Companion change: table.getIsAllRowsExpanded() now only considers expandable rows, so the materialized map still round-trips as "all expanded". A side effect worth calling out in review: a state of stale ids with no expandable rows in the current model now returns false rather than true.

#5833 — paginated flatRows duplicates expanded sub-rows. The rebuild pushed each page row and then recursed into its subRows, but page rows already contain expanded descendants inline, so those rows landed in flatRows twice. Now deduped by row id. Semantic decision: collapsed descendants stay included, consistent with every other row model, where flatRows ignores expansion state. Only the duplication is removed.

#6136 — spurious onExpandedChange. row.toggleExpanded(bool) and table.toggleAllRowsExpanded(bool) fired the change handler even when the requested state already matched. Both now early-return.

#4939 — imperative toggles ignore getCanExpand. Neither toggle consulted row.getCanExpand(), unlike their row-selection equivalents. The expand direction is now guarded. Collapsing is always allowed so stale expanded ids can still be cleaned up.

This last one has fallout for consumers who drove expansion on flat rows without setting getRowCanExpand: those calls become no-ops. The angular and ember flex-render tests did exactly that and are updated with getRowCanExpand: () => true.

Sorting toggle defaults

#4946enableMultiRemove was dead on every path. column.toggleSorting() called column.getNextSortingOrder(column) without the multi argument, so the option could never take effect. Now forwarded as multi && column.getCanMultiSort(), which matches the multi-mode condition the updater itself computes, so a multi toggle on a column that cannot multi-sort correctly falls back to single-sort removal semantics. The public getNextSortingOrder type now accepts the multi argument it always supported at runtime.

#5147 / #5832 — auto sort direction flips the toggle cycle. column.getAutoSortDir() sampled only flatRows[0], so a leading null or a manual-sorting data swap changed the inferred first direction mid-cycle, and the cycle went asc → removed without ever reaching desc. It now samples the first 10 filtered rows for the first non-nullish value, matching getAutoSortFn's existing N=10 convention. #5832 is the same root cause and closes as a duplicate.

#5653 (docs half only). sortUndefined: false was documented as "undefined values will be considered tied" in all ten framework sorting guides and the reference. That is wrong: undefined values are passed straight to the sorting function with no special handling, and the built-in text fns coerce them to ''. Corrected, and the missing 'first'/'last' bullets were added to the generated reference page.

The semantic half of #5653 — whether the default sortUndefined: 1 should short-circuit before a user's custom sortFn — is deliberately not addressed here. Current behavior is defensible and now accurately documented; users who want their fn to see undefined can set sortUndefined: false.

MRT example crashes

Surfaced while exercising the sorting changes against the MUI and Mantine example ports, not caused by them.

  • Both sort labels read sorting off state, which does not carry it, and crashed on sorting.length. They now read it through table.Subscribe on table.atoms.sorting, which also makes the multi-sort badge reactive.
  • The row-action edit handler passed a shallow row copy (setEditingRow({ ...row })) instead of the row, breaking the row identity the edit modal depends on.
  • mrtRefsFeature seeded the keyed editInputRefs / filterInputRefs bags with null instead of {}, crashing on the first keyed write when filters or edit inputs mounted.
  • One duplicate React key in the MUI example's row-action menu.

New e2e coverage pins all of these plus the sort-direction indicator, per the existing per-example self-contained spec convention.

Verification

  • table-core: 1255 tests pass, tsc and declaration-emit clean.
  • angular-table (41) and ember-table (34) pass with the updated expansion tests.
  • eslint and prettier clean on all changed files. The 24 pre-existing eslint errors elsewhere in packages/table-core/tests are untouched by this PR.
  • New regression tests were each verified to fail against the pre-fix code.

Closes #6115, closes #5833, closes #6136, closes #4939, closes #4946, closes #5147, closes #5832.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved row expansion to ignore non-expandable rows, avoid redundant updates, and prevent duplicate child rows in paginated results.
    • Corrected automatic sorting direction when leading values are empty or null.
    • Improved multi-column sorting and removal behavior.
  • Documentation

    • Clarified handling of undefined values and sorting options across framework guides and reference documentation.
  • Tests

    • Added coverage for expansion, pagination, sorting indicators, filtering, and row-edit workflows.

@nx-cloud

nx-cloud Bot commented Aug 3, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 9b40f22

Command Status Duration Result
nx affected --targets=test:eslint,test:sherif,t... ✅ Succeeded 4m 22s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 31s View ↗

☁️ Nx Cloud last updated this comment at 2026-08-03 03:18:38 UTC

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0a097c2-9cb4-4cb4-80c5-ac9fc876f6c0

📥 Commits

Reviewing files that changed from the base of the PR and between 9b40f22 and c35d70d.

📒 Files selected for processing (32)
  • beta-window-triage.md
  • docs/framework/alpine/guide/sorting.md
  • docs/framework/angular/guide/sorting.md
  • docs/framework/ember/guide/sorting.md
  • docs/framework/lit/guide/sorting.md
  • docs/framework/octane/guide/sorting.md
  • docs/framework/preact/guide/sorting.md
  • docs/framework/react/guide/sorting.md
  • docs/framework/solid/guide/sorting.md
  • docs/framework/svelte/guide/sorting.md
  • docs/framework/vue/guide/sorting.md
  • docs/reference/index/interfaces/ColumnDef_RowSorting.md
  • docs/reference/index/interfaces/Column_RowSorting.md
  • docs/reference/static-functions/functions/column_getAutoSortDir.md
  • docs/reference/static-functions/functions/column_toggleSorting.md
  • examples/react/mantine-react-table/src/mantine-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx
  • examples/react/mantine-react-table/src/mantine-react-table/components/head/MRT_TableHeadCellSortLabel.tsx
  • examples/react/mantine-react-table/tests/e2e/smoke.spec.ts
  • examples/react/material-react-table/src/main.tsx
  • examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx
  • examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx
  • examples/react/material-react-table/src/material-react-table/features/mrtRefsFeature.ts
  • examples/react/material-react-table/tests/e2e/smoke.spec.ts
  • packages/angular-table/tests/flex-render/flex-render-table.test.ts
  • packages/ember-table/tests/integration/flex-render.test.gts
  • packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts
  • packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts
  • packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts
  • packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts
  • packages/table-core/tests/implementation/features/row-pagination/createPaginatedRowModel.test.ts
  • packages/table-core/tests/unit/features/row-expanding/rowExpandingFeature.utils.test.ts
  • packages/table-core/tests/unit/features/row-sorting/rowSortingFeature.utils.test.ts
🚧 Files skipped from review as they are similar to previous changes (32)
  • examples/react/material-react-table/src/main.tsx
  • docs/framework/octane/guide/sorting.md
  • docs/framework/react/guide/sorting.md
  • docs/framework/alpine/guide/sorting.md
  • docs/framework/lit/guide/sorting.md
  • packages/table-core/tests/implementation/features/row-pagination/createPaginatedRowModel.test.ts
  • examples/react/material-react-table/src/material-react-table/features/mrtRefsFeature.ts
  • docs/framework/preact/guide/sorting.md
  • docs/framework/vue/guide/sorting.md
  • examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx
  • docs/framework/solid/guide/sorting.md
  • docs/reference/index/interfaces/Column_RowSorting.md
  • docs/reference/static-functions/functions/column_getAutoSortDir.md
  • docs/reference/static-functions/functions/column_toggleSorting.md
  • examples/react/material-react-table/tests/e2e/smoke.spec.ts
  • packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts
  • docs/framework/angular/guide/sorting.md
  • packages/ember-table/tests/integration/flex-render.test.gts
  • docs/reference/index/interfaces/ColumnDef_RowSorting.md
  • packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts
  • docs/framework/svelte/guide/sorting.md
  • packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts
  • examples/react/mantine-react-table/src/mantine-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx
  • packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts
  • packages/table-core/tests/unit/features/row-expanding/rowExpandingFeature.utils.test.ts
  • docs/framework/ember/guide/sorting.md
  • examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx
  • packages/angular-table/tests/flex-render/flex-render-table.test.ts
  • examples/react/mantine-react-table/tests/e2e/smoke.spec.ts
  • beta-window-triage.md
  • examples/react/mantine-react-table/src/mantine-react-table/components/head/MRT_TableHeadCellSortLabel.tsx
  • packages/table-core/tests/unit/features/row-sorting/rowSortingFeature.utils.test.ts

📝 Walkthrough

Walkthrough

The PR updates row expansion and pagination behavior, sorting contracts and direction inference, sorting documentation across frameworks, and Mantine and Material React example behavior and smoke tests.

Changes

Expansion and pagination semantics

Layer / File(s) Summary
Guarded expansion state
packages/table-core/src/features/row-expanding/..., packages/table-core/tests/unit/features/row-expanding/..., packages/angular-table/tests/..., packages/ember-table/tests/..., beta-window-triage.md
Expansion operations now respect getRowCanExpand, skip redundant updates, exclude non-expandable rows from expanded-all state, and allow stale expansion entries to be collapsed.
Deduplicated paginated rows
packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts, packages/table-core/tests/implementation/features/row-pagination/...
Paginated flatRows now includes each row ID once in both pagination modes.

Sorting semantics

Layer / File(s) Summary
Sorting contracts and behavior
packages/table-core/src/features/row-sorting/..., packages/table-core/tests/unit/features/row-sorting/..., docs/framework/*/guide/sorting.md, docs/reference/index/interfaces/*RowSorting.md, docs/reference/static-functions/functions/column_*.md
sortUndefined: false delegates handling to the sorting function. Automatic sort direction skips nullish samples. getNextSortingOrder receives multi-sort state and respects enableMultiRemove.

React example integration

Layer / File(s) Summary
Mantine sorting and editing example
examples/react/mantine-react-table/src/..., examples/react/mantine-react-table/tests/e2e/smoke.spec.ts
The sort label subscribes to sorting atoms, editing preserves the original row reference, and smoke tests cover sorting and row editing.
Material sorting and editing example
examples/react/material-react-table/src/..., examples/react/material-react-table/tests/e2e/smoke.spec.ts
The sort label subscribes to sorting atoms, editing preserves the original row reference, ref maps initialize as objects, and smoke tests cover sorting, filters, and row editing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • TanStack/table#6458: The React sorting-label changes use reactive atom subscription behavior related to this PR.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main fixes for expanded, paginated, and sorting state behavior.
Linked Issues check ✅ Passed The changes address expandable-row state, unique paginated flatRows, no-op expansion toggles, multi-sort removal, and stable auto-sort direction [#6115, #5833, #6136, #4939, #4946, #5147, #5832].
Out of Scope Changes check ✅ Passed The documentation, regression tests, and MRT example fixes directly support the linked expansion and sorting objectives.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/expanding-sorting-state-contents

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 3, 2026

Copy link
Copy Markdown
More templates

@tanstack/alpine-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/alpine-table@6501

@tanstack/angular-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table@6501

@tanstack/angular-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table-devtools@6501

@tanstack/ember-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/ember-table@6501

@tanstack/lit-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/lit-table@6501

@tanstack/match-sorter-utils

npm i https://pkg.pr.new/TanStack/table/@tanstack/match-sorter-utils@6501

@tanstack/octane-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/octane-table@6501

@tanstack/preact-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table@6501

@tanstack/preact-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table-devtools@6501

@tanstack/react-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table@6501

@tanstack/react-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table-devtools@6501

@tanstack/solid-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table@6501

@tanstack/solid-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table-devtools@6501

@tanstack/svelte-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/svelte-table@6501

@tanstack/table-core

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-core@6501

@tanstack/table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-devtools@6501

@tanstack/vue-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table@6501

@tanstack/vue-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table-devtools@6501

commit: c35d70d

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
examples/react/mantine-react-table/src/mantine-react-table/components/head/MRT_TableHeadCellSortLabel.tsx (1)

4-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer table.Subscribe over the standalone Subscribe import.

This component imports the standalone Subscribe component. The TanStack Table v9 migration guide states that "For table.Subscribe from useTable, prefer that API — it uses overloads so JSX contextual typing works. This standalone component uses a union props type." The Material counterpart of this component uses table.Subscribe directly. Use table.Subscribe here too for better type inference and consistency across the Mantine and Material examples.

♻️ Proposed refactor
-import { Subscribe } from '`@tanstack/react-table`'
+
   return (
-    <Subscribe source={table.atoms.sorting}>
+    <table.Subscribe source={table.atoms.sorting}>
       {(sorting) => {
       }}
-    </Subscribe>
+    </table.Subscribe>
   )

Also applies to: 31-32, 96-96

🤖 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
`@examples/react/mantine-react-table/src/mantine-react-table/components/head/MRT_TableHeadCellSortLabel.tsx`
at line 4, Remove the standalone Subscribe import and update the component’s
Subscribe usages to call table.Subscribe instead, matching the Material
counterpart and preserving the existing subscription behavior and JSX content.
🤖 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 `@docs/framework/alpine/guide/expanding.md`:
- Around line 279-280: Correct the getCanExpand() wording to state that rows are
expanded only when row.getCanExpand() returns true, not when it “accepts” rows.
Apply this wording change in docs/framework/alpine/guide/expanding.md lines
279-280, docs/framework/angular/guide/expanding.md lines 254-255,
docs/framework/ember/guide/expanding.md lines 270-271,
docs/framework/lit/guide/expanding.md lines 273-274,
docs/framework/octane/guide/expanding.md lines 258-259, and
docs/framework/preact/guide/expanding.md lines 258-259.

In `@docs/reference/index/interfaces/Column_RowSorting.md`:
- Around line 142-144: Update the documentation for column_getNextSortingOrder
to state that enableSortingRemoval is the global gate for removing sorting,
while enableMultiRemove applies the additional restriction for multi-sort
toggles.

In `@packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts`:
- Around line 80-81: The TSDoc for table_toggleAllRowsExpanded must clarify that
having no expandable rows is a no-op only for expansion requests; collapsing
must still clear stale expanded IDs. Update the no-op description near
table_toggleAllRowsExpanded without changing the implementation.
- Around line 94-97: Update the guard in the all-rows expansion logic to treat
any state where table_getIsAllRowsExpanded(table) is true as already expanded,
not only currentExpanded === true. Preserve the existing partial-expansion and
non-expandable checks, and add a regression test covering
table_toggleAllRowsExpanded(table, true) with an explicit map containing every
expandable row ID to verify onExpandedChange is not called.

---

Nitpick comments:
In
`@examples/react/mantine-react-table/src/mantine-react-table/components/head/MRT_TableHeadCellSortLabel.tsx`:
- Line 4: Remove the standalone Subscribe import and update the component’s
Subscribe usages to call table.Subscribe instead, matching the Material
counterpart and preserving the existing subscription behavior and JSX content.
🪄 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: bbbc38de-d807-4682-874f-986352f71ef5

📥 Commits

Reviewing files that changed from the base of the PR and between 015b3d2 and 9b40f22.

📒 Files selected for processing (42)
  • beta-window-triage.md
  • docs/framework/alpine/guide/expanding.md
  • docs/framework/alpine/guide/sorting.md
  • docs/framework/angular/guide/expanding.md
  • docs/framework/angular/guide/sorting.md
  • docs/framework/ember/guide/expanding.md
  • docs/framework/ember/guide/sorting.md
  • docs/framework/lit/guide/expanding.md
  • docs/framework/lit/guide/sorting.md
  • docs/framework/octane/guide/expanding.md
  • docs/framework/octane/guide/sorting.md
  • docs/framework/preact/guide/expanding.md
  • docs/framework/preact/guide/sorting.md
  • docs/framework/react/guide/expanding.md
  • docs/framework/react/guide/sorting.md
  • docs/framework/solid/guide/expanding.md
  • docs/framework/solid/guide/sorting.md
  • docs/framework/svelte/guide/expanding.md
  • docs/framework/svelte/guide/sorting.md
  • docs/framework/vue/guide/expanding.md
  • docs/framework/vue/guide/sorting.md
  • docs/reference/index/interfaces/ColumnDef_RowSorting.md
  • docs/reference/index/interfaces/Column_RowSorting.md
  • docs/reference/static-functions/functions/column_getAutoSortDir.md
  • docs/reference/static-functions/functions/column_toggleSorting.md
  • examples/react/mantine-react-table/src/mantine-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx
  • examples/react/mantine-react-table/src/mantine-react-table/components/head/MRT_TableHeadCellSortLabel.tsx
  • examples/react/mantine-react-table/tests/e2e/smoke.spec.ts
  • examples/react/material-react-table/src/main.tsx
  • examples/react/material-react-table/src/material-react-table/components/buttons/MRT_ToggleRowActionMenuButton.tsx
  • examples/react/material-react-table/src/material-react-table/components/head/MRT_TableHeadCellSortLabel.tsx
  • examples/react/material-react-table/src/material-react-table/features/mrtRefsFeature.ts
  • examples/react/material-react-table/tests/e2e/smoke.spec.ts
  • packages/angular-table/tests/flex-render/flex-render-table.test.ts
  • packages/ember-table/tests/integration/flex-render.test.gts
  • packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts
  • packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts
  • packages/table-core/src/features/row-sorting/rowSortingFeature.types.ts
  • packages/table-core/src/features/row-sorting/rowSortingFeature.utils.ts
  • packages/table-core/tests/implementation/features/row-pagination/createPaginatedRowModel.test.ts
  • packages/table-core/tests/unit/features/row-expanding/rowExpandingFeature.utils.test.ts
  • packages/table-core/tests/unit/features/row-sorting/rowSortingFeature.utils.test.ts

Comment on lines +279 to +280
Toggling is guarded and de-duplicated. `row.toggleExpanded()` and `table.toggleAllRowsExpanded()` only expand rows that `row.getCanExpand()` accepts, and they skip `onExpandedChange` entirely when the requested state already matches the current state. Collapsing is always allowed, so stale ids left in a controlled `expanded` map can still be cleared.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the getCanExpand() wording.

getCanExpand() returns a boolean. It does not accept rows. Replace “rows that row.getCanExpand() accepts” with “rows for which row.getCanExpand() returns true”.

  • docs/framework/alpine/guide/expanding.md#L279-L280: Correct the predicate wording.
  • docs/framework/angular/guide/expanding.md#L254-L255: Apply the same wording correction.
  • docs/framework/ember/guide/expanding.md#L270-L271: Apply the same wording correction.
  • docs/framework/lit/guide/expanding.md#L273-L274: Apply the same wording correction.
  • docs/framework/octane/guide/expanding.md#L258-L259: Apply the same wording correction.
  • docs/framework/preact/guide/expanding.md#L258-L259: Apply the same wording correction.
📍 Affects 6 files
  • docs/framework/alpine/guide/expanding.md#L279-L280 (this comment)
  • docs/framework/angular/guide/expanding.md#L254-L255
  • docs/framework/ember/guide/expanding.md#L270-L271
  • docs/framework/lit/guide/expanding.md#L273-L274
  • docs/framework/octane/guide/expanding.md#L258-L259
  • docs/framework/preact/guide/expanding.md#L258-L259
🤖 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 `@docs/framework/alpine/guide/expanding.md` around lines 279 - 280, Correct the
getCanExpand() wording to state that rows are expanded only when
row.getCanExpand() returns true, not when it “accepts” rows. Apply this wording
change in docs/framework/alpine/guide/expanding.md lines 279-280,
docs/framework/angular/guide/expanding.md lines 254-255,
docs/framework/ember/guide/expanding.md lines 270-271,
docs/framework/lit/guide/expanding.md lines 273-274,
docs/framework/octane/guide/expanding.md lines 258-259, and
docs/framework/preact/guide/expanding.md lines 258-259.

Comment on lines +142 to +144
Returns the next sorting order. Pass `multi` to resolve the order for a
multi-sort toggle, where `enableMultiRemove` governs whether the cycle can
remove the sort.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document the global removal setting as well.

enableSortingRemoval remains the global removal gate in column_getNextSortingOrder; enableMultiRemove adds a multi-sort-specific restriction. Update this text so readers do not assume enableMultiRemove alone controls removal.

🤖 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 `@docs/reference/index/interfaces/Column_RowSorting.md` around lines 142 - 144,
Update the documentation for column_getNextSortingOrder to state that
enableSortingRemoval is the global gate for removing sorting, while
enableMultiRemove applies the additional restriction for multi-sort toggles.

…g toggle defaults

Two independent clusters of default-behavior bugs from the beta triage.

Expanded and paginated state contents:

Expand-all materialized every id in `rowsById`, including leaf rows that
can never expand, so a serialized `ExpandedState` was polluted with dead
keys and `getExpandedDepth` was skewed by them. Materialization now writes
only ids where `row.getCanExpand()` is true, chosen over `subRows.length`
so `getRowCanExpand` lazy-load overrides stay expandable.
`getExpandedDepth` filters the same way, and `getIsAllRowsExpanded` now
only considers expandable rows so the materialized map still round-trips
as "all expanded" (a map of stale ids with no expandable rows is false).

Paginated `flatRows` pushed each row and then recursed into its subRows,
but page rows already contain expanded descendants inline, so those rows
appeared twice. The rebuild now dedupes by row id. Collapsed descendants
stay included, consistent with every other row model, where `flatRows`
ignores expansion state.

`row.toggleExpanded(bool)` and `table.toggleAllRowsExpanded(bool)` fired
`onExpandedChange` even when the requested state already matched, so
controlled consumers got spurious callbacks. Both now early-return.

Neither toggle consulted `row.getCanExpand()`, unlike their row-selection
equivalents, so a non-expandable row could be written into expanded state
imperatively. The expand direction is now guarded; collapsing is always
allowed so stale expanded ids can still be cleaned up.

Sorting toggle defaults:

`column.toggleSorting()` called `column.getNextSortingOrder(column)` with
no `multi` argument, so `enableMultiRemove` was dead on every path. The
argument is now forwarded as `multi && column.getCanMultiSort()`, matching
the multi-mode condition the updater itself uses. The public
`getNextSortingOrder` type now accepts the `multi` argument it always
supported at runtime.

`column.getAutoSortDir()` sampled only `flatRows[0]`, so a leading null or
a manual-sorting data swap flipped the inferred first direction mid-cycle
and silently dropped a state from the toggle cycle. It now samples the
first 10 rows for a non-nullish value, matching `getAutoSortFn`.

Docs: `sortUndefined: false` was documented as "considered tied" in all
framework sorting guides; undefined values are actually passed straight to
the sorting function with no special handling. Corrected, and the missing
`'first'`/`'last'` bullets were added to the generated reference.

Also fixes three crashes in the MRT examples surfaced while testing the
sorting changes. The MUI and Mantine sort labels read `sorting` off
`state`, which does not carry it, and crashed on `sorting.length`; they now
read it through `table.Subscribe` on `table.atoms.sorting`, which also
makes the badge reactive. The row-action edit handler passed a shallow row
copy to `setEditingRow`, breaking the row identity the edit modal needs.
`mrtRefsFeature` seeded the keyed `editInputRefs`/`filterInputRefs` bags
with `null` instead of `{}`, crashing on first keyed write. New e2e
coverage pins all three plus the sort-direction indicator.

Closes #6115
Closes #5833
Closes #6136
Closes #4939
Closes #4946
Closes #5147
Closes #5832

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@KevinVandy
KevinVandy force-pushed the fix/expanding-sorting-state-contents branch from 9b40f22 to c35d70d Compare August 3, 2026 03:12
@KevinVandy
KevinVandy merged commit aad2c29 into beta Aug 3, 2026
9 checks passed
@KevinVandy
KevinVandy deleted the fix/expanding-sorting-state-contents branch August 3, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment