Skip to content

refactor(plugin-grid): move ObjectGrid's row-height sync, column state and mobile affordances into sibling hooks (slice 7) - #26773

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-70tavg
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-70tavg

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Warren · project thread

Part of #25994 (slice 7 of the move-only split: regions C, D and E. Slices 1 to 6 have landed; slice 8, regions R, U and V, stays on the card and closes it.)

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:把 ObjectGrid.tsx 组件顶部三段代码(行高同步、列状态持久化、下拉刷新与卡片视图断点)原样搬进三个同目录 hook 文件,组件在原位置调用它们。
  • 为什么改:维护者裁决「大文件互踩: 立重构卡把 ObjectView 和 ObjectGrid 拆成小模块。这个可以立卡」;这是第 7 片,文件从 5250 行降到 5160 行,并行卡更少撞在同一文件里。
  • 风险与回滚:纯搬移,无逻辑、命名、渲染变化,hook 调用顺序不变;有问题直接 revert 本 PR 即可。
  • 先看:ui/packages/plugin-grid/src/objectGridColumnState.ts(NON-AUTHOR SURFACE 注释仍紧贴 columnState 种子)、ObjectGrid.tsx 里三处调用、gridNonAuthorKeys.test.tsx 的路径改动。
  • 两分钟验证:pnpm --dir ui exec vitest run packages/plugin-grid/ --maxWorkers=2,预期 253 个文件、2256 个测试全绿,与 main 相同。
  • 需要你做的:无,席位落地。

What changes

Base 5cc31c78 (origin/main). ui/packages/plugin-grid/src/ObjectGrid.tsx is 5250 lines there. This slice moves regions C, D and E of the seam table in #26364, the three adjacent blocks at the top of the component body, verbatim into three custom hooks in new sibling modules:

# Concern New home Inputs Returns
C Row-height sync: the effect that follows a changed schema.rowHeight useObjectGridRowHeightSync in objectGridRowHeight.ts schema, rowHeightMode, setRowHeightMode nothing
D Column-state persistence: columnStorageKey, the columnState seed with its NON-AUTHOR SURFACE comment, the external columnState sync, saveColumnState useObjectGridColumnState in objectGridColumnState.ts schema, onColumnStateChange columnState, saveColumnState
E Pull to refresh and the card-view breakpoint effect useObjectGridMobile in objectGridMobile.ts schema, dataSource, setRefreshKey, setUseCardView pullRef, isRefreshing, pullDistance
  • ObjectGrid calls the three hooks exactly where the blocks stood, in the same order, so the component's hook order does not change. The state the blocks read or set (rowHeightMode, refreshKey, useCardView) stays in the component, and its setters are passed in.
  • Inputs are typed from their source: setters as React's Dispatch of SetStateAction over the state's own type, onColumnStateChange as ObjectGridExternalPaginationProps['onColumnStateChange'], dataSource as DataSource | undefined. No context and no new any; the four (schema as any).columnState reads move as they were.
  • Each hook returns only the names the rest of the component reads. columnStorageKey, setColumnState, externalColumnStateKey and handlePullRefresh have no reader outside their block, so they stay inside the hooks.
  • Imports: usePullToRefresh moves with its only reader; the type ObjectGridColumnState import specifier leaves ObjectGrid.tsx (its only reader moved). The export type { ObjectGridColumnState, … } re-export is untouched, so the package entry and every exported name are unchanged.
  • ObjectGrid.tsx goes from 5250 to 5160 lines. The diff is 307 changed lines in 6 files.

Move-only proof. The multiset of non-blank lines of the base ObjectGrid.tsx equals the new ObjectGrid.tsx plus the three modules. Missing: 1 line, the edited ./objectGridProps import (it only lost the type ObjectGridColumnState specifier). Added: 81 lines, all of them the three module headers and docblocks, their imports, the three hook signatures and parameter types, the two return { … } lists, and in ObjectGrid.tsx the three new imports plus the three calls with their comments.

No open PR touches these files. I checked the 18 open PRs at the claim: only #26556 touches plugin-grid, and only its package.json.

Why

The card's ruling, verbatim: 「大文件互踩: 立重构卡把 ObjectView 和 ObjectGrid 拆成小模块。这个可以立卡」. One move-only slice per PR, per the card's ask 1 to 5 and the hand-off notes on the card.

Tests

One test edit, path-only, forced by the move:

  • ui/packages/plugin-grid/src/__tests__/gridNonAuthorKeys.test.tsx: the control case "and the four keys ruled in objectui#5091 still carry theirs" now reads ObjectGrid.tsx and objectGridColumnState.ts joined, because the NON-AUTHOR SURFACE comment on columnState moved with the seed it documents. The onNavigate: onNavigate ?? schema.onNavigate read and its comment block stay in ObjectGrid.tsx, so the gridLines reads are unchanged. Assertions unchanged; one new path constant, one changed line.

No other test reads the moved lines as source. columnStatePersistence and rowHeightOffSpecBoundary are behavioural and render the real ObjectGrid, so they cover the hooks. I matched every string literal of every tracked test and script against the lines that left ObjectGrid.tsx; the hits outside gridNonAuthorKeys were generic words (innerWidth, JSON.parse, @object-ui/mobile) in behavioural tests or in gates that scan their own surfaces, and all of those ran green below.

