fix(draw): restore table cell resize origin#1160
Conversation
Deploying plait with
|
| Latest commit: |
976c1d0
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://a15a0b6c.plait.pages.dev |
| Branch Preview URL: | https://xingxing-table-resize-origin-t7hs.plait.pages.dev |
Deploying plait-docs with
|
| Latest commit: |
976c1d0
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://38acd7c6.plait-docs.pages.dev |
| Branch Preview URL: | https://xingxing-table-resize-origin-nfs4.plait-docs.pages.dev |
|
Hi @nightt5879 , Please help review, I also improve text fixture in this PR! |
nightt5879
left a comment
There was a problem hiding this comment.
Thanks for the follow-up. The overall direction looks good, and I left the higher-priority behavior and fixture notes inline. Two small, non-blocking cleanup notes:
- [P3] fixture.destroy() only traverses the current board.children, so initial nodes replaced by Immer can retain NODE_TO_PARENT / NODE_TO_INDEX entries. Keeping the initial snapshot (or all mapped nodes) for cleanup would improve test isolation.
- [P3] fill-style.spec.ts calls the same GeometryShapeGenerator.draw() twice at lines 61-62; one of the calls can be removed.
| [220, 100] | ||
| ]); | ||
| fixture.board.pointerMove(createPointerEvent('pointermove', 100, 50)); | ||
| tick(16); |
There was a problem hiding this comment.
[P1] Could we also cover the case where the move back to x=100 and pointerUp happen within the same RAF? In that order, globalPointerUp clears startPoint / resizeRef before the queued resize callback runs, so the table can remain at width 120 (points ending at 220). Reordering this part to move(100) -> pointerUp -> tick reproduces it. It may be worth applying or flushing the pending final resize before clearing the resize state.
| appliedOffset, | ||
| edge | ||
| ); | ||
| Transforms.setNode(board, { rows, points }, path); |
There was a problem hiding this comment.
[P2] Could we avoid setNode when clamping produces no live change? For a cell already at MIN_CELL_SIZE, an inward drag has targetSize === currentSize, but the new arrays still create a set_node operation. With withHistory this clears redo and can add a no-op undo entry. Comparing the result with the live node would preserve the origin restore while skipping a true no-op.
| ); | ||
| Transforms.setNode(board, { rows, points }, path); | ||
| } else { | ||
| const { columns, points } = updateColumns( |
There was a problem hiding this comment.
[P2] Returning to the origin restores the numeric size, but not the original auto-size representation: a column like { id } becomes { id, width: 100 } (and similarly for row height). That changes later remaining-space distribution, especially for swimlanes. Could the zero-offset restore reuse the pointer-down rows / columns / points snapshot exactly?
| rectangle: () => createG(), | ||
| linearPath: () => createG() | ||
| }; | ||
| return roughSVG as unknown as RoughSVG; |
There was a problem hiding this comment.
[P2] This object is cast to the full RoughSVG interface, but it is missing methods already used by repository drawing paths, including line, curve, and ellipse. A fixture exercising those paths will fail at runtime. Could we implement the used RoughSVG surface here, or narrow the declared mock type?
|
|
||
| export const fakeBoardHost = (board: PlaitBoard) => { | ||
| const host = createSVG(); | ||
| Object.defineProperty(host, 'viewBox', { |
There was a problem hiding this comment.
[P2] Defining viewBox as a fixed own property means a later setAttribute('viewBox', ...) does not update baseVal. getViewBox / toViewBoxPoint will therefore continue reading 0,0,1000,1000 after viewport changes. Could we initialize the live SVG viewBox instead, or keep this mock value synchronized with attribute updates?
Summary
Replaces the closed draft #1159 with a clean branch based on the latest
developafter #1151 landed.This fixes the table cell resize-origin case: when a cell edge is dragged away from its original size and then the pointer returns to the pointer-down position within the same resize cycle, the table should restore the original row/column size and points.
Root Cause
resizeRef.elementis captured on pointer down and remains the pointer-down element reference during the resize cycle. The board update flow is immer-backed:set_nodemutates a draft and then replacesboard.children, soresizeRef.elementstill represents the original resize baseline.When the cumulative pointer offset returns to
0, the computed target size is the original size andappliedOffsetbecomes0. The previousappliedOffset !== 0guard skipped that write, leaving the board at the previous non-zero resize frame.Change
Remove the
appliedOffset !== 0guard so the resize path applies the computed row/column state even when the effective offset is zero.Test Coverage
Added an interaction-style spec for
withTableResizethat uses the realwithDrawplugin chain and simulated pointer events:100to120and verify the first column expands to120.Verification
npm run build:drawAttempted locally but blocked by existing/local test environment issues:
npx tsc -p packages/draw/tsconfig.spec.json --noEmitstill fails on existing swimlane spec issues unrelated to this change:packages/draw/src/transforms/swimlane.spec.ts:flatMaplib / implicit any errorspackages/draw/src/utils/swimlane.spec.ts:BOARD_TO_TEMPORARY_POINTERexport errornpm run test:draw -- --watch=false --browsers=ChromeHeadlessCI --progress=false --include=packages/draw/src/plugins/with-table-resize.spec.tsexits locally during the Karma building phase with code 134 before running specs.