Skip to content

feat: add angular devtools support and fix core devtools reactivity#6248

Open
riccardoperra wants to merge 12 commits into
alphafrom
feat/angular-devtools
Open

feat: add angular devtools support and fix core devtools reactivity#6248
riccardoperra wants to merge 12 commits into
alphafrom
feat/angular-devtools

Conversation

@riccardoperra
Copy link
Copy Markdown
Collaborator

@riccardoperra riccardoperra commented May 9, 2026

TanStack Devtools Angular package is not published yet in npm

  • add new @tanstack/angular-table-devtools package
  • add devtools integration in composable tables

Summary by CodeRabbit

  • New Features
    • TanStack Table DevTools added to examples (dev-mode, lazy-loaded) for interactive table inspection.
  • Bug Fixes / UX
    • Example UIs now read from the public table.state surface — fixes debug panels, pagination, resizing and other live bindings.
  • Documentation
    • Migration and framework guides updated to reference table.state instead of the legacy store surface.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

📝 Walkthrough

Walkthrough

Adds a new Angular devtools package, wires TanStack Table devtools into Angular and React examples, introduces React table instanceId support, refactors table-devtools to Solid reactivity, and updates adapters, examples, types, tests, and docs to use the new table.state surface.

Changes

All changes (single checkpoint)

Layer / File(s) Summary
Entire PR (package, integration, reactivity, adapters, examples, tests, docs)
packages/angular-table-devtools/*, packages/table-devtools/*, packages/react-table-devtools/*, packages/react-table/*, packages/*-table/*, examples/*/*, packages/*/skills/*, examples/react/composable-tables/*
Creates @tanstack/angular-table-devtools with build/test/config, conditionally provides Angular devtools in examples, injects devtools into Angular components, adds React table instanceId and updates React devtools hook, migrates table-devtools internals to Solid signals/memos/effects, updates adapters’ public types to expose table.state (and deprecate store reads), and adds tests/docs reflecting the state-surface change.

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

Suggested reviewers:

  • schiller-manuel
  • KevinVandy

🐰 I stitched the tables, signals, and more,
A devtools patch from ceiling to floor.
Angular, React, Solid — all sing in tune,
Tables now hum with a debugty-tune. 🥕✨

✨ 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 feat/angular-devtools

@riccardoperra riccardoperra changed the title feat: add angular devtools feat: integrate angular devtools May 9, 2026
@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 9, 2026

View your CI Pipeline Execution ↗ for commit 403a782


☁️ Nx Cloud last updated this comment at 2026-05-24 16:45:12 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 9, 2026

More templates

@tanstack/angular-table

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

@tanstack/angular-table-devtools

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

@tanstack/lit-table

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

@tanstack/match-sorter-utils

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

@tanstack/preact-table

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

@tanstack/preact-table-devtools

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

@tanstack/react-table

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

@tanstack/react-table-devtools

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

@tanstack/solid-table

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

@tanstack/solid-table-devtools

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

@tanstack/svelte-table

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

@tanstack/table-core

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

@tanstack/table-devtools

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

@tanstack/vue-table

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

@tanstack/vue-table-devtools

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

commit: 403a782

Copy link
Copy Markdown

@nx-cloud nx-cloud Bot left a comment

Choose a reason for hiding this comment

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

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud is proposing a fix for your failed CI:

We resolved two CI failures introduced by the angular devtools integration. The sherif failure was fixed by reordering dependencies alphabetically in the composable-tables example, and the knip failures were fixed by removing the unused @tanstack/angular-devtools dependency from the package, adding the missing tslib dependency required by importHelpers, and removing the export keyword from the internal-only generateId function.

Tip

We verified this fix by re-running table:test:sherif, table:test:knip.

Suggested Fix changes
diff --git a/examples/angular/composable-tables/package.json b/examples/angular/composable-tables/package.json
index 2663831d..3d441290 100644
--- a/examples/angular/composable-tables/package.json
+++ b/examples/angular/composable-tables/package.json
@@ -19,8 +19,8 @@
     "@angular/router": "^21.2.11",
     "@faker-js/faker": "^10.4.0",
     "@tanstack/angular-devtools": "https://pkg.pr.new/TanStack/devtools/@tanstack/angular-devtools@368",
-    "@tanstack/angular-table-devtools": "^9.0.0-alpha.43",
     "@tanstack/angular-table": "^9.0.0-alpha.45",
+    "@tanstack/angular-table-devtools": "^9.0.0-alpha.43",
     "rxjs": "~7.8.2",
     "tslib": "^2.8.1"
   },
diff --git a/packages/angular-table-devtools/package.json b/packages/angular-table-devtools/package.json
index 7bf1bf22..2df42e78 100644
--- a/packages/angular-table-devtools/package.json
+++ b/packages/angular-table-devtools/package.json
@@ -44,10 +44,10 @@
     "src"
   ],
   "dependencies": {
-    "@tanstack/angular-devtools": "https://pkg.pr.new/TanStack/devtools/@tanstack/angular-devtools@368",
     "@tanstack/devtools-utils": "https://pkg.pr.new/TanStack/devtools/@tanstack/devtools-utils@368",
     "@tanstack/table-core": "workspace:*",
-    "@tanstack/table-devtools": "workspace:*"
+    "@tanstack/table-devtools": "workspace:*",
+    "tslib": "^2.8.1"
   },
   "peerDependencies": {
     "@angular/core": ">=21.0.0"
diff --git a/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts b/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts
index 40303e30..e769ae3b 100644
--- a/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts
+++ b/packages/angular-table-devtools/src/injectTanStackTableDevtools.ts
@@ -24,7 +24,7 @@ function normalizeName(name?: string) {
 }
 
 let autoId = 0
-export function generateId(): string {
+function generateId(): string {
   const appId = inject(APP_ID)
   return `tanstacktable-${appId}_${autoId++}${Date.now().toString(36)}`
 }

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally DsIG-vU7o

Apply fix locally with your editor ↗   View interactive diff ↗



🎓 Learn more about Self-Healing CI on nx.dev

@riccardoperra riccardoperra force-pushed the feat/angular-devtools branch 2 times, most recently from 9a3e490 to d397a99 Compare May 9, 2026 08:05
@riccardoperra riccardoperra changed the title feat: integrate angular devtools feat(angular): integrate angular devtools May 9, 2026
@riccardoperra riccardoperra force-pushed the feat/angular-devtools branch 2 times, most recently from 5b002f3 to 926dcf9 Compare May 17, 2026 12:21
@riccardoperra riccardoperra changed the title feat(angular): integrate angular devtools feat: add angular devtools support and fix core devtools reactivity May 19, 2026
@riccardoperra riccardoperra force-pushed the feat/angular-devtools branch from 17bc739 to cd854d6 Compare May 19, 2026 13:24
Refactor devtools panel with a more solid-idiomatic approach, using memo and dynamic `useTableState` subscription via Accessor getter to not break reactivity.
@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 19, 2026

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm @angular/build is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: examples/angular/basic-external-atoms/package.jsonnpm/@angular/build@21.2.12

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@angular/build@21.2.12. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @angular/cli is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: examples/angular/basic-external-atoms/package.jsonnpm/@angular/cli@21.2.12

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@angular/cli@21.2.12. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
High CVE: npm @angular/platform-server: SSRF via Hostname Hijacking

CVE: GHSA-rfh7-fxqc-q52v @angular/platform-server: SSRF via Hostname Hijacking (HIGH)

Affected versions: >= 22.0.0-next.0 < 22.0.0-next.12; >= 21.0.0-next.0 < 21.2.13; >= 20.0.0-next.0 < 20.3.21; >= 19.0.0-next.0 < 19.2.22; <= 18.2.14

Patched version: 21.2.13

From: examples/angular/remote-data/package.jsonnpm/@angular/platform-server@21.2.12

ℹ Read more on: This package | This alert | What is a CVE?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Remove or replace dependencies that include known high severity CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@angular/platform-server@21.2.12. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @schematics/angular is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: ?npm/@angular/cli@21.2.12npm/@schematics/angular@21.2.12

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@schematics/angular@21.2.12. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@riccardoperra riccardoperra force-pushed the feat/angular-devtools branch from 2967e10 to 20b40f9 Compare May 19, 2026 13:30
@riccardoperra riccardoperra force-pushed the feat/angular-devtools branch from 20b40f9 to bdd89ba Compare May 19, 2026 13:35
Comment thread packages/react-table/src/useTable.ts Outdated
@@ -137,6 +141,12 @@ export function useTable<
tableOptions: TableOptions<TFeatures, TData>,
selector?: (state: TableState<TFeatures>) => TSelected,
): ReactTable<TFeatures, TData, TSelected> {
const instanceIdRef = useRef<string | undefined>(undefined)
const id = useId()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this technically makes this a React 18+ package now. We could just require an id/key table option in order for devtools to work, and then remove the 2nd arg from useTanStackTableDevtools(table)

Copy link
Copy Markdown
Collaborator Author

@riccardoperra riccardoperra May 19, 2026

Choose a reason for hiding this comment

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

What about removing entirely useId 🤔 ? There is still the generation logic provided next. it was just added as a prefix but probably unnecessary

-  const id = useId()
   if (!instanceIdRef.current) {
    // eslint-disable-next-line @eslint-react/purity
-     instanceIdRef.current = `${id}-${Math.random().toString(36).slice(2, 9)}`
+     instanceIdRef.current = Math.random().toString(36).slice(2, 9);
   }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Using math.random for anything in a library usually causes security scanners to freak out, even if it's for something trivial like this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

switched with crypto.randomUUID (if present) or just id++ for this

@KevinVandy KevinVandy marked this pull request as ready for review May 21, 2026 23:10
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (4)
packages/table-devtools/src/components/StatePanel.tsx (1)

1-1: 💤 Low value

Unused import: createEffect.

createEffect is imported but not used in this file.

🧹 Proposed fix
-import { For, Show, createEffect, createMemo, createSignal } from 'solid-js'
+import { For, Show, createMemo, createSignal } from 'solid-js'
🤖 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 `@packages/table-devtools/src/components/StatePanel.tsx` at line 1, Remove the
unused Solid import createEffect from the import list in StatePanel.tsx; update
the import line that currently reads import { For, Show, createEffect,
createMemo, createSignal } from 'solid-js' to omit createEffect so only used
symbols (For, Show, createMemo, createSignal) remain, ensuring no other
references to createEffect exist in the file before committing.
packages/table-devtools/src/useTableStore.ts (1)

5-9: 💤 Low value

Outdated documentation.

The comment still claims the hook handles both subscribe APIs (function return for 0.8.x and { unsubscribe } for 0.9.x), but the implementation now only handles the { unsubscribe } object return pattern on line 28.

📝 Proposed fix
 /**
- * Subscribes to a table store and returns a reactive signal.
- * Handles both subscribe APIs: function return (store 0.8.x) and
- * { unsubscribe } object return (store 0.9.x).
+ * Subscribes to a table store and returns a reactive signal.
  */
