fix(draw): adjust table cell edge resize#1151
Conversation
Deploying plait with
|
| Latest commit: |
d682b87
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://4829bea4.plait.pages.dev |
| Branch Preview URL: | https://codex-table-resize-cell-edge.plait.pages.dev |
Deploying plait-docs with
|
| Latest commit: |
d682b87
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://2cb4e412.plait-docs.pages.dev |
| Branch Preview URL: | https://codex-table-resize-cell-edge.plait-docs.pages.dev |
281b6a4 to
6871efa
Compare
|
@nightt5879 I think this PR is ready for review, help me, please! |
nightt5879
left a comment
There was a problem hiding this comment.
A few edge cases I ran into while testing this.
| handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, 0); | ||
| const rectangle = RectangleClient.getRectangleByPoints(cells[i].points); | ||
| const handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, 0); | ||
| if (handleRef && !isCornerHandle(board, handleRef.handle)) { |
There was a problem hiding this comment.
At grid intersections this helper returns the cell corner first, then we discard it without checking the side handle. That makes the drag fall through instead of resizing the row or column. I can reproduce it on the swimlane edge: dragging there moves the whole swimlane. Could we handle side hits explicitly here?
There was a problem hiding this comment.
Good eye, thanks! I updated the hit testing to resolve table dividers directly after preserving table corner handles. Grid intersections now choose the nearest divider axis, so side drags no longer fall through to whole swimlane/table movement.
| Transforms.setNode(board, { rows, points }, path); | ||
|
|
||
| const originRect = RectangleClient.getRectangleByPoints(originPoints); | ||
| const targetRect = RectangleClient.getRectangleByPoints(targetPoints); |
There was a problem hiding this comment.
getRectangleByPoints normalizes reversed points. If the dragged edge crosses the fixed edge, the size becomes positive again, so the edge jumps to the other side and starts growing in reverse. Could we keep a signed delta here, or clamp at MIN_CELL_SIZE?
There was a problem hiding this comment.
Good eye, thanks! I replaced the normalized-rectangle delta with a signed pointer delta and clamp the target size at MIN_CELL_SIZE before applying the offset, so crossing the fixed edge no longer flips and grows in reverse.
| rectangle = RectangleClient.getRectangleByPoints(cells[i].points); | ||
| handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, 0); | ||
| const rectangle = RectangleClient.getRectangleByPoints(cells[i].points); | ||
| const handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, 0); |
There was a problem hiding this comment.
A shared divider hits both adjacent cells, so this picks whichever cell comes first in cells. addSwimlaneRow/Column(index) can leave cells in a different order from the rows and columns, which means the same divider may resize the opposite side. Should the target be resolved from the row or column indexes instead?
There was a problem hiding this comment.
Good eye, thanks! I removed the cell-order-based target selection. Divider hits are now resolved from the row/column divider index: the outer start divider maps to the first row/column start, and internal/end dividers map to the previous row/column end. This keeps the same divider stable regardless of cell order after row/column insertion.
|
I am still working on it, because I need to check the new resolution. |
Summary
This PR reworks the table resize interaction from the older #931 idea against the current
developbranch.The important behavior change is not just a code cleanup. It makes table resize intent explicit:
Interaction Intent Changes
1. Outer table edges now mean row/column resize, not whole-table resize
Before this change, when a user selected a table and moved the pointer to the right edge of the table, that position could match both:
The old hit-test path checked the table handle first, so the interaction was often interpreted as whole-table resize.
That meant the user appeared to be dragging the last column edge, but the system treated it as resizing the whole table.
After this change, cell resize handles are checked first. If the pointer hits the right edge of the last cell, the interaction is handled as a column resize.
2. Whole-table resize is now reserved for table corners
Before this change, both table side handles and table corner handles could trigger whole-table resize.
That made these two user intents compete with each other:
After this change, table-level resize only falls back to corner handles. Side edges are reserved for row/column resize.
This makes the interaction model mutually exclusive and easier to predict.
3. Start-side row/column resize is now explicit
The previous implementation could already move
points[0]through the table-level resize path. For example, when the interaction was handled as a whole-table resize,resizeSnapRef.activePointsplusnormalizeShapePointscould produce a new start point.The gap was in the cell row/column resize path. The old row/column update helpers behaved like end-side updates:
That is correct for right/bottom cell edges, but it does not clearly model the user intent when dragging a left/top cell edge.
When a user drags the left edge of the first column, the expected intent is not whole-table resize. The intent is:
So the row/column resize path itself needs to know whether the dragged edge is the start side or the end side.
This PR introduces a small
ResizeEdgeconcept:w / n->starte / s->endSo the row/column update now matches the dragged cell edge:
The improvement is therefore not first-time support for changing
points[0]; it is making start-side row/column resize explicit instead of relying on the table-level resize path.4. Merged cells resolve the resize target by dragged edge
Merged cells can cover multiple rows or columns.
For example, a cell with
colspan=3covers columns 1, 2, and 3.The expected interaction is:
The old logic mainly followed the cell starting
rowId/columnId, which made end-side resize ambiguous forrowspan/colspancells.This PR resolves the target row/column from the dragged edge:
So merged-cell resize now maps to the user visible drag target instead of always leaning on the cell starting row/column.
Implementation Notes
hitTestchecks cell side handles before table-level handles.ResizeEdgerepresents whether the dragged cell edge is the start or end side.getResizeTargetRowOrColumnIndexresolves the row/column affected by normal and merged cells.getCurrentRowOrColumnSizederives the current rendered row/column size from the table layout, avoiding fragile inference from cell rectangles.Verification
npm run build:drawFocused manual checks to run:
Unit tests can be added in a follow-up once the interaction behavior is confirmed.