feat: DH-22800: Support Intersection 2D Window Resizing#2701
feat: DH-22800: Support Intersection 2D Window Resizing#2701SimonVutov wants to merge 6 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2701 +/- ##
==========================================
+ Coverage 50.49% 51.16% +0.67%
==========================================
Files 788 792 +4
Lines 44923 45445 +522
Branches 11447 11593 +146
==========================================
+ Hits 22682 23253 +571
+ Misses 22222 22173 -49
Partials 19 19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds 2D “intersection” resize handles to Golden Layout so users can drag diagonally at row/column splitter crossings to resize both axes together (DH-22800).
Changes:
- Add
IntersectionSplittercontrol (2D drag handle) and export it fromcontrols. - Extend
RowOrColumnto create/refresh intersection handles and apply drag updates for both the parent splitter and a perpendicular child splitter. - Add styling + Jest coverage for intersection handle creation and drag behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/golden-layout/src/items/RowOrColumn.ts | Creates/positions intersection handles and wires diagonal drag to existing 1D splitter logic. |
| packages/golden-layout/src/controls/IntersectionSplitter.ts | New 2D splitter control backed by DragListener. |
| packages/golden-layout/src/controls/index.ts | Re-exports IntersectionSplitter. |
| packages/golden-layout/src/tests/intersection-drag.test.ts | Adds tests covering diagonal drag + handle persistence across refreshes/drags. |
| packages/golden-layout/scss/goldenlayout-dark-theme.scss | Dark theme styling for intersection handle visibility/hover/drag states. |
| packages/golden-layout/scss/goldenlayout-base.scss | Base styling + cursor override while intersection-dragging. |
Replaced the one-level-deep loop with a small recursive walk
b54162a to
5cb5501
Compare
dsmmcken
left a comment
There was a problem hiding this comment.
2d drag, over another splitter triggers it and it gets stuck hovered;

I wonder if we could detect 4-way corners, with a bit of fuzziness (like if the 4th corner is +/- 5px or 10px or whatever), and make them a 4-way drag (that leaves it snapped perfectly aligned on drop)?
Didn't review JS, will leave to someone else to review that.
| .lm_intersection_dragging, | ||
| .lm_intersection_dragging * { | ||
| cursor: move !important; | ||
| } |
There was a problem hiding this comment.
Doesn't actually do anything, pointer-events none means cursor wont trigger, and the pointer-events none is needed to prevent interaction with other elements while dragging.
| z-index: 59; | ||
| } | ||
| } | ||
|
|
||
| // Intersection splitter: an invisible grab area at grid crossing points that | ||
| // enables simultaneous (2D) resizing of rows and columns. The visible drag | ||
| // affordance is the two perpendicular splitter lines themselves, which are | ||
| // highlighted (via .lm_dragging) on hover and while dragging. | ||
| .lm_intersection_splitter { | ||
| position: absolute; | ||
| z-index: 60; |
There was a problem hiding this comment.
these z-indexes look sus.
| // Intersection splitter (2D grid resize). The grab area is invisible; the drag | ||
| // affordance is the two perpendicular splitter lines, which reuse the standard | ||
| // .lm_splitter.lm_dragging highlight above. | ||
| .lm_intersection_splitter { | ||
| background: transparent; | ||
| } |
There was a problem hiding this comment.
Does nothing, transparent by default.
Changes
Validation
packages/golden-layout/src/__tests__/intersection-drag.test.tsDemo (23s mov video):
2026-06-24.10-35-43.mov
Other Information
The splitter lines are width 10px, and this intersection handle is a square of side length 14px.
this._hitAreaSize = Math.max(this._grabSize, 14);Each crossing gets an invisible square handle element and it is centered exactly on the crossing point: It uses
_getIntersectionPositionto get the intersection position and places the handle centered there with slightly higher z index than splitter lines so that it has priority over them.