🤖 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 `@packages/table-devtools/src/useTableStore.ts` around lines 5 - 9, The
docblock for useTableStore is outdated: it claims support for both the old
function-return subscribe API and the new { unsubscribe } object-return API, but
the implementation only handles the object-return pattern; update the comment
above useTableStore to state that the hook expects the { unsubscribe }
object-return subscription API (remove the mention of the function-return 0.8.x
pattern) so the documentation matches the actual behavior of the subscribe
handling in useTableStore.
packages/table-devtools/src/components/ThreeWayResizableSplit.tsx (1)

23-23: ⚡ Quick win

Document the ESLint suppression rationale.

The suppression is likely justified since event handlers in Solid can read signals without tracking, but adding a brief comment would help future maintainers understand why the rule was disabled.

📝 Suggested documentation
-    // eslint-disable-next-line solid/reactivity
+    // eslint-disable-next-line solid/reactivity -- Event handlers can read signals without tracking
     (e) => {
🤖 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 `@packages/table-devtools/src/components/ThreeWayResizableSplit.tsx` at line
23, Add a short rationale comment immediately above the existing eslint
suppression for the solid/reactivity rule in ThreeWayResizableSplit (where "//
eslint-disable-next-line solid/reactivity" appears) explaining why the rule is
disabled (e.g., event handlers intentionally read signals without tracking to
avoid creating reactive subscriptions and to prevent unnecessary rerenders).
Reference the component name ThreeWayResizableSplit and the specific suppression
so maintainers understand this is intentional and safe for the event-handler
context.
examples/angular/row-selection-signal/src/app/app.config.ts (1)

6-20: ⚡ Quick win

Provider array creates nested array in production builds.

The ternary expression isDevMode() ? provideTanStackDevtools(...) : [] produces [[]] (an array containing an empty array) when dev mode is false. While Angular may tolerate this, it's structurally incorrect.

♻️ Use spread operator to flatten conditional providers
 export const appConfig: ApplicationConfig = {
   providers: [
-    isDevMode()
-      ? provideTanStackDevtools(() => ({
-          plugins: [
-            {
-              name: 'TanStack Table',
-              render: () =>
-                import('`@tanstack/angular-table-devtools`').then((m) =>
-                  m.TableDevtoolsPanel(),
-                ),
-            },
-          ],
-        }))
-      : [],
+    ...(isDevMode()
+      ? [provideTanStackDevtools(() => ({
+          plugins: [
+            {
+              name: 'TanStack Table',
+              render: () =>
+                import('`@tanstack/angular-table-devtools`').then((m) =>
+                  m.TableDevtoolsPanel(),
+                ),
+            },
+          ],
+        }))]
+      : []),
   ],
 }

Note: This pattern appears across all Angular example app.config.ts files in this PR. Consider applying the fix consistently.

🤖 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/angular/row-selection-signal/src/app/app.config.ts` around lines 6 -
20, The providers array conditionally returns an array (or empty array) causing
a nested array ([[]]) in production; update the providers entry to spread the
conditional result so it flattens into the outer array—e.g., replace the current
ternary `isDevMode() ? provideTanStackDevtools(...) : []` with `...(isDevMode()
? [provideTanStackDevtools(() => ({ plugins: [...] }))] : [])` (referencing
isDevMode and provideTanStackDevtools and the existing devtools plugin block)
and apply the same pattern across other app.config.ts examples.
🤖 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 `@examples/angular/row-selection-signal/package.json`:
- Line 14: Dependencies for Angular in package.json are inconsistent: update the
downgraded packages (e.g., "`@angular/animations`" and any other Angular packages
currently at "^21.2.12") to the same version used by the rest ("^21.2.13") so
all `@angular/`* entries use a single, consistent version spec; edit the
dependency entries in package.json to replace "^21.2.12" with "^21.2.13" for the
identified Angular package names.

In `@packages/angular-table-devtools/src/injectTanStackTableDevtools.ts`:
- Around line 46-53: The code currently calls
removeTableDevtoolsTarget(registrationId) when enabledValue is falsy or table is
missing but then continues to call upsertTableDevtoolsTarget(...) which
re-registers the target (possibly with an undefined table); update the branch so
that when !enabledValue || !table the function returns early (or otherwise skips
the subsequent upsert) instead of falling through, ensuring
removeTableDevtoolsTarget(registrationId) is the terminal action for that case
and only call upsertTableDevtoolsTarget with { id: registrationId, table, name:
normalizeName(name) } when enabledValue is truthy and table exists.

In `@packages/react-table-devtools/src/useTanStackTableDevtools.ts`:
- Around line 38-54: The effect that registers the devtools target (useEffect)
omits normalizedName from its dependency array, so changes to name won't trigger
upsertTableDevtoolsTarget when instanceId is stable; update the dependency list
for the useEffect that calls upsertTableDevtoolsTarget/removeTableDevtoolsTarget
to include normalizedName alongside enabled, registrationId, and instanceId so
the effect reruns and existingRegistration.name is updated when normalizedName
changes.
- Around line 31-34: The computed instanceId is evaluated unguarded and can
throw when table is undefined, and normalizedName changes are not propagated
because it isn’t in the effect dependencies; inside useTanStackTableDevtools
(function name) move the computation of instanceId into the useEffect that
guards on table (or guard before accessing (table as ...).instanceId) and add
normalizedName to the effect dependency array so instanceId is recomputed when
name changes; ensure the upsertTableDevtoolsTarget call uses the locally
computed instanceId and the current normalizedName so updates propagate
correctly.

In `@packages/react-table/src/useTable.ts`:
- Around line 145-150: The current check "'randomUUID' in globalThis.crypto" can
throw if globalThis.crypto is undefined; update the guard around instanceIdRef
initialization (in useTable) to safely check for crypto and randomUUID — e.g.,
verify globalThis.crypto exists and has a randomUUID function (like typeof
globalThis.crypto?.randomUUID === 'function' or 'randomUUID' in
(globalThis.crypto || {})) before calling it, falling back to the
`table-${++tableId}` path if not available; reference instanceIdRef, useRef,
globalThis.crypto.randomUUID and tableId when making the change.

In `@packages/table-devtools/src/components/Shell.tsx`:
- Around line 52-65: The render-prop parameters passed into Solid's Show are
already resolved values, not accessors—fix the JSX in the Show children to treat
the parameters as values: when destructuring the first Show use the value (e.g.,
tableOptions) as the options prop (options={tableOptions}), and in the inner
Show use the value (e.g., selectedTargetId) as the Select value
(value={selectedTargetId}) and call setSelectedTargetId from the onChange
handler; ensure you still call the accessors tableOptions() and
selectedTargetId() only where you intend to read the signals directly, and
reference Show, tableOptions, selectedTargetId, setSelectedTargetId, Select, and
EMPTY_PANEL_KEY to locate the incorrect props.

---

Nitpick comments:
In `@examples/angular/row-selection-signal/src/app/app.config.ts`:
- Around line 6-20: The providers array conditionally returns an array (or empty
array) causing a nested array ([[]]) in production; update the providers entry
to spread the conditional result so it flattens into the outer array—e.g.,
replace the current ternary `isDevMode() ? provideTanStackDevtools(...) : []`
with `...(isDevMode() ? [provideTanStackDevtools(() => ({ plugins: [...] }))] :
[])` (referencing isDevMode and provideTanStackDevtools and the existing
devtools plugin block) and apply the same pattern across other app.config.ts
examples.

In `@packages/table-devtools/src/components/StatePanel.tsx`:
- Line 1: Remove the unused Solid import createEffect from the import list in
StatePanel.tsx; update the import line that currently reads import { For, Show,
createEffect, createMemo, createSignal } from 'solid-js' to omit createEffect so
only used symbols (For, Show, createMemo, createSignal) remain, ensuring no
other references to createEffect exist in the file before committing.

In `@packages/table-devtools/src/components/ThreeWayResizableSplit.tsx`:
- Line 23: Add a short rationale comment immediately above the existing eslint
suppression for the solid/reactivity rule in ThreeWayResizableSplit (where "//
eslint-disable-next-line solid/reactivity" appears) explaining why the rule is
disabled (e.g., event handlers intentionally read signals without tracking to
avoid creating reactive subscriptions and to prevent unnecessary rerenders).
Reference the component name ThreeWayResizableSplit and the specific suppression
so maintainers understand this is intentional and safe for the event-handler
context.

In `@packages/table-devtools/src/useTableStore.ts`:
- Around line 5-9: The docblock for useTableStore is outdated: it claims support
for both the old function-return subscribe API and the new { unsubscribe }
object-return API, but the implementation only handles the object-return
pattern; update the comment above useTableStore to state that the hook expects
the { unsubscribe } object-return subscription API (remove the mention of the
function-return 0.8.x pattern) so the documentation matches the actual behavior
of the subscribe handling in useTableStore.
🪄 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

Run ID: 7181463f-b364-476b-8721-90df11ac2ddc

📥 Commits

Reviewing files that changed from the base of the PR and between 4db9f8e and 8a240a5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (84)
  • examples/angular/basic-app-table/package.json
  • examples/angular/basic-app-table/src/app/app.config.ts
  • examples/angular/basic-app-table/src/app/app.ts
  • examples/angular/basic-inject-table/package.json
  • examples/angular/basic-inject-table/src/app/app.config.ts
  • examples/angular/basic-inject-table/src/app/app.ts
  • examples/angular/column-ordering/package.json
  • examples/angular/column-ordering/src/app/app.config.ts
  • examples/angular/column-ordering/src/app/app.ts
  • examples/angular/column-pinning-sticky/package.json
  • examples/angular/column-pinning-sticky/src/app/app.config.ts
  • examples/angular/column-pinning-sticky/src/app/app.ts
  • examples/angular/column-pinning/package.json
  • examples/angular/column-pinning/src/app/app.config.ts
  • examples/angular/column-pinning/src/app/app.ts
  • examples/angular/column-resizing-performant/package.json
  • examples/angular/column-resizing-performant/src/app/app.config.ts
  • examples/angular/column-resizing-performant/src/app/app.ts
  • examples/angular/column-visibility/package.json
  • examples/angular/column-visibility/src/app/app.config.ts
  • examples/angular/column-visibility/src/app/app.ts
  • examples/angular/composable-tables/package.json
  • examples/angular/composable-tables/src/app/app.config.ts
  • examples/angular/composable-tables/src/app/components/products-table/products-table.ts
  • examples/angular/composable-tables/src/app/components/users-table/users-table.ts
  • examples/angular/custom-plugin/package.json
  • examples/angular/custom-plugin/src/app/app.config.ts
  • examples/angular/custom-plugin/src/app/app.ts
  • examples/angular/editable/package.json
  • examples/angular/editable/src/app/app.config.ts
  • examples/angular/editable/src/app/app.ts
  • examples/angular/expanding/package.json
  • examples/angular/expanding/src/app/app.config.ts
  • examples/angular/expanding/src/app/app.ts
  • examples/angular/filters/package.json
  • examples/angular/filters/src/app/app.config.ts
  • examples/angular/filters/src/app/app.ts
  • examples/angular/grouping/package.json
  • examples/angular/grouping/src/app/app.config.ts
  • examples/angular/grouping/src/app/app.ts
  • examples/angular/remote-data/package.json
  • examples/angular/remote-data/src/app/app.config.ts
  • examples/angular/remote-data/src/app/app.ts
  • examples/angular/row-dnd/package.json
  • examples/angular/row-dnd/src/app/app.config.ts
  • examples/angular/row-dnd/src/app/app.ts
  • examples/angular/row-selection-signal/package.json
  • examples/angular/row-selection-signal/src/app/app.component.ts
  • examples/angular/row-selection-signal/src/app/app.config.ts
  • examples/angular/row-selection/package.json
  • examples/angular/row-selection/src/app/app.config.ts
  • examples/angular/row-selection/src/app/app.ts
  • examples/angular/signal-input/package.json
  • examples/angular/signal-input/src/app/app.config.ts
  • examples/angular/signal-input/src/app/person-table/person-table.ts
  • examples/angular/sub-components/package.json
  • examples/angular/sub-components/src/app/app.config.ts
  • examples/angular/sub-components/src/app/app.ts
  • examples/react/composable-tables/package.json
  • examples/react/composable-tables/src/main.tsx
  • packages/angular-table-devtools/eslint.config.js
  • packages/angular-table-devtools/package.json
  • packages/angular-table-devtools/src/TableDevtools.ts
  • packages/angular-table-devtools/src/index.ts
  • packages/angular-table-devtools/src/injectTanStackTableDevtools.ts
  • packages/angular-table-devtools/src/plugin.ts
  • packages/angular-table-devtools/src/production.ts
  • packages/angular-table-devtools/tsconfig.json
  • packages/angular-table-devtools/tsdown.config.ts
  • packages/angular-table-devtools/vite.config.ts
  • packages/react-table-devtools/src/useTanStackTableDevtools.ts
  • packages/react-table/src/useTable.ts
  • packages/table-devtools/eslint.config.js
  • packages/table-devtools/package.json
  • packages/table-devtools/src/TableContextProvider.tsx
  • packages/table-devtools/src/components/ColumnsPanel.tsx
  • packages/table-devtools/src/components/FeaturesPanel.tsx
  • packages/table-devtools/src/components/OptionsPanel.tsx
  • packages/table-devtools/src/components/RowsPanel.tsx
  • packages/table-devtools/src/components/Shell.tsx
  • packages/table-devtools/src/components/StatePanel.tsx
  • packages/table-devtools/src/components/ThreeWayResizableSplit.tsx
  • packages/table-devtools/src/tableTarget.ts
  • packages/table-devtools/src/useTableStore.ts

"private": true,
"dependencies": {
"@angular/animations": "^21.2.13",
"@angular/animations": "^21.2.12",
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inconsistent Angular package versions.

Two Angular packages are downgraded to 21.2.12 while the rest remain at 21.2.13 (lines 15-19). This version mismatch can cause peer dependency warnings and potential runtime issues.

📦 Align Angular package versions
-    "`@angular/animations`": "^21.2.12",
+    "`@angular/animations`": "^21.2.13",
-    "`@angular/platform-browser-dynamic`": "^21.2.12",
+    "`@angular/platform-browser-dynamic`": "^21.2.13",

Also applies to: 20-20

🤖 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/angular/row-selection-signal/package.json` at line 14, Dependencies
for Angular in package.json are inconsistent: update the downgraded packages
(e.g., "`@angular/animations`" and any other Angular packages currently at
"^21.2.12") to the same version used by the rest ("^21.2.13") so all `@angular/`*
entries use a single, consistent version spec; edit the dependency entries in
package.json to replace "^21.2.12" with "^21.2.13" for the identified Angular
package names.

Comment on lines +46 to +53
if (!enabledValue || !table) {
removeTableDevtoolsTarget(registrationId)
}
upsertTableDevtoolsTarget({
id: registrationId,
table: table,
name: normalizeName(name),
})
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop upserting after the disabled/no-table branch.

Lines 46-53 remove the target but then still re-register it. This makes enabled ineffective and can register an undefined table.

Proposed fix
       const { table, name } = options()
       const enabledValue = enabled()
       if (!enabledValue || !table) {
         removeTableDevtoolsTarget(registrationId)
+        return
       }
       upsertTableDevtoolsTarget({
         id: registrationId,
         table: table,
         name: normalizeName(name),
       })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!enabledValue || !table) {
removeTableDevtoolsTarget(registrationId)
}
upsertTableDevtoolsTarget({
id: registrationId,
table: table,
name: normalizeName(name),
})
if (!enabledValue || !table) {
removeTableDevtoolsTarget(registrationId)
return
}
upsertTableDevtoolsTarget({
id: registrationId,
table: table,
name: normalizeName(name),
})
🤖 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 `@packages/angular-table-devtools/src/injectTanStackTableDevtools.ts` around
lines 46 - 53, The code currently calls
removeTableDevtoolsTarget(registrationId) when enabledValue is falsy or table is
missing but then continues to call upsertTableDevtoolsTarget(...) which
re-registers the target (possibly with an undefined table); update the branch so
that when !enabledValue || !table the function returns early (or otherwise skips
the subsequent upsert) instead of falling through, ensuring
removeTableDevtoolsTarget(registrationId) is the terminal action for that case
and only call upsertTableDevtoolsTarget with { id: registrationId, table, name:
normalizeName(name) } when enabledValue is truthy and table exists.

Comment on lines +31 to +34
const instanceId =
// instanceId from react table adapter (if it exists) allows for stable devtools registration even if the table instance changes
(table as unknown as { instanceId?: string }).instanceId ||
`${registrationId}${normalizedName ? `-${normalizedName}` : ``}`
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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/react-table-devtools/src/useTanStackTableDevtools.ts"
if [ ! -f "$FILE" ]; then
  echo "File not found: $FILE" >&2
  exit 1
fi

# Show the relevant lines with context (keep output small)
nl -ba "$FILE" | sed -n '1,120p' | sed -n '20,90p'

Repository: TanStack/table

Length of output: 102


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/react-table-devtools/src/useTanStackTableDevtools.ts"
test -f "$FILE" || { echo "File not found: $FILE" >&2; exit 1; }

# Print only the relevant section (around the reported line range)
# Use cat -n (available) instead of nl.
cat -n "$FILE" | sed -n '1,120p' | sed -n '20,90p'

echo "-----"

# Also extract just the `instanceId` assignment block and the nearest effect deps
rg -n "instanceId\s*=" "$FILE" -n
rg -n "useEffect\(|upsertTableDevtoolsTarget|normalizedName|enabled|registrationId" "$FILE" -n

Repository: TanStack/table

Length of output: 2180


Fix potential runtime crash in instanceId and ensure normalizedName updates propagate

  • Critical: instanceId is computed outside the useEffect guard; when table is undefined, (table ...).instanceId can throw before the if (!table) check runs.
  • Minor: normalizedName is used in upsertTableDevtoolsTarget({ name: normalizedName }), but it’s not in the effect deps; if table.instanceId is present, instanceId won’t change when name changes, so updates may not propagate.
🐛 Suggested fix
-  const instanceId =
-    // instanceId from react table adapter (if it exists) allows for stable devtools registration even if the table instance changes
-    (table as unknown as { instanceId?: string }).instanceId ||
-    `${registrationId}${normalizedName ? `-${normalizedName}` : ``}`
+  const instanceId =
+    // instanceId from react table adapter (if it exists) allows for stable devtools registration even if the table instance changes
+    (table as { instanceId?: string } | undefined)?.instanceId ??
+    `${registrationId}${normalizedName ? `-${normalizedName}` : ``}`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const instanceId =
// instanceId from react table adapter (if it exists) allows for stable devtools registration even if the table instance changes
(table as unknown as { instanceId?: string }).instanceId ||
`${registrationId}${normalizedName ? `-${normalizedName}` : ``}`
const instanceId =
// instanceId from react table adapter (if it exists) allows for stable devtools registration even if the table instance changes
(table as { instanceId?: string } | undefined)?.instanceId ??
`${registrationId}${normalizedName ? `-${normalizedName}` : ``}`
🤖 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 `@packages/react-table-devtools/src/useTanStackTableDevtools.ts` around lines
31 - 34, The computed instanceId is evaluated unguarded and can throw when table
is undefined, and normalizedName changes are not propagated because it isn’t in
the effect dependencies; inside useTanStackTableDevtools (function name) move
the computation of instanceId into the useEffect that guards on table (or guard
before accessing (table as ...).instanceId) and add normalizedName to the effect
dependency array so instanceId is recomputed when name changes; ensure the
upsertTableDevtoolsTarget call uses the locally computed instanceId and the
current normalizedName so updates propagate correctly.

Comment on lines +38 to +54
useEffect(() => {
if (!enabled || !table) {
removeTableDevtoolsTarget(registrationId)
removeTableDevtoolsTarget(instanceId)
return
}

upsertTableDevtoolsTarget({
id: registrationId,
id: instanceId,
table,
name: normalizeName(name),
name: normalizedName,
})

return () => {
removeTableDevtoolsTarget(registrationId)
removeTableDevtoolsTarget(instanceId)
}
}, [enabled, name, registrationId, table])
// eslint-disable-next-line @eslint-react/exhaustive-deps,react-hooks/exhaustive-deps
}, [enabled, registrationId, instanceId])
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/react-table-devtools/src/useTanStackTableDevtools.ts"

