Repository navigation
refactor(react): one drag state machine for the tool panel's row lists - #527
Merged
Merged
Conversation
ColumnsSection and GroupingSection carried near-verbatim copies of the same pointer-drag state machine: the 5px threshold, the pending/active drag shapes, the pointerdown/move/up/cancel handlers, endDrag, and the document-level Escape-cancel effect with its preventDefault interlock. Only the pure geometry (tool-panel-drop-target.ts) was shared. The machine now lives in one hook, useToolRowDrag, parameterized over the real differences: how the section measures its rendered rows, what subgroups they partition into (pin groups vs a single constant group), and what a finished move commits. The constraint-carrying comments moved with it — capture-at-pointerdown with its rAF-coalescing measurement, commit-on-release-only with the coalesced-last-move finding, and the Escape preventDefault interlock — while the commit-time re-read rationale stays with each section's commit, where what there is to re-read differs. GroupingSection's settle-aware pending-grip-focus handling stays section-side. One test added: the columns section's pointer-RELEASE commit had no jsdom pin (only cancel paths were pinned), so a commit-path mutation in the shared hook was caught only by the grouping suite. Both sections' suites now fail on a commit mutation and on an Escape-cancel mutation; all 119 tool-panel tests (and the full react suite, 1568) are green on the real code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
blove
enabled auto-merge (squash)
August 30, 2026 02:49
Contributor
Vercel preview readyPreview: https://pretable-6q4u4xh9l-cacheplane.vercel.app Updated automatically by the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The duplication
ColumnsSection.tsxandgrouping/GroupingSection.tsxcarried near-verbatim copies of the same pointer-drag state machine, recorded during the SP3b review:DRAG_THRESHOLD_PX, thePendingRowDrag/ActiveRowDragshapes, the pointerdown/move/up/cancel handlers,endDrag, and the document-level Escape-cancel effect with thepreventDefaultinterlock. Only the pure insertion geometry (tool-panel-drop-target.ts) was shared.The extraction
The machine now lives in
packages/react/src/tool-panel/useToolRowDrag.ts, parameterized over the three real differences:measureRows— how the section measures its rendered rows (called fresh on every move and again at release; the never-cache rationale moved into the option's TSDoc).groups— the rendered subgroups (the columns section's pin partition vs the grouping list's single constant group).commit— what a finished move applies. Called only from a release over a resolved target; the commit-timegetStatere-read rationale stays with each section's commit, because what there is to re-read differs (livecolumnLayoutvs the row model'srowGroups).The hook returns
{ drag, gripHandlers }; each section spreadsgripHandlers(columnId)onto its grip. Constraint-carrying comments moved with the code they constrain: capture-at-pointerdown with its rAF-coalescing measurement, commit-on-release-only with the coalesced-last-move cross-boundary finding, the EscapepreventDefaultinterlock, and the generalized no-stopPropagation-on-pointerdown rule (an open popover's outside-press close must fire). GroupingSection's async-settle-aware pending-grip-focus handling stays section-side, inside its commit. Behavior-preserving by construction and by suite: no existing test was touched except to add one.Mutation proof
endDragremoved → 2 failures, both sections' pre-existing "Escape mid-drag cancels" tests.pnpm --filter @pretable/react test tool-panel: 8 files, 119 tests green.Verification
pnpm format, eslint,tsc --noEmit: clean.api:checkfresh — nothing public moved (the hook is internal, not in any barrel); no changeset.🤖 Generated with Claude Code