You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7bdff7e
Browse filesBrowse the repository at this point in the historyBrowse files
refactor(plugin-grid): move ObjectGrid's row-height sync, column state and mobile affordances into sibling hooks (slice 7) (#26773)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8KF8i7bmUmRJW1rodBW4KnP)_
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
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; eslint on the touched files reports 0 errors.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` not touched.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 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.com/claude-code)
https://claude.ai/code/session_01JQwxbXqCPeUA7ztE9YWKwP
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbXqCPeUA7ztE9YWKwP)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
refactor(plugin-grid): `ObjectGrid`'s row-height sync, column state and mobile affordances move into three sibling hooks
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
Three adjacent blocks at the top of the `ObjectGrid` component move verbatim out of `ObjectGrid.tsx`. The effect that follows a changed `schema.rowHeight` goes to `useObjectGridRowHeightSync` (`objectGridRowHeight.ts`). The column-state persistence (the storage key, the `columnState` seed, the sync of a host-supplied `columnState` and `saveColumnState`) goes to `useObjectGridColumnState` (`objectGridColumnState.ts`). Pull to refresh and the card-view breakpoint go to `useObjectGridMobile` (`objectGridMobile.ts`). `ObjectGrid` calls each hook where its block stood, so its hook order, its stored column state and its rendered output do not change. No name is renamed, and the package entry is unchanged.
0 commit comments