echo "=== File header (imports/exports) ==="
sed -n '1,120p' "$FILE" | nl -ba

echo "=== Target effect region (lines ~30-80) ==="
sed -n '1,120p' "$FILE" | nl -ba | sed -n '25,90p'

echo "=== Search for normalizedName definition/usages ==="
rg -n "normalizedName" "$FILE" || true

echo "=== Locate upsertTableDevtoolsTarget/removeTableDevtoolsTarget implementations ==="
rg -n "function upsertTableDevtoolsTarget|upsertTableDevtoolsTarget\\(|removeTableDevtoolsTarget\\(" packages/react-table-devtools -S

# Also search whole repo in case helpers live elsewhere
rg -n "upsertTableDevtoolsTarget\\(|removeTableDevtoolsTarget\\(" -S

Repository: TanStack/table

Length of output: 157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/react-table-devtools/src/useTanStackTableDevtools.ts"

echo "=== Show lines 1-140 with line numbers (python) ==="
python3 - <<'PY'
path = "packages/react-table-devtools/src/useTanStackTableDevtools.ts"
with open(path, "r", encoding="utf-8") as f:
    for i, line in enumerate(f, 1):
        if i <= 140:
            print(f"{i:4d}: {line.rstrip()}")
PY

echo "=== Search normalizedName definition/usages ==="
rg -n "normalizedName" "$FILE" || true

echo "=== Search for upsert/remove helpers ==="
rg -n "upsertTableDevtoolsTarget\\(|removeTableDevtoolsTarget\\(" -S packages/react-table-devtools || true
rg -n "upsertTableDevtoolsTarget\\(|removeTableDevtoolsTarget\\(" -S . || true

Repository: TanStack/table

Length of output: 6144


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/table-devtools/src/tableTarget.ts"
python3 - <<'PY'
path = "packages/table-devtools/src/tableTarget.ts"
with open(path, "r", encoding="utf-8") as f:
    for i, line in enumerate(f, 1):
        if i <= 200:
            print(f"{i:4d}: {line.rstrip()}")
PY

echo "=== Search for 'name' usage inside tableTarget.ts ==="
rg -n "name\\b" packages/table-devtools/src/tableTarget.ts

Repository: TanStack/table

Length of output: 3057


Add normalizedName to the effect deps so devtools target name updates when adapter instanceId is stable.

normalizedName is sent to upsertTableDevtoolsTarget, but it isn’t in the useEffect deps; when the adapter provides a stable instanceId, changing name won’t rerun the effect, so existingRegistration.name won’t be updated.

♻️ Suggested fix
-  }, [enabled, registrationId, instanceId])
+  }, [enabled, registrationId, instanceId, normalizedName])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
if (!enabled || !table) {
removeTableDevtoolsTarget(registrationId)
removeTableDevtoolsTarget(instanceId)
return
}
upsertTableDevtoolsTarget({
id: registrationId,
id: instanceId,
table,
name: normalizeName(name),
name: normalizedName,
})
return () => {
removeTableDevtoolsTarget(registrationId)
removeTableDevtoolsTarget(instanceId)
}
}, [enabled, name, registrationId, table])
// eslint-disable-next-line @eslint-react/exhaustive-deps,react-hooks/exhaustive-deps
}, [enabled, registrationId, instanceId])
useEffect(() => {
if (!enabled || !table) {
removeTableDevtoolsTarget(instanceId)
return
}
upsertTableDevtoolsTarget({
id: instanceId,
table,
name: normalizedName,
})
return () => {
removeTableDevtoolsTarget(instanceId)
}
// eslint-disable-next-line `@eslint-react/exhaustive-deps`,react-hooks/exhaustive-deps
}, [enabled, registrationId, instanceId, normalizedName])
🤖 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 `@packages/react-table-devtools/src/useTanStackTableDevtools.ts` around lines
38 - 54, The effect that registers the devtools target (useEffect) omits
normalizedName from its dependency array, so changes to name won't trigger
upsertTableDevtoolsTarget when instanceId is stable; update the dependency list
for the useEffect that calls upsertTableDevtoolsTarget/removeTableDevtoolsTarget
to include normalizedName alongside enabled, registrationId, and instanceId so
the effect reruns and existingRegistration.name is updated when normalizedName
changes.