Acceptance notes

  • Hook boundaries hide React lint findings, as on slices 4 to 6 (trap 3 of the hand-off). eslint on the four files: 0 errors; warnings 188 before, 189 after. react-hooks/set-state-in-effect on setRowHeightMode is no longer raised, because the rule only knows setters declared by useState in the same function: hidden, not fixed. react-hooks/exhaustive-deps now names setRefreshKey (the pull-to-refresh useCallback) and setUseCardView (the breakpoint effect) as missing dependencies, for the same reason: a setter passed in as a hook parameter is not known to be stable. No dependency array changed. The other messages are the same findings at shifted lines or in the new module.
  • Moved comments still say "saveColumnState below" and "the seed above" inside the new module, where they remain true; they are kept verbatim.
  • The failure message of the re-pointed control case still says "gone from ObjectGrid.tsx"; it is left unchanged so the test edit stays path-only.

Verification

Run on head 02d40dc8:

  • pnpm --dir ui exec vitest run packages/plugin-grid/ --maxWorkers=2 under the verification lock: 253 of 253 files, 2256 of 2256 tests after the move. Before: the same command on base 5cc31c78 (a separate worktree, deps built): 253 of 253 files, 2256 of 2256 tests.
  • The 108 test files outside plugin-grid that read source trees (every ui test that reads files and names plugin-grid or walks the package roots): 108 of 108 files, 3152 of 3152 tests.
  • pnpm --filter @object-ui/plugin-grid type-check exit 0, after turbo run build --filter='@object-ui/plugin-grid^...' (48 of 48 tasks).
  • The Type Check UI job's 17 check:* steps plus type-check:coverage: all exit 0 (check:spec-symbols and check:doc-example-readers included; no new local type shares a spec name, and no single-return wrapper is exported).
  • pnpm --dir ui run check:new-line-citations: 0 new citations.
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 35 derived commands, all exit 0 (pnpm --dir ui exec vitest run scripts/ under the lock: 178 passed and 2 skipped files, 5065 passed and 2 skipped tests); --ran reconciles 35 of 35 (0 NOT-MEASURED, 0 UNRUN); the 18 Type Check UI commands above are recorded as outside the derivation.

Changeset: .changeset/25994-objectgrid-column-state-mobile-hooks.md (patch, @object-ui/plugin-grid).

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (not touched)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; eslint on the touched files reports 0 errors.
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset.
  • 6. packages/spec not touched.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the maintainer quick-read section and the quoted ruling are Chinese by rule).

🤖 Generated with Claude Code

https://claude.ai/code/session_01JQwxbXqCPeUA7ztE9YWKwP


Generated by Claude Code

…e and mobile affordances into sibling hooks

Slice 7 of the move-only ObjectGrid split: regions C, D and E move verbatim
into useObjectGridRowHeightSync, useObjectGridColumnState and
useObjectGridMobile, called where the lines stood.

Claude-Session: https://claude.ai/code/session_01JQwxbXqCPeUA7ztE9YWKwP
Co-authored-by: Claude <noreply@anthropic.com>
…; add the slice changeset

Claude-Session: https://claude.ai/code/session_01JQwxbXqCPeUA7ztE9YWKwP
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

  • 改了什么:ObjectGrid.tsx 里行高同步、列状态持久化、下拉刷新与卡片视图断点三段代码,原样搬进三个同目录 hook 文件(objectGridRowHeight.ts、objectGridColumnState.ts、objectGridMobile.ts),组件在原位置按原顺序调用。
  • 为什么改:执行维护者「大文件互踩: 立重构卡把 ObjectView 和 ObjectGrid 拆成小模块。这个可以立卡」,第 7 片;文件 5250 → 5160 行。
  • 风险与回滚:纯搬移,无逻辑、命名、渲染变化;直接 revert 即可。
  • 先看:objectGridColumnState.ts(NON-AUTHOR SURFACE 注释仍紧贴 columnState 种子)。
  • 两分钟验证:plugin-grid 测试套 253/253 文件、2256/2256 用例前后一致。
  • 需要你做的:无,席位落地。
  • 席位意见:席位独立复算搬移证明——基点删除的非空行全部出现在三个新模块里,唯一差异是 objectGridProps 的 import 少引一个类型(随搬移去了新模块)。

席位核对

ACCEPT · seat domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · head 02d40dc8 · 2026-10-27T15:33Z

  1. Shape: move-only slice 7 (regions C, D, E) of [maintainer] refactor(ui): split ObjectGrid.tsx (7641 lines) into smaller modules, one move-only slice per PR, so concurrent ui cards stop colliding in it #25994, Part of #25994; 6 files, +204/−103; three new sibling hooks called where their lines stood, hook order unchanged; one forced test path edit (gridNonAuthorKeys.test.tsx reads both files); patch changeset in the root .changeset/.
  2. Premise measured: the seat recomputed the move proof on 5cc31c78...02d40dc8: every non-blank line removed from ObjectGrid.tsx is present in the three new modules, except the objectGridProps import line, which drops ObjectGridColumnState (now imported by objectGridColumnState.ts). Lines added to ObjectGrid.tsx are only the three imports, the three hook calls and their pointer comments.
  3. Gates / check-runs: on head 02d40dc8, 43 success · 9 skipped · 0 failed · 0 pending; mergeable_state: clean. Dev's local run: dispatch-gates 35/35 exit 0, --ran 0 NOT-MEASURED; Type Check UI check:* steps exit 0.
  4. Accepted deviations: eslint warnings 188 → 189; setters and refs passed to hooks as params are out of sight of the React lint rules (the body says so: hidden, not fixed), as on slice 6.
  5. Out of scope: none filed. Skills-docs: none — move-only, no metadata-protocol change.
  6. Landing: not Tier H (no governed path), under 3000 changed lines; the seat readies and arms auto-merge. Slice 8 (R + U + V, closes the card) is dispatched after this merges.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 15:35
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 7bdff7e Oct 27, 2026
53 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-70tavg branch October 27, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants