Skip to content

feat(table): harden grouping, tree adapters, exports, and retail demo - #38

Merged
jacksonkasi1 merged 9 commits into
mainfrom
dev
Jul 12, 2026
Merged

jacksonkasi1 merged 9 commits into
mainfrom
dev

Conversation

@jacksonkasi1

@jacksonkasi1 jacksonkasi1 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

Adds production-ready row grouping, static/lazy trees, toolbar placement APIs, secure export handling, and the retail hierarchy demo while preserving existing master-detail and row-selection behavior.

Final fixes

  • requires patched Next.js versions: >=15.5.18 <16 or >=16.2.6, excluding GHSA-gx5p-jg67-6x7h and GHSA-26hh-7cqf-hhc6
  • prevents group rows from selection/actions and prevents interactive cell controls from row clicks
  • preserves cross-page selection and validates exact returned ID sets before export
  • recursively resolves custom static-tree IDs and child containers with cycle/duplicate protection
  • keeps the lazy-tree adapter identity stable and remaps child cache revisions without refetching roots
  • adds sourceKey lifecycle handling: source changes abort root/child requests, clear caches, and issue exactly one fresh root query
  • dynamically reconciles optional lazy-tree queryByIds capability when callbacks are added or removed
  • normalizes lazy-tree IDs, cancels stale requests, supports retry/invalidation, and clears stale URL parameters
  • makes individual, bulk, depth, and imperative grouping callbacks consistent
  • protects CSV cells and headers from formula injection while using standard DOM anchor creation
  • provides deterministic mixed retail sorting, pagination, seed data, and child ordering
  • provisions PostgreSQL integration testing and read-only checkout credentials in CI

Verification evidence

Final head: 60d4c70cb4d185c1b5eb4f981e663c1de4d0d10e

  • bun install — passed; lockfile regenerated
  • bun install --frozen-lockfile — passed
  • bun run typecheck — passed for all workspaces
  • bun run test — passed; table package 108 tests, root suite 530 tests total
  • bun run --filter hono-example test:integration — passed in CI against PostgreSQL 17, 12 tests
  • bun run build — passed for all workspaces in CI
  • git diff --check — passed
  • working tree — clean

Green workflows:

Integration status

CI provisions an isolated PostgreSQL 17 service, creates deterministic retail fixtures, and verifies mixed sorting in both directions, fallback fields, invalid fields, ties, empty results, later pages, and child endpoint ordering. Local integration execution requires a PostgreSQL server through DATABASE_URL.

Remaining manual QA

  • visually confirm keyboard focus and Enter/Space behavior for group, tree, and master-detail controls
  • verify cross-page export against a production adapter implementing queryByIds
  • verify tenant/account switching supplies the documented sourceKey
  • review the Vercel demo preview at desktop and mobile widths

Breaking-risk areas

No intentional breaking API changes. Search changes continue to clear selection; pagination preserves it. Unsupported lazy-tree cross-page exports fail explicitly. Next.js versions affected by the cited security advisories are intentionally no longer accepted.

Do not merge until final human review and manual QA are complete.

* feat(table): add row grouping feature (#32)

- Add RowGroupingAggregation, RowGroupingConfig<T>, OnRowGroupExpandInfo types
- Add rowGrouping, rowGroupingConfig, onRowGroupExpand props to DataTableProps
- Add enableRowGroupingControls to TableConfig (default: true)
- Add expandAllGroups/collapseAllGroups/isRowGroupingActive to TableContext
- Wire getGroupedRowModel + GroupingState into DataTable
- Render collapsible group-header rows with chevron + label + badge
- Support multi-level grouping with depth-based indentation on child rows
- Support per-column aggregation functions (sum/mean/min/max etc.)
- Support custom group cell renderer via renderGroupCell
- Add Expand All / Collapse All toolbar buttons (gated by enableRowGroupingControls)
- Add GroupRowChevron + GroupRowBadge components to expand-icon.tsx
- Add row grouping CSS classes to styles.css (depth-accent borders, badge, chevron anim)
- Fix: getRowCanExpand now always returns true for group rows (was blocking TanStack expand)
- Fix: expanded state init now correctly respects rowGroupingConfig.defaultExpanded
- Fix: renderGroupCell returning null now falls back to default label (was rendering nothing)
- Fix: placeholder cells in group rows render empty <td> (was null, broke column grid)
- Fix: Fragment keys namespaced to prevent group/leaf row ID collision
- Fix: keyboard handler (Space/Enter) works on group rows + unmasked implicit role=row bug
- Fix: isRowGroupingActive reads grouping state (not prop) to stay accurate after setGrouping
- Fix: group label uses meta.label ?? id.replace(/_/g,' ') instead of raw column ID
- Fix: Object.keys(true) guard in onRowGroupExpand effect when expanded=true (expand-all)
- Fix: row model pipeline order documented (Core->Filter->Group->Sort->Page)
- Fix: manualPagination+grouping dev warning to prevent silent group-splitting across pages
- Add row grouping aggregationFns performance note to RowGroupingConfig JSDoc
- Fix: export-utils createElementNS fix (prevents spy infinite recursion in tests)
- Add employees-grouping demo page (3 examples: dept, dept+team, custom renderer)
- Re-export RowGroupingAggregation, RowGroupingConfig, OnRowGroupExpandInfo from index.ts

BREAKING CHANGE: none — all new props are optional, all existing props/methods intact
Tests: 81 passed / 0 failed (5 suites)

* feat(table): add imperative TableGroupingAPI via groupingRef (#32)

Adds advanced depth-level grouping control matching simple-table's v2.1 API surface, built on top of TanStack's row model.

- Add TableGroupingAPI interface to types.ts (expandDepth, collapseDepth, toggleDepth, etc.)
- Add groupingRef prop to DataTableProps to expose imperative handle
- Add depth-level helpers (expandDepth, collapseDepth, toggleDepth, getExpandedDepths, setExpandedDepths) to data-table.tsx
- Add property/depth lookup helpers (getGroupingProperty, getGroupingDepth)
- Expose all new helpers on TableContext for declarative usage
- Update TableCraft employees-grouping demo with ProgrammaticDemo showcasing the new API
- Fix: remove process.env check in use-table-data effect (resolves TS2591 process not found)
- Docs: add TableGroupingAPI to index.ts exports

* fix(table): row grouping review fixes (#32)

- Swap toolbar Expand/Collapse icons (ChevronsUpDown for expand,
  ChevronsDownUp for collapse) — they were inverted
- Gate the rowGrouping+pagination warning on NODE_ENV via globalThis
  so it stays out of production logs (and stops requiring @types/node)
- Stop expandDepth from collapsing other depths when expanded === true:
  return prev unchanged in the boolean case instead of resetting to {}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(table): stabilize groupingRef handle across renders (#32)

The imperative handle effect ran without a dependency array and cleaned
up by nulling the ref. With the empty deps the effect/cleanup pair
fired every render, so any consumer reading `ref.current` between
renders could see `null` for a tick.

- Add a real dep array listing every closure the handle captures
- Drop the cleanup that nulls the ref; parent owns the ref's lifecycle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(table): mitigate CSV formula injection and drop aria-selected on group rows

CSV injection: cell values whose first character is `=`, `+`, `-`, `@`,
`\t`, or `\r` are interpreted as formulas by Excel, Google Sheets, and
LibreOffice when an exported file is opened. Prefix such values with a
single quote so spreadsheet apps treat them as plain text. Headers come
from column metadata and are not user-controlled, so they are left
unchanged.

aria-selected: row-grouping rows are never selectable, so reporting
`aria-selected="false"` on them was misleading to assistive tech. Omit
the attribute on group rows.

Tests: 82 passing (added one for the CSV sanitizer).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(table): add endToolbarContent/endToolbarPlacement for right-side injection

Mirrors the existing startToolbarContent/startToolbarPlacement API so
consumers can inject custom content anywhere in the right toolbar cluster
without shifting any built-in controls.

Slots (EndToolbarPlacement):
  before-grouping  → first on the right (after legacy customToolbarContent)
  after-grouping / before-export → between grouping controls and export
  after-export   / before-view   → between export and view-options
  after-view     / before-settings → between view-options and settings (default)
  after-settings → last (rightmost)

Like startToolbarContent, accepts a ReactNode or a function that receives
ToolbarContext (selection, search, dateRange state).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(demo): add Toolbar Placement demo page in vite-web-example

Adds /toolbar-placement route showcasing all endToolbarContent slots:

- before-export: context-aware Archive/Restore bulk-action buttons that
  appear only when rows are selected (reads ctx.totalSelected + selectedIds)
- after-settings: static Import CSV button in the last/rightmost slot
- before-view: custom category filter chips driving a customFilters on
  the adapter — no search input or URL state
- after-view (default): Delete button disabled when nothing is selected

All four examples use the existing products endpoint from hono-example —
no new seed data or API routes required.

Also includes a slot-map reference strip at the top of the page so
developers can quickly see the full right-cluster order.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(demo): split toolbar demos into Start Slots / End Slots pages

- Add /toolbar-start page: 3 compact examples for startToolbarContent
  - before-search: New Product button
  - after-search: category chips that drive customFilters
  - after-date: Sync button with spinner state

- Rewrite /toolbar-placement (end slots): same 4 examples, drastically
  less description text — one-liner label + badge per section

- Nav: change flat "Toolbar" link to a group dropdown with
  "Start Slots" and "End Slots"

No new API routes or seed data needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(demo): add Archived toggle next to search on Products page

Uses startToolbarPlacement="after-search" + startToolbarContent to place
an Archive toggle button immediately after the search input. When active
it drives customFilters={isArchived: eq true} on the adapter so only
archived products are fetched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(table): add lazy-tree support — getSubRows, onRowExpand, keepPreviousData

- Add `getSubRows` prop so TanStack renders hierarchical data with depth
  indentation and a chevron on the first data cell of expandable rows
- Add `onRowExpand` callback (fires on expand/collapse of non-grouped rows)
  for lazy-loading children on first expand
- Add `keepPreviousData` config flag to skip skeleton flash when the adapter
  is recreated to push fresh tree data
- Add `flattenTree` helper so export and selection count traverse all loaded
  child nodes, not just top-level adapter rows
- Stop propagation on system-column (select/expand/actions) clicks so
  checking a checkbox no longer toggles row expansion
- Clear `rowSelection` on page change, page-size change, and search change
  to prevent stale cross-page selection accumulation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(hono): add retail tree DB schema, REST API, and seed script

- Add retailRegions / retailStores / retailProducts tables with Drizzle ORM
- GET /api/manual/retail/tree — paginated regions (tree mode) or full-text
  deep search across all three levels with breadcrumb field (search mode)
- GET /api/manual/retail/tree/:id/children — lazy-loads stores for a region
  or products for a store, both with sort support
- seed-retail.ts seeds 60 regions, 139 stores, 417 products (6+ pages at
  default page size of 10)
- Add seed:retail script to package.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web): add server-side lazy tree example (Regions → Stores → Products)

- New /row-grouping/server page using DataTable with server-side search,
  sort, pagination, and on-demand child loading via onRowExpand
- mergeChildren recursively reattaches cached children so multi-level
  expansion works correctly after adapter version bumps
- Breadcrumb subtitle shown in Name cell for flat deep-search results
- Restructure /row-grouping into a layout with Basic (static) and Server tabs
- Add explicit column definitions to EmployeesGroupingPage so group rows
  render the value directly without the stale column-label prefix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: ignore graphify-out dir and update bun lockfile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(table): add useTreeAdapter hook — lazy server-side tree in one call

Encapsulates all lazy-tree boilerplate (childrenRef, version re-memo,
mergeChildren walk, loading placeholder, expand handler, per-node abort,
dedupe, depth-cap cycle guard, unmount cleanup) into a single reusable
hook so pages only declare what's unique to their data.

server.tsx drops from 226 → 154 lines with no functional change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(hono): simplify retail tree route with engine utilities

- Use engine's parseRequest for validated page/pageSize/search parsing
- Consolidate 3 sort maps into a single SORT namespace
- Extract order() helper (sort-column lookup + direction in one call)
- Extract pageMeta() to eliminate repeated meta object construction
- Extract parseParams() to centralise URL extraction across both endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(hono): remove as const from SORT map to avoid IDE type inference issue

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update README.md

* chore: update lockfile with redis optional peers

* fix(web): satisfy eslint react-hooks and react-refresh rules

- Move `cn` helper from LiquidCard.tsx into lib/utils.ts (shadcn convention)
  so LiquidCard only exports a component, satisfying react-refresh.
- Drop the synchronous handleMouseMove() call from the Presentation mount
  effect — the controls already default to visible, so just schedule the
  auto-hide timer to avoid cascading renders (react-hooks/set-state-in-effect).

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: jacksonnkasi <jacksonnkasi@jacksonnkasis-MacBook-Pro.local>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @jacksonkasi1, your pull request is larger than the review limit of 150000 diff characters

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@jacksonkasi1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ec33922c-2ee8-4fe6-8d85-03c2d4eb60b1

📥 Commits

Reviewing files that changed from the base of the PR and between 60d4c70 and 1aa6317.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • CHANGELOG.md
  • packages/adapter-next/package.json
  • packages/table/package.json
📝 Walkthrough

Walkthrough

Adds a retail hierarchy API and seed data, lazy tree loading, row grouping, toolbar placement demos, CSV formula sanitization, CI, and related adapter, documentation, dependency, and example updates.

Changes

TableCraft feature expansion

Layer / File(s) Summary
Retail schema, seed data, and API
apps/hono-example/src/db/*, apps/hono-example/src/routes/manual/*, apps/hono-example/test/*
Adds retail tables, deterministic seeding, hierarchical endpoints, route registration, Vitest setup, and integration coverage.
Lazy tree loading and cancellation
packages/table/src/auto/*, packages/table/src/types.ts, packages/table/src/core/*, packages/table/test/use-tree-adapter.test.tsx
Adds abort-aware adapter contracts and lazy tree caching, loading rows, invalidation, stale-response protection, and cleanup.
Row grouping and hierarchical rendering
packages/table/src/data-table.tsx, packages/table/src/toolbar.tsx, packages/table/src/types.ts, packages/table/src/styles.css, packages/table/src/expand-icon.tsx
Adds grouping state, aggregation, expansion APIs, tree-aware selection, grouped rendering, toolbar controls, and styles.
Example navigation and feature pages
apps/vite-web-example/src/*, apps/vite-web-example/package.json, apps/vite-web-example/src/data/*
Adds grouped/tree examples, toolbar placement pages, navigation groups, fixtures, and archived-product filtering.
CSV sanitization and export tests
packages/table/src/utils/export-utils.ts, packages/table/test/export-utils.test.ts
Sanitizes formula-like CSV values and expands escaping coverage for headers, tabs, and multiline cells.
Documentation, utilities, package alignment, and CI
docs/*, apps/web/src/*, packages/*/package.json, .github/workflows/ci.yml, .gitignore, README.md
Updates documentation, centralizes cn, adjusts presentation behavior, aligns packages and test commands, adds CI, and updates repository metadata.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DataTable
  participant useTreeAdapter
  participant RetailAPI
  User->>DataTable: Expand region or store
  DataTable->>useTreeAdapter: onRowExpand(id)
  useTreeAdapter->>RetailAPI: Fetch children with AbortSignal
  RetailAPI-->>useTreeAdapter: Return child rows
  useTreeAdapter-->>DataTable: Merge children into tree
  DataTable-->>User: Render expanded rows
Loading

Possibly related PRs

  • jacksonkasi1/TableCraft#36: Overlaps with the retail tree API, lazy tree adapter, row grouping, toolbar placement, and CSV export changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main table-focused changes: grouping, tree adapters, exports, and the retail demo.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

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.

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tablecraft-demo Ready Ready Preview, Comment Jul 12, 2026 4:32am

jacksonnkasi and others added 2 commits July 9, 2026 22:43
…ion, dep CVEs

- plugin-cache: declare ioredis and @upstash/redis as real optional peer
  dependencies (peerDependenciesMeta was inert without matching peer
  entries, leaving bun.lock out of sync with package.json).
- table: thread AbortSignal through DataAdapter.query so useTableData can
  cancel stale requests before they overwrite newer table data; add a
  post-await abort guard in both useTableData and useTreeAdapter so
  adapters that ignore the signal still cannot race newer requests.
- table/export-utils: quote cells containing CR or LF (RFC 4180); trim
  leading whitespace in sanitizeCsvCell so values like ' =SUM(1)' cannot
  bypass the formula-injection prefix check.
- Bump high+critical dep versions: axios >=1.16.0 (ReDoS/MITM/Proxy-Auth
  leak), next >=16.2.5 (DoS/SSRF in peer of @tablecraft/adapter-next),
  hono >=4.12.18 (serveStatic file read), react-router-dom >=7.14.2
  (RCE via turbo-stream in vite-web-example), vite >=6.4.3 (fs.deny
  bypass). vitest already on ^4.1.5 which is above the affected <3.2.6
  range; jsdom already on ^29.1.1 which bundles undici >=7.28.0.

Co-Authored-By: Claude <noreply@anthropic.com>
Includes:
- plugin-cache peer deps fix
- table: AbortSignal threading through DataAdapter
- table/export-utils: CR/LF escaping + leading-whitespace trim
- security dep bumps (axios, next, hono, react-router-dom, vite)

Co-Authored-By: Claude <noreply@anthropic.com>
@jacksonkasi1 jacksonkasi1 changed the title chore(release): dev → main (security audit #35) feat(table): harden grouping, tree adapters, exports, and retail demo Jul 11, 2026

@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: 3

🧹 Nitpick comments (4)
apps/hono-example/src/routes/manual/retail.ts (1)

12-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Wrap the SORT map entries to respect the 100-char line limit.

Lines 13–15 run well beyond 100 columns. Break each whitelist object across multiple lines (one column per line, or grouped) to comply.

As per coding guidelines: "Maintain 100 character maximum line length".

🤖 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 `@apps/hono-example/src/routes/manual/retail.ts` around lines 12 - 16, Reformat
the SORT map entries for region, store, and product so each whitelist object’s
properties are split across multiple lines and every line stays within the
100-character limit. Preserve the existing columns and mappings unchanged.

Source: Coding guidelines

packages/table/test/use-tree-adapter.test.tsx (1)

41-101: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add coverage for dedupe/cycle/depth-limit merge behavior.

mergeChildren in use-tree-adapter.ts filters duplicate child IDs, guards against cycles via ancestors, and caps recursion at maxDepth. None of these are covered by the current three tests.

🤖 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/test/use-tree-adapter.test.tsx` around lines 41 - 101, Add
tests covering the useTreeAdapter mergeChildren behavior for duplicate child
IDs, ancestor-based cycle prevention, and the maxDepth recursion limit.
Construct child data that exercises each case and assert the merged tree
excludes duplicates and cycles while stopping expansion at the configured depth;
keep the existing query, abort, and retry tests unchanged.
packages/table/src/types.ts (1)

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

JSDoc added on new public API surface across three files — violates "Omit JSDoc comments for public APIs." Each new exported type/interface/function in this PR is documented with JSDoc, contrary to the stated repo convention for **/*.{ts,tsx,js,jsx}; the shared fix is to strip or relocate this documentation.

  • packages/table/src/types.ts#L44-L172 (also 220-261, 292-304, 411-426, 612-617, 666-696, 735-777): remove JSDoc from RowGroupingConfig, TableGroupingAPI, TableConfig's new fields, DataAdapter.query, TableContext's grouping members, getSubRows, toolbar-placement props, and the new DataTableProps grouping/tree props.
  • packages/table/src/auto/rest-adapter.ts#L4-L14: remove the JSDoc block above queryFn.
  • packages/table/src/auto/use-tree-adapter.ts#L6-L127: remove JSDoc from makeTreeLoadingId, isTreeLoadingRow, UseTreeAdapterListSource, UseTreeAdapterChildrenSource, UseTreeAdapterOptions, UseTreeAdapterReturn, and useTreeAdapter.
🤖 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/src/types.ts` around lines 44 - 172, Remove the newly added
JSDoc documentation from the public API symbols in
packages/table/src/types.ts#L44-172, 220-261, 292-304, 411-426, 612-617,
666-696, and 735-777, including RowGroupingConfig, TableGroupingAPI, new
TableConfig, DataAdapter.query, TableContext, getSubRows, toolbar-placement, and
DataTableProps grouping/tree members. Also remove the JSDoc above queryFn in
packages/table/src/auto/rest-adapter.ts#L4-14 and from makeTreeLoadingId,
isTreeLoadingRow, the UseTreeAdapter* interfaces, and useTreeAdapter in
packages/table/src/auto/use-tree-adapter.ts#L6-127; preserve the declarations
and implementation unchanged.

Source: Coding guidelines

packages/table/src/core/use-table-data.ts (1)

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

Undeclared effect dependencies lack an eslint-disable comment.

The effect reads result and config.keepPreviousData (line 127) but the dependency array is only [adapter, queryParams] (line 159). Adding them would cause an infinite fetch loop (setResult → effect re-run → refetch), so the omission is deliberate — but unlike the equivalent situation in data-table.tsx (which explicitly adds // eslint-disable-next-line react-hooks/exhaustive-deps before its own intentionally-incomplete deps array), this effect has no such comment, making the intent unclear to readers/lint tooling and risking a react-hooks/exhaustive-deps CI failure.

🔧 Suggested fix
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [adapter, queryParams]);
🤖 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/src/core/use-table-data.ts` around lines 118 - 159, Add an
eslint-disable-next-line react-hooks/exhaustive-deps comment immediately before
the useEffect dependency array in the fetch effect, documenting that result and
config.keepPreviousData are intentionally omitted to avoid refetch loops. Keep
the dependency array as [adapter, queryParams].
🤖 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/adapter-next/package.json`:
- Line 27: Update the Next.js peer dependency range in package.json so the
pre-16 branch starts at the patched 15.5.16 release, excluding vulnerable
versions through 15.5.15 while preserving support for the intended Next.js 14/15
range and the existing >=16.2.5 branch.

In `@packages/table/src/auto/use-tree-adapter.ts`:
- Around line 141-230: Stop using the cache-update version state to recreate the
DataAdapter in the useTreeAdapter adapter useMemo, since bumpVersion currently
causes useTableData to refetch the top-level list. Decouple cached-child refresh
from adapter identity while preserving updated merged children for existing
data, and ensure inline children.fetch, loadingRow, and getRowId callbacks do
not trigger unnecessary list requests.

In `@packages/table/src/utils/export-utils.ts`:
- Around line 81-86: Restore document.createElement("a") in the CSV download
logic, replacing the createElementNS call. Move the nested
document.createElement spy workaround into the export-utils test harness so the
existing a.click stub remains effective without coupling production code to test
behavior.

---

Nitpick comments:
In `@apps/hono-example/src/routes/manual/retail.ts`:
- Around line 12-16: Reformat the SORT map entries for region, store, and
product so each whitelist object’s properties are split across multiple lines
and every line stays within the 100-character limit. Preserve the existing
columns and mappings unchanged.

In `@packages/table/src/core/use-table-data.ts`:
- Around line 118-159: Add an eslint-disable-next-line
react-hooks/exhaustive-deps comment immediately before the useEffect dependency
array in the fetch effect, documenting that result and config.keepPreviousData
are intentionally omitted to avoid refetch loops. Keep the dependency array as
[adapter, queryParams].

In `@packages/table/src/types.ts`:
- Around line 44-172: Remove the newly added JSDoc documentation from the public
API symbols in packages/table/src/types.ts#L44-172, 220-261, 292-304, 411-426,
612-617, 666-696, and 735-777, including RowGroupingConfig, TableGroupingAPI,
new TableConfig, DataAdapter.query, TableContext, getSubRows, toolbar-placement,
and DataTableProps grouping/tree members. Also remove the JSDoc above queryFn in
packages/table/src/auto/rest-adapter.ts#L4-14 and from makeTreeLoadingId,
isTreeLoadingRow, the UseTreeAdapter* interfaces, and useTreeAdapter in
packages/table/src/auto/use-tree-adapter.ts#L6-127; preserve the declarations
and implementation unchanged.

In `@packages/table/test/use-tree-adapter.test.tsx`:
- Around line 41-101: Add tests covering the useTreeAdapter mergeChildren
behavior for duplicate child IDs, ancestor-based cycle prevention, and the
maxDepth recursion limit. Construct child data that exercises each case and
assert the merged tree excludes duplicates and cycles while stopping expansion
at the configured depth; keep the existing query, abort, and retry tests
unchanged.
🪄 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: 23d3cec0-ff89-4554-9b3f-c73ec349b955

📥 Commits

Reviewing files that changed from the base of the PR and between 421c9e9 and b43b7c3.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (44)
  • .gitignore
  • README.md
  • apps/hono-example/package.json
  • apps/hono-example/src/db/schema.ts
  • apps/hono-example/src/db/seed-retail.ts
  • apps/hono-example/src/routes/manual/index.ts
  • apps/hono-example/src/routes/manual/retail.ts
  • apps/sveltekit-example/package.json
  • apps/vite-web-example/eslint.config.js
  • apps/vite-web-example/package.json
  • apps/vite-web-example/src/App.tsx
  • apps/vite-web-example/src/data/employees-grouping.ts
  • apps/vite-web-example/src/data/retail-tree.ts
  • apps/vite-web-example/src/pages/products-page.tsx
  • apps/vite-web-example/src/pages/row-grouping/basic.tsx
  • apps/vite-web-example/src/pages/row-grouping/layout.tsx
  • apps/vite-web-example/src/pages/row-grouping/server.tsx
  • apps/vite-web-example/src/pages/toolbar-placement-page.tsx
  • apps/vite-web-example/src/pages/toolbar-start-page.tsx
  • apps/web/package.json
  • apps/web/src/Presentation.tsx
  • apps/web/src/components/LiquidCard.tsx
  • apps/web/src/lib/utils.ts
  • build_log.txt
  • docs/api-reference.md
  • packages/adapter-hono/package.json
  • packages/adapter-next/package.json
  • packages/client/package.json
  • packages/plugin-cache/package.json
  • packages/table/src/auto/rest-adapter.ts
  • packages/table/src/auto/static-adapter.ts
  • packages/table/src/auto/tablecraft-adapter.ts
  • packages/table/src/auto/use-tree-adapter.ts
  • packages/table/src/core/table-config.ts
  • packages/table/src/core/use-table-data.ts
  • packages/table/src/data-table.tsx
  • packages/table/src/expand-icon.tsx
  • packages/table/src/index.ts
  • packages/table/src/styles.css
  • packages/table/src/toolbar.tsx
  • packages/table/src/types.ts
  • packages/table/src/utils/export-utils.ts
  • packages/table/test/export-utils.test.ts
  • packages/table/test/use-tree-adapter.test.tsx
💤 Files with no reviewable changes (1)
  • build_log.txt

Comment thread packages/adapter-next/package.json Outdated
Comment thread packages/table/src/auto/use-tree-adapter.ts
Comment thread packages/table/src/utils/export-utils.ts Outdated

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/hono-example/package.json (1)

10-27: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Upgrade hono to ^4.12.25 or newer. ^4.12.18 is still affected by a high-severity CORS middleware issue when credentials are enabled.

🤖 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 `@apps/hono-example/package.json` around lines 10 - 27, Update the hono
dependency in the package manifest from ^4.12.18 to ^4.12.25 or newer, leaving
the other dependency declarations unchanged.
🤖 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 @.github/workflows/ci.yml:
- Line 32: Update the actions/checkout@v4 step to set persist-credentials to
false, preventing the GITHUB_TOKEN from being stored in the local Git
configuration while preserving the existing checkout behavior.

In `@apps/hono-example/test/retail.integration.test.ts`:
- Around line 19-22: Update the RetailResponse interface’s meta property to
declare the page and pageSize numeric fields alongside total and totalPages,
matching the response shape asserted by the retail integration test.

In `@packages/adapter-next/package.json`:
- Around line 22-27: Update the next peer dependency range in package.json to
exclude vulnerable releases: use >=15.5.18 <16 or >=16.2.6, while preserving the
existing version-range structure.

---

Outside diff comments:
In `@apps/hono-example/package.json`:
- Around line 10-27: Update the hono dependency in the package manifest from
^4.12.18 to ^4.12.25 or newer, leaving the other dependency declarations
unchanged.
🪄 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: 31585539-5c48-43ad-979a-3bd8afad84dc

📥 Commits

Reviewing files that changed from the base of the PR and between b43b7c3 and 4638116.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (34)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • apps/hono-example/package.json
  • apps/hono-example/src/db/index.ts
  • apps/hono-example/src/routes/manual/retail.ts
  • apps/hono-example/test/retail.integration.test.ts
  • apps/hono-example/vitest.config.ts
  • apps/sveltekit-example/package.json
  • docs/api-reference.md
  • docs/packages.md
  • package.json
  • packages/adapter-elysia/package.json
  • packages/adapter-express/package.json
  • packages/adapter-hono/package.json
  • packages/adapter-next/README.md
  • packages/adapter-next/package.json
  • packages/adapter-sveltekit/package.json
  • packages/client/package.json
  • packages/codegen/package.json
  • packages/engine/package.json
  • packages/plugin-cache/package.json
  • packages/table/package.json
  • packages/table/src/auto/static-adapter.ts
  • packages/table/src/auto/use-tree-adapter.ts
  • packages/table/src/core/use-table-data.ts
  • packages/table/src/data-table.tsx
  • packages/table/src/expand-icon.tsx
  • packages/table/src/types.ts
  • packages/table/src/utils/export-utils.ts
  • packages/table/test/data-table-regressions.test.tsx
  • packages/table/test/expand-icon.test.tsx
  • packages/table/test/export-utils.test.ts
  • packages/table/test/static-adapter.test.ts
  • packages/table/test/use-tree-adapter.test.tsx
✅ Files skipped from review due to trivial changes (8)
  • packages/adapter-elysia/package.json
  • apps/hono-example/vitest.config.ts
  • packages/table/test/expand-icon.test.tsx
  • docs/packages.md
  • CHANGELOG.md
  • packages/engine/package.json
  • packages/adapter-next/README.md
  • docs/api-reference.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/client/package.json
  • packages/table/src/core/use-table-data.ts
  • packages/table/test/export-utils.test.ts
  • packages/adapter-hono/package.json
  • packages/plugin-cache/package.json
  • apps/hono-example/src/routes/manual/retail.ts
  • packages/table/src/data-table.tsx
  • packages/table/src/types.ts

Comment thread .github/workflows/ci.yml
Comment thread apps/hono-example/test/retail.integration.test.ts
Comment thread packages/adapter-next/package.json Outdated
jacksonnkasi and others added 2 commits July 12, 2026 09:13
- Bump @tablecraft/table to 0.2.27 (grouping, tree adapters, exports)
- Bump @tablecraft/adapter-next to 0.1.7 (Next.js peer dep floors)
- Add 0.2.27 release entry to CHANGELOG.md covering PR #38

Co-Authored-By: Claude <noreply@anthropic.com>
@jacksonkasi1
jacksonkasi1 merged commit 7bac786 into main Jul 12, 2026
10 checks passed
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