Comment on lines +145 to +150
const instanceIdRef = useRef<string | undefined>(undefined)
if (!instanceIdRef.current) {
instanceIdRef.current =
'randomUUID' in globalThis.crypto
? globalThis.crypto.randomUUID()
: `table-${++tableId}`
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the file and print the relevant region with line numbers
FILE="packages/react-table/src/useTable.ts"
if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE" >&2
  exit 1
fi

echo "---- $FILE (lines ~120-180) ----"
nl -ba "$FILE" | sed -n '120,190p'

# Search for other uses/guards of globalThis.crypto / randomUUID in the codebase
echo "---- Search: globalThis.crypto / randomUUID ----"
rg -n "globalThis\.crypto|randomUUID" packages/react-table/src || true

# Check whether there's any polyfill/assumption about globalThis.crypto earlier in repo
echo "---- Search: randomUUID in repo (small scope) ----"
rg -n "randomUUID" packages/react-table || true

Repository: TanStack/table

Length of output: 184


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/react-table/src/useTable.ts"
if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE" >&2
  exit 1
fi

python3 - <<'PY'
from pathlib import Path
path = Path("packages/react-table/src/useTable.ts")
lines = path.read_text(encoding="utf-8").splitlines()
start, end = 120, 190  # 1-based line numbers
for i in range(start, min(end, len(lines)) + 1):
    print(f"{i:4d}\t{lines[i-1]}")
PY

echo "---- Search: globalThis.crypto / randomUUID ----"
rg -n "globalThis\.crypto|randomUUID" packages/react-table/src || true

echo "---- Search: crypto polyfills / globalThis assumptions (small scope) ----"
rg -n "globalThis|crypto" packages/react-table || true

Repository: TanStack/table

Length of output: 2655


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Search entire repo for globalThis.crypto / randomUUID ----"
rg -n "globalThis\.crypto|randomUUID" . || true

echo "---- Search for crypto polyfills or globalThis assignments ----"
rg -n "polyfill|crypto\.randomUUID|require\\('crypto'\\)|globalThis\\.(crypto|msCrypto)" . || true

echo "---- Search for checks like 'crypto' in globalThis ----"
rg -n "'crypto' in globalThis|globalThis\\.crypto\\s*\\?|typeof globalThis\\.crypto" . || true

Repository: TanStack/table

Length of output: 4887


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show root package engines / browserslist (if any)
ls -la package.json >/dev/null 2>&1 && cat package.json || true
echo "----"
for f in packages/*/package.json packages/react-table/package.json; do
  if [ -f "$f" ]; then echo "## $f"; cat "$f"; fi
done

echo "---- Search for browserslist / engines ----"
rg -n "\"browserslist\"|browserslist|\"engines\"" -S . || true

Repository: TanStack/table

Length of output: 34086


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- Search for useTable usage in react-table package ----"
rg -n "useTable\\(" packages/react-table || true

echo "---- Search for react-table test setup (jsdom/node) ----"
rg -n "jsdom|testEnvironment|vitest.*environment|environment:" packages/react-table packages/table-core packages/react-table-devtools || true

echo "---- Search README for SSR / crypto assumptions ----"
for f in packages/react-table/README.md packages/react-table-devtools/README.md README.md; do
  if [ -f "$f" ]; then
    echo "## $f"
    rg -n "SSR|server|hydrate|crypto|randomUUID" "$f" || true
  fi
done

Repository: TanStack/table

Length of output: 10044


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- packages/react-table/vite.config.ts ----"
cat packages/react-table/vite.config.ts

echo "---- packages/react-table-devtools/vite.config.ts ----"
cat packages/react-table-devtools/vite.config.ts 2>/dev/null || true

echo "---- packages/table-core/vite.config.ts ----"
cat packages/table-core/vite.config.ts 2>/dev/null || true

echo "---- Search for vitest config in react-table ----"
rg -n "vitest|environment\\s*:\\s*'jsdom'|test\\s*:\\s*\\{|jsdom" packages/react-table -S || true

echo "---- Search for SSR notes in useTable docs/comments ----"
rg -n "server-side|SSR|hydrate|globalThis" packages/react-table/src -S || true

Repository: TanStack/table

Length of output: 1668


🏁 Script executed:

node -p "({ crypto: typeof globalThis.crypto, randomUUID: typeof globalThis.crypto?.randomUUID })"

Repository: TanStack/table

Length of output: 103


🌐 Web query:

Node 16 globalThis.crypto availability webcrypto experimental global webcrypto

💡 Result:

In Node.js 16, Web Crypto is available via the Web Crypto API implementation, but it is not exposed as globalThis.crypto; you should use require('node:crypto').webcrypto (CommonJS) or import { webcrypto } from 'node:crypto' (ESM) instead.[1][2] What to do in Node 16: 1) CommonJS const { webcrypto } = require('node:crypto'); const { subtle } = webcrypto; 2) ESM import { webcrypto } from 'node:crypto'; const { subtle } = webcrypto; For contrast: current Node.js docs (e.g., newer versions) describe accessing the same Web Crypto API via globalThis.crypto or require('node:crypto').webcrypto.[3][4] Notes: - Node’s Web Crypto API is implemented as the standard Web Crypto API, with globalThis.crypto being an instance of the Crypto singleton in environments where it’s available.[3][4]

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "globalThis\\.crypto|randomUUID" packages/react-table/src || true

Repository: TanStack/table

Length of output: 221


Guard globalThis.crypto before probing randomUUID.

'randomUUID' in globalThis.crypto throws a TypeError when globalThis.crypto is missing (possible in Node 16 SSR/server runtimes since @tanstack/react-table supports node >=16). Use a guarded check for randomUUID instead.

🐛 Suggested fix
   if (!instanceIdRef.current) {
-    instanceIdRef.current =
-      'randomUUID' in globalThis.crypto
-        ? globalThis.crypto.randomUUID()
-        : `table-${++tableId}`
+    const cryptoObj = globalThis.crypto
+    instanceIdRef.current =
+      typeof cryptoObj?.randomUUID === 'function'
+        ? cryptoObj.randomUUID()
+        : `table-${++tableId}`
   }
🤖 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 `@packages/react-table/src/useTable.ts` around lines 145 - 150, The current
check "'randomUUID' in globalThis.crypto" can throw if globalThis.crypto is
undefined; update the guard around instanceIdRef initialization (in useTable) to
safely check for crypto and randomUUID — e.g., verify globalThis.crypto exists
and has a randomUUID function (like typeof globalThis.crypto?.randomUUID ===
'function' or 'randomUUID' in (globalThis.crypto || {})) before calling it,
falling back to the `table-${++tableId}` path if not available; reference
instanceIdRef, useRef, globalThis.crypto.randomUUID and tableId when making the
change.

Comment on lines +52 to 65
<Show when={tableOptions().length > 0 && tableOptions()}>
{(tableOptions) => (
<Show when={selectedTargetId() ?? EMPTY_PANEL_KEY}>
{(selectedTargetId) => (
<Select
label="Table"
options={tableOptions()}
value={selectedTargetId()}
onChange={(value) => setSelectedTargetId(value)}
/>
)}
</Show>
)}
</Show>
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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Render prop parameters are values, not functions.

Solid's Show render prop receives the resolved value, not an accessor function. Lines 58-59 incorrectly call the render prop parameters as functions:

  • Line 53: (tableOptions) receives the array returned by tableOptions()
  • Line 58: options={tableOptions()} attempts to call that array as a function ❌
  • Line 55: (selectedTargetId) receives the string/value
  • Line 59: value={selectedTargetId()} attempts to call that value as a function ❌

This will cause a TypeError: ... is not a function at runtime.

🐛 Proposed fix
         <Show when={tableOptions().length > 0 && tableOptions()}>
           {(tableOptions) => (
             <Show when={selectedTargetId() ?? EMPTY_PANEL_KEY}>
               {(selectedTargetId) => (
                 <Select
                   label="Table"
-                  options={tableOptions()}
-                  value={selectedTargetId()}
+                  options={tableOptions}
+                  value={selectedTargetId}
                   onChange={(value) => setSelectedTargetId(value)}
                 />
               )}
             </Show>
           )}
         </Show>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Show when={tableOptions().length > 0 && tableOptions()}>
{(tableOptions) => (
<Show when={selectedTargetId() ?? EMPTY_PANEL_KEY}>
{(selectedTargetId) => (
<Select
label="Table"
options={tableOptions()}
value={selectedTargetId()}
onChange={(value) => setSelectedTargetId(value)}
/>
)}
</Show>
)}
</Show>
<Show when={tableOptions().length > 0 && tableOptions()}>
{(tableOptions) => (
<Show when={selectedTargetId() ?? EMPTY_PANEL_KEY}>
{(selectedTargetId) => (
<Select
label="Table"
options={tableOptions}
value={selectedTargetId}
onChange={(value) => setSelectedTargetId(value)}
/>
)}
</Show>
)}
</Show>
🤖 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 `@packages/table-devtools/src/components/Shell.tsx` around lines 52 - 65, The
render-prop parameters passed into Solid's Show are already resolved values, not
accessors—fix the JSX in the Show children to treat the parameters as values:
when destructuring the first Show use the value (e.g., tableOptions) as the
options prop (options={tableOptions}), and in the inner Show use the value
(e.g., selectedTargetId) as the Select value (value={selectedTargetId}) and call
setSelectedTargetId from the onChange handler; ensure you still call the
accessors tableOptions() and selectedTargetId() only where you intend to read
the signals directly, and reference Show, tableOptions, selectedTargetId,
setSelectedTargetId, Select, and EMPTY_PANEL_KEY to locate the incorrect props.

mark table.store as deprecated in adapter table types
replace table.store.state with table.state in examples
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@packages/angular-table/src/injectTable.ts`:
- Around line 37-40: Update the deprecation JSDoc so the second sentence refers
to table.store.state (not table.state); specifically change the phrase
"table.state is a current-value snapshot and is easy to misuse in render code"
to reference "table.store.state is a current-value snapshot and is easy to
misuse in render code" so IntelliSense and the docs point to the correct API
(symbols: table.state, table.store.state, table.atoms).
- Around line 125-128: The getter defined with Object.defineProperty(table,
'state', ...) is self-recursive (it returns table.state) and causes infinite
recursion; replace it so the getter returns a backing value instead of calling
table.state — e.g. capture the real state in a local/backing variable or a
symbol (e.g., stateBacking or STATE_SYMBOL) and have the getter return that
backing value (and the setter update it if needed), or remove the custom getter
entirely and expose the existing state property directly; update references to
use the backing name if you introduce one.

In `@packages/react-table/skills/react/migrate-v8-to-v9/SKILL.md`:
- Line 9: The migration text contains a duplicated phrase "table.state" in the
list "`table.getState()` → `table.state` / `table.state` /
`table.atoms.X.get()`"; edit the sentence in SKILL.md to remove the duplicate so
it reads "`table.getState()` → `table.state` / `table.atoms.X.get()`", and make
the same change at the other occurrence referenced (around the second mention
noted in the comment).

In `@packages/vue-table/src/useTable.ts`:
- Around line 160-165: The mergedOptions build is currently spreading
tableOptions._features directly which will spread the ref/computed wrapper
instead of the inner feature map; change the spread to use the unwrapped value
(e.g., ...(unref(tableOptions._features) || {})) so that mergeProxy receives the
actual feature objects; ensure unref is imported from 'vue' and keep the
existing vueReactivity() and type cast (symbols: mergedOptions, tableOptions,
_features, mergeProxy, vueReactivity).
🪄 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

Run ID: e20f3ba9-5e0d-4ed0-9d49-81e14e9f2713

📥 Commits

Reviewing files that changed from the base of the PR and between 8a240a5 and 403a782.

📒 Files selected for processing (115)
  • examples/angular/column-ordering/src/app/app.ts
  • examples/angular/column-pinning-sticky/src/app/app.ts
  • examples/angular/column-pinning/src/app/app.ts
  • examples/angular/column-visibility/src/app/app.ts
  • examples/angular/composable-tables/src/app/components/table-components.ts
  • examples/angular/editable/src/app/app.html
  • examples/angular/expanding/src/app/app.html
  • examples/angular/filters/src/app/app.html
  • examples/angular/grouping/src/app/app.html
  • examples/angular/kitchen-sink/src/app/app.html
  • examples/angular/kitchen-sink/src/app/app.ts
  • examples/angular/remote-data/src/app/app.html
  • examples/angular/row-selection-signal/src/app/app.component.html
  • examples/angular/signal-input/src/app/person-table/person-table.html
  • examples/lit/column-resizing/src/main.ts
  • examples/preact/column-resizing-performant/src/main.tsx
  • examples/preact/column-resizing/src/main.tsx
  • examples/preact/column-sizing/src/main.tsx
  • examples/preact/custom-plugin/src/main.tsx
  • examples/preact/filters-fuzzy/src/main.tsx
  • examples/preact/row-pinning/src/main.tsx
  • examples/react/column-dnd/src/main.tsx
  • examples/react/column-resizing-performant/src/main.tsx
  • examples/react/column-resizing/src/main.tsx
  • examples/react/column-sizing/src/main.tsx
  • examples/react/custom-plugin/src/main.tsx
  • examples/react/filters-fuzzy/src/main.tsx
  • examples/react/kitchen-sink-hero-ui/src/lib/data-table.ts
  • examples/react/kitchen-sink-hero-ui/src/main.tsx
  • examples/react/kitchen-sink-mantine/src/lib/data-table.ts
  • examples/react/kitchen-sink-mantine/src/main.tsx
  • examples/react/kitchen-sink-material-ui/src/lib/data-table.ts
  • examples/react/kitchen-sink-material-ui/src/main.tsx
  • examples/react/kitchen-sink-react-aria/src/lib/data-table.ts
  • examples/react/kitchen-sink-react-aria/src/main.tsx
  • examples/react/kitchen-sink-shadcn-base/src/components/data-table/data-table-pagination.tsx
  • examples/react/kitchen-sink-shadcn-base/src/lib/data-table.ts
  • examples/react/kitchen-sink-shadcn-base/src/main.tsx
  • examples/react/kitchen-sink-shadcn-radix/src/components/data-table/data-table-pagination.tsx
  • examples/react/kitchen-sink-shadcn-radix/src/lib/data-table.ts
  • examples/react/kitchen-sink-shadcn-radix/src/main.tsx
  • examples/react/kitchen-sink/src/main.tsx
  • examples/react/row-pinning/src/main.tsx
  • examples/react/virtualized-columns-experimental/src/main.tsx
  • examples/react/virtualized-rows-experimental/src/main.tsx
  • examples/react/with-tanstack-router/src/components/table.tsx
  • examples/solid/column-ordering/src/App.tsx
  • examples/solid/column-pinning-split/src/App.tsx
  • examples/solid/column-pinning-sticky/src/App.tsx
  • examples/solid/column-pinning/src/App.tsx
  • examples/solid/column-resizing-performant/src/App.tsx
  • examples/solid/column-resizing/src/App.tsx
  • examples/solid/column-sizing/src/App.tsx
  • examples/solid/column-visibility/src/App.tsx
  • examples/solid/composable-tables/src/components/table-components.tsx
  • examples/solid/expanding/src/App.tsx
  • examples/solid/filters-faceted/src/App.tsx
  • examples/solid/filters-fuzzy/src/App.tsx
  • examples/solid/filters/src/App.tsx
  • examples/solid/grouping/src/App.tsx
  • examples/solid/kitchen-sink/src/App.tsx
  • examples/solid/pagination/src/App.tsx
  • examples/solid/row-pinning/src/App.tsx
  • examples/solid/row-selection/README.md
  • examples/solid/row-selection/src/App.tsx
  • examples/solid/sorting/src/App.tsx
  • examples/solid/virtualized-rows/src/App.tsx
  • examples/solid/with-tanstack-form/src/App.tsx
  • examples/solid/with-tanstack-router/src/components/table.tsx
  • examples/svelte/basic-app-table/src/App.svelte
  • examples/svelte/column-ordering/src/App.svelte
  • examples/svelte/column-pinning/src/App.svelte
  • examples/svelte/column-resizing-performant/src/App.svelte
  • examples/svelte/column-resizing/src/App.svelte
  • examples/svelte/column-sizing/src/App.svelte
  • examples/svelte/column-visibility/src/App.svelte
  • examples/svelte/composable-tables/src/components/PaginationControls.svelte
  • examples/svelte/composable-tables/src/components/ProductsTable.svelte
  • examples/svelte/composable-tables/src/components/UsersTable.svelte
  • examples/svelte/filters-fuzzy/src/App.svelte
  • examples/vue/column-visibility/src/App.tsx
  • examples/vue/expanding/src/App.tsx
  • packages/angular-table/skills/angular/compose-with-tanstack-store/SKILL.md
  • packages/angular-table/skills/angular/migrate-v8-to-v9/SKILL.md
  • packages/angular-table/skills/angular/production-readiness/SKILL.md
  • packages/angular-table/skills/angular/table-state/SKILL.md
  • packages/angular-table/src/injectTable.ts
  • packages/lit-table/skills/lit/lit-table-controller/SKILL.md
  • packages/lit-table/skills/lit/table-state/SKILL.md
  • packages/lit-table/src/TableController.ts
  • packages/preact-table/skills/preact/getting-started/SKILL.md
  • packages/preact-table/skills/preact/table-state/SKILL.md
  • packages/preact-table/src/useTable.ts
  • packages/react-table/skills/react/compose-with-tanstack-store/SKILL.md
  • packages/react-table/skills/react/migrate-v8-to-v9/SKILL.md
  • packages/react-table/skills/react/production-readiness/SKILL.md
  • packages/react-table/skills/react/table-state/SKILL.md
  • packages/react-table/src/useLegacyTable.ts
  • packages/react-table/src/useTable.ts
  • packages/solid-table/skills/solid/production-readiness/SKILL.md
  • packages/solid-table/skills/solid/table-state/SKILL.md
  • packages/solid-table/src/createTable.ts
  • packages/solid-table/src/reactivity.ts
  • packages/solid-table/tests/unit/reactivity.test.ts
  • packages/svelte-table/skills/svelte/compose-with-tanstack-store/SKILL.md
  • packages/svelte-table/skills/svelte/production-readiness/SKILL.md
  • packages/svelte-table/skills/svelte/table-state/SKILL.md
  • packages/svelte-table/src/createTable.svelte.ts
  • packages/svelte-table/src/reactivity.svelte.ts
  • packages/vue-table/skills/vue/compose-with-tanstack-store/SKILL.md
  • packages/vue-table/skills/vue/migrate-v8-to-v9/SKILL.md
  • packages/vue-table/skills/vue/table-state/SKILL.md
  • packages/vue-table/src/reactivity.ts
  • packages/vue-table/src/useTable.ts
  • packages/vue-table/tests/unit/signals.test.ts
✅ Files skipped from review due to trivial changes (16)
  • packages/svelte-table/skills/svelte/compose-with-tanstack-store/SKILL.md
  • examples/angular/expanding/src/app/app.html
  • examples/solid/row-selection/README.md
  • packages/vue-table/skills/vue/compose-with-tanstack-store/SKILL.md
  • packages/preact-table/skills/preact/table-state/SKILL.md
  • packages/react-table/skills/react/production-readiness/SKILL.md
  • packages/svelte-table/skills/svelte/table-state/SKILL.md
  • packages/angular-table/skills/angular/compose-with-tanstack-store/SKILL.md
  • packages/lit-table/skills/lit/table-state/SKILL.md
  • packages/react-table/skills/react/compose-with-tanstack-store/SKILL.md
  • packages/react-table/skills/react/table-state/SKILL.md
  • packages/preact-table/skills/preact/getting-started/SKILL.md
  • examples/react/row-pinning/src/main.tsx
  • packages/solid-table/skills/solid/production-readiness/SKILL.md
  • packages/react-table/src/useLegacyTable.ts
  • packages/svelte-table/skills/svelte/production-readiness/SKILL.md

Comment on lines +37 to +40
* @deprecated Prefer `table.state` for template/render reads,
* `table.atoms.<slice>.get()` for slice snapshots, or Angular computed values
* around explicit selectors. `table.state` is a current-value snapshot
* and is easy to misuse in render code.
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the deprecated store JSDoc target.

This block tells users to prefer table.state, then says table.state is the snapshot that's easy to misuse. The second sentence should point to table.store.state, otherwise IntelliSense contradicts the API you're introducing.

🤖 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 `@packages/angular-table/src/injectTable.ts` around lines 37 - 40, Update the
deprecation JSDoc so the second sentence refers to table.store.state (not
table.state); specifically change the phrase "table.state is a current-value
snapshot and is easy to misuse in render code" to reference "table.store.state
is a current-value snapshot and is easy to misuse in render code" so
IntelliSense and the docs point to the correct API (symbols: table.state,
table.store.state, table.atoms).

Comment on lines +125 to +128
Object.defineProperty(table, 'state', {
get() {
return table.state
},
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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Avoid the self-recursive state getter.

This getter shadows state on the instance and then returns table.state, so every read immediately recurses back into the same getter. Any template or internal state read will overflow the stack.

🩹 Proposed fix
       Object.defineProperty(table, 'state', {
         get() {
-          return table.state
+          return table.store.state
         },
         configurable: true,
         enumerable: true,
       })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Object.defineProperty(table, 'state', {
get() {
return table.state
},
Object.defineProperty(table, 'state', {
get() {
return table.store.state
},
configurable: true,
enumerable: true,
})
🤖 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 `@packages/angular-table/src/injectTable.ts` around lines 125 - 128, The getter
defined with Object.defineProperty(table, 'state', ...) is self-recursive (it
returns table.state) and causes infinite recursion; replace it so the getter
returns a backing value instead of calling table.state — e.g. capture the real
state in a local/backing variable or a symbol (e.g., stateBacking or
STATE_SYMBOL) and have the getter return that backing value (and the setter
update it if needed), or remove the custom getter entirely and expose the
existing state property directly; update references to use the backing name if
you introduce one.

root `get*RowModel` options → `_rowModels` with factory + *Fns parameter,
`createColumnHelper<TData>` → `createColumnHelper<typeof _features, TData>`,
`table.getState()` → `table.store.state` / `table.state` / `table.atoms.X.get()`,
`table.getState()` → `table.state` / `table.state` / `table.atoms.X.get()`,
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicated table.state wording in migration text.

Two lines currently repeat table.state in a way that reads like a copy/paste mistake and can confuse readers.

✏️ Proposed wording cleanup
-  `table.getState()` → `table.state` / `table.state` / `table.atoms.X.get()`,
+  `table.getState()` → `table.state` / `table.atoms.X.get()`,
...
-`getState` was removed. Use `table.state` for a flat snapshot, `table.state` if you passed a `useTable` selector, or `<table.Subscribe>` for reactive reads.
+`getState` was removed. Use `table.state` for a snapshot (flat by default, selector-shaped if you passed a `useTable` selector), or `<table.Subscribe>` for reactive reads.

Also applies to: 332-332

🤖 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 `@packages/react-table/skills/react/migrate-v8-to-v9/SKILL.md` at line 9, The
migration text contains a duplicated phrase "table.state" in the list
"`table.getState()` → `table.state` / `table.state` / `table.atoms.X.get()`";
edit the sentence in SKILL.md to remove the duplicate so it reads
"`table.getState()` → `table.state` / `table.atoms.X.get()`", and make the same
change at the other occurrence referenced (around the second mention noted in
the comment).

Comment on lines +160 to +165
const mergedOptions = mergeProxy(tableOptions, {
_features: {
coreReativityFeature: vueReactivity(),
...tableOptions._features,
},
}
}) as TableOptionsWithReactiveData<TFeatures, TData>
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Unwrap reactive _features before spreading it into mergedOptions.

mergedOptions currently spreads tableOptions._features directly. If the caller provides _features as a ref/computed, this spread operates on the ref wrapper instead of the underlying feature map, so the subsequent top-level unref pass can’t recover the original features.

🩹 Proposed fix
   const mergedOptions = mergeProxy(tableOptions, {
     _features: {
       coreReativityFeature: vueReactivity(),
-      ...tableOptions._features,
+      ...unref(tableOptions._features),
     },
   }) as TableOptionsWithReactiveData<TFeatures, TData>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const mergedOptions = mergeProxy(tableOptions, {
_features: {
coreReativityFeature: vueReactivity(),
...tableOptions._features,
},
}
}) as TableOptionsWithReactiveData<TFeatures, TData>
const mergedOptions = mergeProxy(tableOptions, {
_features: {
coreReativityFeature: vueReactivity(),
...unref(tableOptions._features),
},
}) as TableOptionsWithReactiveData<TFeatures, TData>
🤖 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 `@packages/vue-table/src/useTable.ts` around lines 160 - 165, The mergedOptions
build is currently spreading tableOptions._features directly which will spread
the ref/computed wrapper instead of the inner feature map; change the spread to
use the unwrapped value (e.g., ...(unref(tableOptions._features) || {})) so that
mergeProxy receives the actual feature objects; ensure unref is imported from
'vue' and keep the existing vueReactivity() and type cast (symbols:
mergedOptions, tableOptions, _features, mergeProxy, vueReactivity).

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@examples/angular/basic-external-atoms/src/app/app.html`:
- Around line 37-40: The button labels currently include raw "<" and ">"
characters which must be escaped in the template to avoid HTML/Angular parsing
issues; update the four button text nodes that call table.setPageIndex(0),
table.previousPage(), table.nextPage(), and
table.setPageIndex(table.getPageCount() - 1) to use HTML entities (e.g. replace
"<<" and "<" with "&lt;&lt;" and "&lt;", and ">" and ">>" with "&gt;" and
"&gt;&gt;") while leaving the (click) handlers and [disabled] bindings
(table.getCanPreviousPage(), table.getCanNextPage(), table.getPageCount())
unchanged.

In `@examples/angular/basic-external-atoms/src/styles.css`:
- Line 9: The CSS rule for the .demo-button selector uses the CSS keyword
currentColor with capital C; update the value to the lowercase keyword
currentcolor to comply with the CSS specification and ensure consistent parsing
(locate the ".demo-button { border: 1px solid currentColor; ..." rule and
replace currentColor with currentcolor).

In `@examples/angular/basic-external-state/src/styles.css`:
- Line 43: The CSS uses the keyword "currentColor" for the border value which
violates the value-keyword-case rule; update the border declaration (the border
property line containing currentColor) to use the lowercase keyword
"currentcolor" so the rule is satisfied.

In `@examples/angular/basic-inject-table/src/app/app.ts`:
- Around line 11-18: The file defines a duplicate type: remove the local "type
Person" declaration in app.ts (the one declared lines 11–18) and rely on the
imported "type { Person } from './makeData'"; ensure any usages in App or other
functions reference the imported Person and update any local references if
needed so the single imported type is used project-wide.
🪄 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

Run ID: b7d54f2c-5609-4d01-86ec-b5d4f1d4d714

📥 Commits

Reviewing files that changed from the base of the PR and between 403a782 and a7e7567.

📒 Files selected for processing (26)
  • examples/angular/basic-app-table/src/app/app.html
  • examples/angular/basic-app-table/src/app/app.ts
  • examples/angular/basic-external-atoms/angular.json
  • examples/angular/basic-external-atoms/package.json
  • examples/angular/basic-external-atoms/src/app/app.config.ts
  • examples/angular/basic-external-atoms/src/app/app.html
  • examples/angular/basic-external-atoms/src/app/app.ts
  • examples/angular/basic-external-atoms/src/app/makeData.ts
  • examples/angular/basic-external-atoms/src/index.html
  • examples/angular/basic-external-atoms/src/main.ts
  • examples/angular/basic-external-atoms/src/styles.css
  • examples/angular/basic-external-atoms/tsconfig.app.json
  • examples/angular/basic-external-atoms/tsconfig.json
  • examples/angular/basic-external-state/angular.json
  • examples/angular/basic-external-state/package.json
  • examples/angular/basic-external-state/src/app/app.config.ts
  • examples/angular/basic-external-state/src/app/app.html
  • examples/angular/basic-external-state/src/app/app.ts
  • examples/angular/basic-external-state/src/app/makeData.ts
  • examples/angular/basic-external-state/src/index.html
  • examples/angular/basic-external-state/src/main.ts
  • examples/angular/basic-external-state/src/styles.css
  • examples/angular/basic-external-state/tsconfig.app.json
  • examples/angular/basic-external-state/tsconfig.json
  • examples/angular/basic-inject-table/src/app/app.html
  • examples/angular/basic-inject-table/src/app/app.ts
✅ Files skipped from review due to trivial changes (9)
  • examples/angular/basic-external-atoms/src/main.ts
  • examples/angular/basic-external-atoms/src/index.html
  • examples/angular/basic-external-atoms/src/app/app.config.ts
  • examples/angular/basic-external-state/src/index.html
  • examples/angular/basic-external-atoms/tsconfig.app.json
  • examples/angular/basic-external-atoms/package.json
  • examples/angular/basic-external-state/tsconfig.app.json
  • examples/angular/basic-external-state/package.json
  • examples/angular/basic-external-state/angular.json

Comment on lines +37 to +40
<button class="demo-button demo-button-sm" (click)="table.setPageIndex(0)" [disabled]="!table.getCanPreviousPage()"><<</button>
<button class="demo-button demo-button-sm" (click)="table.previousPage()" [disabled]="!table.getCanPreviousPage()"><</button>
<button class="demo-button demo-button-sm" (click)="table.nextPage()" [disabled]="!table.getCanNextPage()">></button>
<button class="demo-button demo-button-sm" (click)="table.setPageIndex(table.getPageCount() - 1)" [disabled]="!table.getCanNextPage()">>></button>
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="examples/angular/basic-external-atoms/src/app/app.html"
if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE"
  exit 1
fi

nl -ba "$FILE" | sed -n '30,50p'

Repository: TanStack/table

Length of output: 102


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="examples/angular/basic-external-atoms/src/app/app.html"

if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE"
  exit 1
fi

echo "=== Lines 30-50 (with line numbers) ==="
# Use cat -n (available) to show line numbers
cat -n "$FILE" | sed -n '30,50p'

echo
echo "=== Raw pagination text searches ==="
rg -n --fixed-strings '<<' "$FILE" || true
rg -n --fixed-strings '<' "$FILE" || true
rg -n --fixed-strings '>' "$FILE" || true
rg -n --fixed-strings '>>' "$FILE" || true

Repository: TanStack/table

Length of output: 6700


Escape pagination arrow characters in Angular button text (HTML entities required).

examples/angular/basic-external-atoms/src/app/app.html lines 37-40 contain raw </> characters in button text (<<, <, >, >>). These should be escaped to avoid Angular/HTML parsing/lint issues and to ensure the intended glyphs render.

Proposed fix
-    <button class="demo-button demo-button-sm" (click)="table.setPageIndex(0)" [disabled]="!table.getCanPreviousPage()"><<</button>
-    <button class="demo-button demo-button-sm" (click)="table.previousPage()" [disabled]="!table.getCanPreviousPage()"><</button>
-    <button class="demo-button demo-button-sm" (click)="table.nextPage()" [disabled]="!table.getCanNextPage()">></button>
-    <button class="demo-button demo-button-sm" (click)="table.setPageIndex(table.getPageCount() - 1)" [disabled]="!table.getCanNextPage()">>></button>
+    <button class="demo-button demo-button-sm" (click)="table.setPageIndex(0)" [disabled]="!table.getCanPreviousPage()">&lt;&lt;</button>
+    <button class="demo-button demo-button-sm" (click)="table.previousPage()" [disabled]="!table.getCanPreviousPage()">&lt;</button>
+    <button class="demo-button demo-button-sm" (click)="table.nextPage()" [disabled]="!table.getCanNextPage()">&gt;</button>
+    <button class="demo-button demo-button-sm" (click)="table.setPageIndex(table.getPageCount() - 1)" [disabled]="!table.getCanNextPage()">&gt;&gt;</button>
🧰 Tools
🪛 HTMLHint (1.9.2)

[error] 37-37: Special characters must be escaped : [ < ].

(spec-char-escape)


[error] 37-37: Special characters must be escaped : [ < ].

(spec-char-escape)


[error] 38-38: Special characters must be escaped : [ < ].

(spec-char-escape)


[error] 39-39: Special characters must be escaped : [ > ].

(spec-char-escape)


[error] 40-40: Special characters must be escaped : [ > ].

(spec-char-escape)


[error] 40-40: Special characters must be escaped : [ > ].

(spec-char-escape)

🤖 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/angular/basic-external-atoms/src/app/app.html` around lines 37 - 40,
The button labels currently include raw "<" and ">" characters which must be
escaped in the template to avoid HTML/Angular parsing issues; update the four
button text nodes that call table.setPageIndex(0), table.previousPage(),
table.nextPage(), and table.setPageIndex(table.getPageCount() - 1) to use HTML
entities (e.g. replace "<<" and "<" with "&lt;&lt;" and "&lt;", and ">" and ">>"
with "&gt;" and "&gt;&gt;") while leaving the (click) handlers and [disabled]
bindings (table.getCanPreviousPage(), table.getCanNextPage(),
table.getPageCount()) unchanged.

.spacer-sm { height: 0.5rem; }
.spacer-md { height: 1rem; }
.controls, .inline-controls { display: flex; align-items: center; gap: 0.5rem; }
.demo-button { border: 1px solid currentColor; border-radius: 0.25rem; padding: 0.5rem; }
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use lowercase currentcolor per CSS specification.

CSS keyword values should be lowercase. Change currentColor to currentcolor.

🎨 Proposed fix
-.demo-button { border: 1px solid currentColor; border-radius: 0.25rem; padding: 0.5rem; }
+.demo-button { border: 1px solid currentcolor; border-radius: 0.25rem; padding: 0.5rem; }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.demo-button { border: 1px solid currentColor; border-radius: 0.25rem; padding: 0.5rem; }
.demo-button { border: 1px solid currentcolor; border-radius: 0.25rem; padding: 0.5rem; }
🧰 Tools
🪛 Stylelint (17.11.1)

[error] 9-9: Expected "currentColor" to be "currentcolor" (value-keyword-case)

(value-keyword-case)

🤖 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/angular/basic-external-atoms/src/styles.css` at line 9, The CSS rule
for the .demo-button selector uses the CSS keyword currentColor with capital C;
update the value to the lowercase keyword currentcolor to comply with the CSS
specification and ensure consistent parsing (locate the ".demo-button { border:
1px solid currentColor; ..." rule and replace currentColor with currentcolor).

}

.demo-button {
border: 1px solid currentColor;
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix CSS keyword casing.

CSS keywords should be lowercase. Change "currentColor" to "currentcolor" to comply with the value-keyword-case rule.

🎨 Proposed fix
-  border: 1px solid currentColor;
+  border: 1px solid currentcolor;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
border: 1px solid currentColor;
border: 1px solid currentcolor;
🧰 Tools
🪛 Stylelint (17.11.1)

[error] 43-43: Expected "currentColor" to be "currentcolor" (value-keyword-case)

(value-keyword-case)

🤖 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/angular/basic-external-state/src/styles.css` at line 43, The CSS
uses the keyword "currentColor" for the border value which violates the
value-keyword-case rule; update the border declaration (the border property line
containing currentColor) to use the lowercase keyword "currentcolor" so the rule
is satisfied.

Comment on lines +11 to +18
type Person = {
firstName: string
lastName: string
age: number
visits: number
status: string
progress: number
}
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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="examples/angular/basic-inject-table/src/app/app.ts"

echo "=== app.ts (relevant sections) ==="
if [ -f "$FILE" ]; then
  nl -ba "$FILE" | sed -n '1,120p'
else
  echo "Missing: $FILE"
fi

# Find makeData file and its exports
echo
echo "=== makeData file candidates ==="
# Search for makeData.ts under same folder
find examples/angular/basic-inject-table/src/app -maxdepth 1 -type f -iname "*makeData*" -print || true

# If makeData.ts exists, show it
if [ -f "examples/angular/basic-inject-table/src/app/makeData.ts" ]; then
  echo
  echo "=== makeData.ts (relevant sections) ==="
  nl -ba "examples/angular/basic-inject-table/src/app/makeData.ts" | sed -n '1,200p'
fi

Repository: TanStack/table

Length of output: 154


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="examples/angular/basic-inject-table/src/app/app.ts"

echo "=== ls path checks ==="
ls -la "examples/angular/basic-inject-table/src/app" 2>/dev/null || true
ls -la "examples/angular/basic-inject-table/src/app/app.ts" 2>/dev/null || true

echo
echo "=== app.ts (first 160 lines) ==="
if [ -f "$FILE" ]; then
  # use cat -n instead of nl (nl isn't available)
  cat -n "$FILE" | sed -n '1,160p'
else
  echo "Missing: $FILE"
fi

echo
echo "=== Search for 'makeData' and 'Person' in this example ==="
rg -n --hidden --no-ignore -S "makeData|Person" examples/angular/basic-inject-table/src/app || true

echo
echo "=== makeData.ts (if present) ==="
if [ -f "examples/angular/basic-inject-table/src/app/makeData.ts" ]; then
  cat -n "examples/angular/basic-inject-table/src/app/makeData.ts" | sed -n '1,220p'
else
  echo "Missing: examples/angular/basic-inject-table/src/app/makeData.ts"
fi

Repository: TanStack/table

Length of output: 7613


Fix duplicate Person type definition in app.ts
examples/angular/basic-inject-table/src/app/app.ts imports type { Person } from './makeData' (line 5) and also redeclares type Person locally (lines 11-18), causing a TypeScript “Duplicate identifier 'Person'” compile error.

Proposed fix
-import type { Person } from './makeData'

(Alternative: delete the local type Person and keep the import.)

🤖 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/angular/basic-inject-table/src/app/app.ts` around lines 11 - 18, The
file defines a duplicate type: remove the local "type Person" declaration in
app.ts (the one declared lines 11–18) and rely on the imported "type { Person }
from './makeData'"; ensure any usages in App or other functions reference the
imported Person and update any local references if needed so the single imported
type is used project-wide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants