regular-layout 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5 -5
- package/dist/index.js.map +3 -3
- package/dist/layout/generate_grid.d.ts +2 -2
- package/dist/layout/generate_overlay.d.ts +1 -1
- package/dist/layout/redistribute_panel_sizes.d.ts +1 -1
- package/dist/layout/types.d.ts +3 -7
- package/dist/regular-layout-frame.d.ts +10 -3
- package/dist/regular-layout.d.ts +49 -12
- package/package.json +4 -2
- package/src/layout/calculate_edge.ts +3 -1
- package/src/layout/calculate_intersect.ts +2 -2
- package/src/layout/generate_grid.ts +4 -4
- package/src/layout/generate_overlay.ts +1 -1
- package/src/layout/insert_child.ts +5 -5
- package/src/layout/redistribute_panel_sizes.ts +16 -12
- package/src/layout/remove_child.ts +7 -7
- package/src/layout/types.ts +3 -8
- package/src/regular-layout-frame.ts +52 -67
- package/src/regular-layout-tab.ts +5 -5
- package/src/regular-layout.ts +133 -104
|
@@ -40,11 +40,11 @@ export class RegularLayoutTab extends HTMLElement {
|
|
|
40
40
|
(index === this._tab_panel?.selected);
|
|
41
41
|
|
|
42
42
|
const index_changed =
|
|
43
|
-
tab_changed || this._tab_panel?.
|
|
43
|
+
tab_changed || this._tab_panel?.tabs[index] !== tab_panel.tabs[index];
|
|
44
44
|
|
|
45
45
|
if (index_changed) {
|
|
46
46
|
const selected = tab_panel.selected === index;
|
|
47
|
-
const slot = tab_panel.
|
|
47
|
+
const slot = tab_panel.tabs[index];
|
|
48
48
|
this.children[0].textContent = slot;
|
|
49
49
|
|
|
50
50
|
if (selected) {
|
|
@@ -56,7 +56,7 @@ export class RegularLayoutTab extends HTMLElement {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
} else {
|
|
59
|
-
const slot = tab_panel.
|
|
59
|
+
const slot = tab_panel.tabs[index];
|
|
60
60
|
const selected = tab_panel.selected === index;
|
|
61
61
|
const parts = selected ? "active-close close" : "close";
|
|
62
62
|
this.innerHTML = `<div part="title"></div><button part="${parts}"></button>`;
|
|
@@ -78,7 +78,7 @@ export class RegularLayoutTab extends HTMLElement {
|
|
|
78
78
|
|
|
79
79
|
private onTabClose = (_: Event) => {
|
|
80
80
|
if (this._tab_panel !== undefined && this._index !== undefined) {
|
|
81
|
-
this._layout?.removePanel(this._tab_panel.
|
|
81
|
+
this._layout?.removePanel(this._tab_panel.tabs[this._index]);
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
84
|
|
|
@@ -90,7 +90,7 @@ export class RegularLayoutTab extends HTMLElement {
|
|
|
90
90
|
) {
|
|
91
91
|
const new_layout = this._layout?.save();
|
|
92
92
|
const new_tab_panel = this._layout?.getPanel(
|
|
93
|
-
this._tab_panel.
|
|
93
|
+
this._tab_panel.tabs[this._index],
|
|
94
94
|
new_layout,
|
|
95
95
|
);
|
|
96
96
|
|
package/src/regular-layout.ts
CHANGED
|
@@ -39,6 +39,16 @@ import {
|
|
|
39
39
|
type Physics,
|
|
40
40
|
} from "./layout/constants.ts";
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* An interface which models the fields of `PointerEvent` that
|
|
44
|
+
* `<regular-layour>` actually uses, making it easier to sub out with an
|
|
45
|
+
* JavaScript object lieral when you don't have a `PointerEvent` handy.
|
|
46
|
+
*/
|
|
47
|
+
export interface PointerEventCoordinates {
|
|
48
|
+
clientX: number;
|
|
49
|
+
clientY: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
/**
|
|
43
53
|
* A Web Component that provides a resizable panel layout system.
|
|
44
54
|
* Panels are arranged using CSS Grid and can be resized by dragging dividers.
|
|
@@ -71,6 +81,22 @@ import {
|
|
|
71
81
|
* layout.restore(state);
|
|
72
82
|
* ```
|
|
73
83
|
*
|
|
84
|
+
* @remarks
|
|
85
|
+
*
|
|
86
|
+
* Why does this implementation use a `<slot>` at all? We must use
|
|
87
|
+
* `<slot>` and the Shadow DOM to scope the grid CSS rules to each
|
|
88
|
+
* instance of `<regular-layout>` (without e.g. giving them unique
|
|
89
|
+
* `"id"` and injecting into `document,head`), and we can only select
|
|
90
|
+
* `::slotted` light DOM children from `adoptedStyleSheets` on the
|
|
91
|
+
* `ShadowRoot`.
|
|
92
|
+
*
|
|
93
|
+
* Why does this implementation use a single `<slot>` and the child
|
|
94
|
+
* `"name"` attribute, as opposed to a named `<slot name="my_slot">`
|
|
95
|
+
* and the built-in `"slot"` child attribute? Children with a `"slot"`
|
|
96
|
+
* attribute don't fallback to the un-named `<slot>`, so using the
|
|
97
|
+
* latter implementation would require synchronizing the light DOM
|
|
98
|
+
* and shadow DOM slots/slotted children continuously.
|
|
99
|
+
*
|
|
74
100
|
*/
|
|
75
101
|
export class RegularLayout extends HTMLElement {
|
|
76
102
|
private _shadowRoot: ShadowRoot;
|
|
@@ -86,17 +112,6 @@ export class RegularLayout extends HTMLElement {
|
|
|
86
112
|
super();
|
|
87
113
|
this._physics = DEFAULT_PHYSICS;
|
|
88
114
|
this._panel = structuredClone(EMPTY_PANEL);
|
|
89
|
-
|
|
90
|
-
// Why does this implementation use a `<slot>` at all? We must use
|
|
91
|
-
// `<slot>` and the Shadow DOM to scope the grid CSS rules to each
|
|
92
|
-
// instance of `<regular-layout>` (without e.g. giving them unique
|
|
93
|
-
// `"id"` and injecting into `document,head`), and we can only select
|
|
94
|
-
// `::slotted` light DOM children from `adoptedStyleSheets` on the
|
|
95
|
-
// `ShadowRoot`.
|
|
96
|
-
|
|
97
|
-
// In addition, this model uses a single un-named `<slot>` to host all
|
|
98
|
-
// light-DOM children, and the child's `"name"` attribute to identify
|
|
99
|
-
// its position in the `Layout`. Alternatively, using named
|
|
100
115
|
this._shadowRoot = this.attachShadow({ mode: "open" });
|
|
101
116
|
this._shadowRoot.innerHTML = `<slot></slot>`;
|
|
102
117
|
this._stylesheet = new CSSStyleSheet();
|
|
@@ -109,12 +124,14 @@ export class RegularLayout extends HTMLElement {
|
|
|
109
124
|
}
|
|
110
125
|
|
|
111
126
|
connectedCallback() {
|
|
127
|
+
this.addEventListener("dblclick", this.onDblClick);
|
|
112
128
|
this.addEventListener("pointerdown", this.onPointerDown);
|
|
113
129
|
this.addEventListener("pointerup", this.onPointerUp);
|
|
114
130
|
this.addEventListener("pointermove", this.onPointerMove);
|
|
115
131
|
}
|
|
116
132
|
|
|
117
133
|
disconnectedCallback() {
|
|
134
|
+
this.removeEventListener("dblclick", this.onDblClick);
|
|
118
135
|
this.removeEventListener("pointerdown", this.onPointerDown);
|
|
119
136
|
this.removeEventListener("pointerup", this.onPointerUp);
|
|
120
137
|
this.removeEventListener("pointermove", this.onPointerMove);
|
|
@@ -123,36 +140,23 @@ export class RegularLayout extends HTMLElement {
|
|
|
123
140
|
/**
|
|
124
141
|
* Determines which panel is at a given screen coordinate.
|
|
125
142
|
*
|
|
126
|
-
* @param
|
|
127
|
-
*
|
|
143
|
+
* @param coordinates - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
144
|
+
* coordinates in screen pixels.
|
|
128
145
|
* @returns Panel information if a panel is at that position, null otherwise.
|
|
129
146
|
*/
|
|
130
147
|
calculateIntersect = (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const [col, row, rect] = this.relativeCoordinates(x, y, false);
|
|
136
|
-
const panel = calculate_intersection(
|
|
137
|
-
col,
|
|
138
|
-
row,
|
|
139
|
-
this._panel,
|
|
140
|
-
check_dividers ? { rect, size: this._physics.GRID_DIVIDER_SIZE } : null,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
if (panel?.type === "layout-path") {
|
|
144
|
-
return { ...panel, layout: this.save() };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return null;
|
|
148
|
+
coordinates: PointerEventCoordinates,
|
|
149
|
+
): LayoutPath | null => {
|
|
150
|
+
const [col, row, _] = this.relativeCoordinates(coordinates, false);
|
|
151
|
+
return calculate_intersection(col, row, this._panel);
|
|
148
152
|
};
|
|
149
153
|
|
|
150
154
|
/**
|
|
151
155
|
* Sets the visual overlay state during drag-and-drop operations.
|
|
152
156
|
* Displays a preview of where a panel would be placed at the given coordinates.
|
|
153
157
|
*
|
|
154
|
-
* @param
|
|
155
|
-
*
|
|
158
|
+
* @param event - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
159
|
+
* coordinates in screen pixels.
|
|
156
160
|
* @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
|
|
157
161
|
* which points to the drag element in the current layout.
|
|
158
162
|
* @param className - The CSS class name to use for the overlay panel
|
|
@@ -162,18 +166,20 @@ export class RegularLayout extends HTMLElement {
|
|
|
162
166
|
* "absolute".
|
|
163
167
|
*/
|
|
164
168
|
setOverlayState = (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
{ slot }: LayoutPath<unknown>,
|
|
169
|
+
event: PointerEventCoordinates,
|
|
170
|
+
{ slot }: LayoutPath,
|
|
168
171
|
className: string = this._physics.OVERLAY_CLASSNAME,
|
|
169
172
|
mode: OverlayMode = this._physics.OVERLAY_DEFAULT,
|
|
170
173
|
) => {
|
|
171
174
|
const panel = remove_child(this._panel, slot);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
+
const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
|
|
176
|
+
const drag_element = this.querySelector(query);
|
|
177
|
+
if (drag_element) {
|
|
178
|
+
drag_element.classList.add(className);
|
|
179
|
+
}
|
|
175
180
|
|
|
176
|
-
|
|
181
|
+
// TODO: Don't recalculate box (but this currently protects against resize).
|
|
182
|
+
const [col, row, box, style] = this.relativeCoordinates(event, true);
|
|
177
183
|
let drop_target = calculate_intersection(col, row, panel);
|
|
178
184
|
if (drop_target) {
|
|
179
185
|
drop_target = calculate_edge(
|
|
@@ -193,7 +199,6 @@ export class RegularLayout extends HTMLElement {
|
|
|
193
199
|
this._stylesheet.replaceSync(css);
|
|
194
200
|
} else if (mode === "absolute") {
|
|
195
201
|
const grid_css = create_css_grid_layout(panel, undefined, this._physics);
|
|
196
|
-
|
|
197
202
|
const overlay_css = updateOverlaySheet(
|
|
198
203
|
slot,
|
|
199
204
|
box,
|
|
@@ -206,15 +211,15 @@ export class RegularLayout extends HTMLElement {
|
|
|
206
211
|
}
|
|
207
212
|
|
|
208
213
|
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-update`;
|
|
209
|
-
const
|
|
210
|
-
this.dispatchEvent(
|
|
214
|
+
const custom_event = new CustomEvent<Layout>(event_name, { detail: panel });
|
|
215
|
+
this.dispatchEvent(custom_event);
|
|
211
216
|
};
|
|
212
217
|
|
|
213
218
|
/**
|
|
214
219
|
* Clears the overlay state and commits the panel placement.
|
|
215
220
|
*
|
|
216
|
-
* @param
|
|
217
|
-
*
|
|
221
|
+
* @param event - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
222
|
+
* coordinates in screen pixels.
|
|
218
223
|
* @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
|
|
219
224
|
* which points to the drag element in the current layout.
|
|
220
225
|
* @param className - The CSS class name to use for the overlay panel
|
|
@@ -223,46 +228,53 @@ export class RegularLayout extends HTMLElement {
|
|
|
223
228
|
* passed to `setOverlayState`. Defaults to "absolute".
|
|
224
229
|
*/
|
|
225
230
|
clearOverlayState = (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
drag_target: LayoutPath<Layout>,
|
|
231
|
+
event: PointerEventCoordinates | null,
|
|
232
|
+
{ slot, layout }: LayoutPath,
|
|
229
233
|
className: string = this._physics.OVERLAY_CLASSNAME,
|
|
230
234
|
) => {
|
|
231
235
|
let panel = this._panel;
|
|
232
|
-
panel = remove_child(panel,
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
panel = remove_child(panel, slot);
|
|
237
|
+
const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
|
|
238
|
+
const drag_element = this.querySelector(query);
|
|
239
|
+
if (drag_element) {
|
|
240
|
+
drag_element.classList.remove(className);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (event === null) {
|
|
244
|
+
this.restore(layout);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const [col, row, box] = this.relativeCoordinates(event, false);
|
|
242
249
|
let drop_target = calculate_intersection(col, row, panel);
|
|
243
250
|
if (drop_target) {
|
|
244
251
|
drop_target = calculate_edge(
|
|
245
252
|
col,
|
|
246
253
|
row,
|
|
247
254
|
panel,
|
|
248
|
-
|
|
255
|
+
slot,
|
|
249
256
|
drop_target,
|
|
250
257
|
box,
|
|
251
258
|
this._physics,
|
|
252
259
|
);
|
|
253
260
|
}
|
|
254
261
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
if (drop_target) {
|
|
263
|
+
const orientation = drop_target?.is_edge
|
|
264
|
+
? drop_target.orientation
|
|
265
|
+
: undefined;
|
|
266
|
+
|
|
267
|
+
const new_layout = insert_child(
|
|
268
|
+
panel,
|
|
269
|
+
slot,
|
|
270
|
+
drop_target.path,
|
|
271
|
+
orientation,
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
this.restore(new_layout);
|
|
275
|
+
} else {
|
|
276
|
+
this.restore(layout);
|
|
277
|
+
}
|
|
266
278
|
};
|
|
267
279
|
|
|
268
280
|
/**
|
|
@@ -309,9 +321,10 @@ export class RegularLayout extends HTMLElement {
|
|
|
309
321
|
*/
|
|
310
322
|
getPanel = (name: string, layout: Layout = this._panel): TabLayout | null => {
|
|
311
323
|
if (layout.type === "child-panel") {
|
|
312
|
-
if (layout.
|
|
324
|
+
if (layout.tabs.includes(name)) {
|
|
313
325
|
return layout;
|
|
314
326
|
}
|
|
327
|
+
|
|
315
328
|
return null;
|
|
316
329
|
}
|
|
317
330
|
|
|
@@ -347,7 +360,6 @@ export class RegularLayout extends HTMLElement {
|
|
|
347
360
|
restore = (layout: Layout, _is_flattened: boolean = false) => {
|
|
348
361
|
this._panel = !_is_flattened ? flatten(layout) : layout;
|
|
349
362
|
const css = create_css_grid_layout(this._panel, undefined, this._physics);
|
|
350
|
-
|
|
351
363
|
this._stylesheet.replaceSync(css);
|
|
352
364
|
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
353
365
|
const event = new CustomEvent<Layout>(event_name, { detail: this._panel });
|
|
@@ -397,16 +409,15 @@ export class RegularLayout extends HTMLElement {
|
|
|
397
409
|
* Transforms absolute pixel positions into normalized coordinates (0-1 range)
|
|
398
410
|
* relative to the layout's bounding box.
|
|
399
411
|
*
|
|
400
|
-
* @param
|
|
401
|
-
*
|
|
412
|
+
* @param coordinates - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
413
|
+
* coordinates in screen pixels.
|
|
402
414
|
* @returns A tuple containing:
|
|
403
415
|
* - col: Normalized X coordinate (0 = left edge, 1 = right edge)
|
|
404
416
|
* - row: Normalized Y coordinate (0 = top edge, 1 = bottom edge)
|
|
405
417
|
* - box: The layout element's bounding rectangle
|
|
406
418
|
*/
|
|
407
419
|
relativeCoordinates = (
|
|
408
|
-
|
|
409
|
-
clientY: number,
|
|
420
|
+
event: PointerEventCoordinates,
|
|
410
421
|
recalculate_bounds: boolean = true,
|
|
411
422
|
): [number, number, DOMRect, CSSStyleDeclaration] => {
|
|
412
423
|
if (recalculate_bounds || !this._dimensions) {
|
|
@@ -419,12 +430,13 @@ export class RegularLayout extends HTMLElement {
|
|
|
419
430
|
const box = this._dimensions.box;
|
|
420
431
|
const style = this._dimensions.style;
|
|
421
432
|
const col =
|
|
422
|
-
(clientX - box.left - parseFloat(style.paddingLeft)) /
|
|
433
|
+
(event.clientX - box.left - parseFloat(style.paddingLeft)) /
|
|
423
434
|
(box.width -
|
|
424
435
|
parseFloat(style.paddingLeft) -
|
|
425
436
|
parseFloat(style.paddingRight));
|
|
437
|
+
|
|
426
438
|
const row =
|
|
427
|
-
(clientY - box.top - parseFloat(style.paddingTop)) /
|
|
439
|
+
(event.clientY - box.top - parseFloat(style.paddingTop)) /
|
|
428
440
|
(box.height -
|
|
429
441
|
parseFloat(style.paddingTop) -
|
|
430
442
|
parseFloat(style.paddingBottom));
|
|
@@ -432,17 +444,49 @@ export class RegularLayout extends HTMLElement {
|
|
|
432
444
|
return [col, row, box, style];
|
|
433
445
|
};
|
|
434
446
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
447
|
+
/**
|
|
448
|
+
* Calculates the Euclidean distance in pixels between the current pointer
|
|
449
|
+
* coordinates and a drag target's position within the layout.
|
|
450
|
+
*
|
|
451
|
+
* @param coordinates - The current pointer event coordinates.
|
|
452
|
+
* @param drag_target - The layout path representing the drag target
|
|
453
|
+
* position.
|
|
454
|
+
* @returns The distance in pixels between the coordinates and the drag
|
|
455
|
+
* target.
|
|
456
|
+
*/
|
|
457
|
+
diffCoordinates = (
|
|
458
|
+
event: PointerEventCoordinates,
|
|
459
|
+
drag_target: LayoutPath,
|
|
460
|
+
): number => {
|
|
461
|
+
const [column, row, box] = this.relativeCoordinates(event, false);
|
|
462
|
+
const dx = (column - drag_target.column) * box.width;
|
|
463
|
+
const dy = (row - drag_target.row) * box.height;
|
|
464
|
+
return Math.sqrt(dx ** 2 + dy ** 2);
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
private onDblClick = (event: MouseEvent) => {
|
|
468
|
+
const [col, row, rect] = this.relativeCoordinates(event, false);
|
|
469
|
+
const divider = calculate_intersection(col, row, this._panel, {
|
|
470
|
+
rect,
|
|
471
|
+
size: this._physics.GRID_DIVIDER_SIZE,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
if (divider?.type === "horizontal" || divider?.type === "vertical") {
|
|
475
|
+
const panel = redistribute_panel_sizes(
|
|
476
|
+
this._panel,
|
|
477
|
+
divider.path,
|
|
478
|
+
undefined,
|
|
440
479
|
);
|
|
441
480
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
481
|
+
this.restore(panel, true);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
private onPointerDown = (event: PointerEvent) => {
|
|
486
|
+
if (!this._physics.GRID_DIVIDER_CHECK_TARGET || event.target === this) {
|
|
487
|
+
const [col, row, rect] = this.relativeCoordinates(event);
|
|
488
|
+
const size = this._physics.GRID_DIVIDER_SIZE;
|
|
489
|
+
const hit = calculate_intersection(col, row, this._panel, { rect, size });
|
|
446
490
|
if (hit && hit.type !== "layout-path") {
|
|
447
491
|
this._drag_target = [hit, col, row];
|
|
448
492
|
this.setPointerCapture(event.pointerId);
|
|
@@ -453,12 +497,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
453
497
|
|
|
454
498
|
private onPointerMove = (event: PointerEvent) => {
|
|
455
499
|
if (this._drag_target) {
|
|
456
|
-
const [col, row] = this.relativeCoordinates(
|
|
457
|
-
event.clientX,
|
|
458
|
-
event.clientY,
|
|
459
|
-
false,
|
|
460
|
-
);
|
|
461
|
-
|
|
500
|
+
const [col, row] = this.relativeCoordinates(event, false);
|
|
462
501
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
463
502
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
464
503
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|
|
@@ -476,12 +515,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
476
515
|
return;
|
|
477
516
|
}
|
|
478
517
|
|
|
479
|
-
const [col, row, rect] = this.relativeCoordinates(
|
|
480
|
-
event.clientX,
|
|
481
|
-
event.clientY,
|
|
482
|
-
false,
|
|
483
|
-
);
|
|
484
|
-
|
|
518
|
+
const [col, row, rect] = this.relativeCoordinates(event, false);
|
|
485
519
|
const divider = calculate_intersection(col, row, this._panel, {
|
|
486
520
|
rect,
|
|
487
521
|
size: this._physics.GRID_DIVIDER_SIZE,
|
|
@@ -502,12 +536,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
502
536
|
private onPointerUp = (event: PointerEvent) => {
|
|
503
537
|
if (this._drag_target) {
|
|
504
538
|
this.releasePointerCapture(event.pointerId);
|
|
505
|
-
const [col, row] = this.relativeCoordinates(
|
|
506
|
-
event.clientX,
|
|
507
|
-
event.clientY,
|
|
508
|
-
false,
|
|
509
|
-
);
|
|
510
|
-
|
|
539
|
+
const [col, row] = this.relativeCoordinates(event, false);
|
|
511
540
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
512
541
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
513
542
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|