react-resizable-panels 2.0.4 → 2.0.5
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/CHANGELOG.md +4 -0
- package/dist/declarations/src/index.d.ts +3 -1
- package/dist/declarations/src/utils/rects/getIntersectingRectangle.d.ts +2 -0
- package/dist/declarations/src/utils/rects/intersects.d.ts +2 -0
- package/dist/declarations/src/utils/rects/types.d.ts +6 -0
- package/dist/react-resizable-panels.browser.cjs.js +84 -5
- package/dist/react-resizable-panels.browser.cjs.mjs +3 -1
- package/dist/react-resizable-panels.browser.development.cjs.js +84 -5
- package/dist/react-resizable-panels.browser.development.cjs.mjs +3 -1
- package/dist/react-resizable-panels.browser.development.esm.js +83 -6
- package/dist/react-resizable-panels.browser.esm.js +83 -6
- package/dist/react-resizable-panels.cjs.js +84 -5
- package/dist/react-resizable-panels.cjs.mjs +3 -1
- package/dist/react-resizable-panels.development.cjs.js +84 -5
- package/dist/react-resizable-panels.development.cjs.mjs +3 -1
- package/dist/react-resizable-panels.development.esm.js +83 -6
- package/dist/react-resizable-panels.development.node.cjs.js +84 -5
- package/dist/react-resizable-panels.development.node.cjs.mjs +3 -1
- package/dist/react-resizable-panels.development.node.esm.js +83 -6
- package/dist/react-resizable-panels.esm.js +83 -6
- package/dist/react-resizable-panels.node.cjs.js +84 -5
- package/dist/react-resizable-panels.node.cjs.mjs +3 -1
- package/dist/react-resizable-panels.node.esm.js +83 -6
- package/package.json +4 -1
- package/src/PanelResizeHandleRegistry.ts +75 -8
- package/src/index.ts +4 -0
- package/src/utils/rects/getIntersectingRectangle.test.ts +198 -0
- package/src/utils/rects/getIntersectingRectangle.ts +28 -0
- package/src/utils/rects/intersects.test.ts +197 -0
- package/src/utils/rects/intersects.ts +23 -0
- package/src/utils/rects/types.ts +6 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { compare } from 'stacking-order';
|
|
2
3
|
|
|
3
4
|
// This module exists to work around Webpack issue https://github.com/webpack/webpack/issues/14814
|
|
4
5
|
|
|
@@ -270,6 +271,14 @@ function getInputType() {
|
|
|
270
271
|
}
|
|
271
272
|
}
|
|
272
273
|
|
|
274
|
+
function intersects(rectOne, rectTwo, strict) {
|
|
275
|
+
if (strict) {
|
|
276
|
+
return rectOne.x < rectTwo.x + rectTwo.width && rectOne.x + rectOne.width > rectTwo.x && rectOne.y < rectTwo.y + rectTwo.height && rectOne.y + rectOne.height > rectTwo.y;
|
|
277
|
+
} else {
|
|
278
|
+
return rectOne.x <= rectTwo.x + rectTwo.width && rectOne.x + rectOne.width >= rectTwo.x && rectOne.y <= rectTwo.y + rectTwo.height && rectOne.y + rectOne.height >= rectTwo.y;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
273
282
|
const EXCEEDED_HORIZONTAL_MIN = 0b0001;
|
|
274
283
|
const EXCEEDED_HORIZONTAL_MAX = 0b0010;
|
|
275
284
|
const EXCEEDED_VERTICAL_MIN = 0b0100;
|
|
@@ -308,12 +317,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
|
|
|
308
317
|
};
|
|
309
318
|
}
|
|
310
319
|
function handlePointerDown(event) {
|
|
320
|
+
const {
|
|
321
|
+
target
|
|
322
|
+
} = event;
|
|
311
323
|
const {
|
|
312
324
|
x,
|
|
313
325
|
y
|
|
314
326
|
} = getResizeEventCoordinates(event);
|
|
315
327
|
isPointerDown = true;
|
|
316
328
|
recalculateIntersectingHandles({
|
|
329
|
+
target,
|
|
317
330
|
x,
|
|
318
331
|
y
|
|
319
332
|
});
|
|
@@ -329,10 +342,15 @@ function handlePointerMove(event) {
|
|
|
329
342
|
y
|
|
330
343
|
} = getResizeEventCoordinates(event);
|
|
331
344
|
if (!isPointerDown) {
|
|
345
|
+
const {
|
|
346
|
+
target
|
|
347
|
+
} = event;
|
|
348
|
+
|
|
332
349
|
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
333
350
|
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
334
351
|
// but the same set of active handles should be locked until the pointer is released
|
|
335
352
|
recalculateIntersectingHandles({
|
|
353
|
+
target,
|
|
336
354
|
x,
|
|
337
355
|
y
|
|
338
356
|
});
|
|
@@ -346,6 +364,9 @@ function handlePointerMove(event) {
|
|
|
346
364
|
}
|
|
347
365
|
}
|
|
348
366
|
function handlePointerUp(event) {
|
|
367
|
+
const {
|
|
368
|
+
target
|
|
369
|
+
} = event;
|
|
349
370
|
const {
|
|
350
371
|
x,
|
|
351
372
|
y
|
|
@@ -355,33 +376,72 @@ function handlePointerUp(event) {
|
|
|
355
376
|
if (intersectingHandles.length > 0) {
|
|
356
377
|
event.preventDefault();
|
|
357
378
|
}
|
|
379
|
+
updateResizeHandlerStates("up", event);
|
|
358
380
|
recalculateIntersectingHandles({
|
|
381
|
+
target,
|
|
359
382
|
x,
|
|
360
383
|
y
|
|
361
384
|
});
|
|
362
|
-
updateResizeHandlerStates("up", event);
|
|
363
385
|
updateCursor();
|
|
364
386
|
updateListeners();
|
|
365
387
|
}
|
|
366
388
|
function recalculateIntersectingHandles({
|
|
389
|
+
target,
|
|
367
390
|
x,
|
|
368
391
|
y
|
|
369
392
|
}) {
|
|
370
393
|
intersectingHandles.splice(0);
|
|
394
|
+
let targetElement = null;
|
|
395
|
+
if (target instanceof HTMLElement) {
|
|
396
|
+
targetElement = target;
|
|
397
|
+
}
|
|
371
398
|
registeredResizeHandlers.forEach(data => {
|
|
372
399
|
const {
|
|
373
|
-
element,
|
|
400
|
+
element: dragHandleElement,
|
|
374
401
|
hitAreaMargins
|
|
375
402
|
} = data;
|
|
403
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
376
404
|
const {
|
|
377
405
|
bottom,
|
|
378
406
|
left,
|
|
379
407
|
right,
|
|
380
408
|
top
|
|
381
|
-
} =
|
|
409
|
+
} = dragHandleRect;
|
|
382
410
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
383
|
-
const
|
|
384
|
-
if (
|
|
411
|
+
const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
|
|
412
|
+
if (eventIntersects) {
|
|
413
|
+
// TRICKY
|
|
414
|
+
// We listen for pointers events at the root in order to support hit area margins
|
|
415
|
+
// (determining when the pointer is close enough to an element to be considered a "hit")
|
|
416
|
+
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
|
|
417
|
+
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
|
|
418
|
+
// and the element that was actually clicked/touched
|
|
419
|
+
if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
|
|
420
|
+
// Calculating stacking order has a cost, so we should avoid it if possible
|
|
421
|
+
// That is why we only check potentially intersecting handles,
|
|
422
|
+
// and why we skip if the event target is within the handle's DOM
|
|
423
|
+
compare(targetElement, dragHandleElement) > 0) {
|
|
424
|
+
// If the target is above the drag handle, then we also need to confirm they overlap
|
|
425
|
+
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
|
|
426
|
+
//
|
|
427
|
+
// It's not enough to compare only the target
|
|
428
|
+
// The target might be a small element inside of a larger container
|
|
429
|
+
// (For example, a SPAN or a DIV inside of a larger modal dialog)
|
|
430
|
+
let currentElement = targetElement;
|
|
431
|
+
let didIntersect = false;
|
|
432
|
+
while (currentElement) {
|
|
433
|
+
if (currentElement.contains(dragHandleElement)) {
|
|
434
|
+
break;
|
|
435
|
+
} else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
|
|
436
|
+
didIntersect = true;
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
currentElement = currentElement.parentElement;
|
|
440
|
+
}
|
|
441
|
+
if (didIntersect) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
385
445
|
intersectingHandles.push(data);
|
|
386
446
|
}
|
|
387
447
|
});
|
|
@@ -2129,4 +2189,21 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2129
2189
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2130
2190
|
}
|
|
2131
2191
|
|
|
2132
|
-
|
|
2192
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
2193
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
2194
|
+
return {
|
|
2195
|
+
x: 0,
|
|
2196
|
+
y: 0,
|
|
2197
|
+
width: 0,
|
|
2198
|
+
height: 0
|
|
2199
|
+
};
|
|
2200
|
+
}
|
|
2201
|
+
return {
|
|
2202
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2203
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2204
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2205
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
export { Panel, PanelGroup, PanelResizeHandle, assert, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects };
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
+
var stackingOrder = require('stacking-order');
|
|
6
7
|
|
|
7
8
|
function _interopNamespace(e) {
|
|
8
9
|
if (e && e.__esModule) return e;
|
|
@@ -296,6 +297,14 @@ function getInputType() {
|
|
|
296
297
|
}
|
|
297
298
|
}
|
|
298
299
|
|
|
300
|
+
function intersects(rectOne, rectTwo, strict) {
|
|
301
|
+
if (strict) {
|
|
302
|
+
return rectOne.x < rectTwo.x + rectTwo.width && rectOne.x + rectOne.width > rectTwo.x && rectOne.y < rectTwo.y + rectTwo.height && rectOne.y + rectOne.height > rectTwo.y;
|
|
303
|
+
} else {
|
|
304
|
+
return rectOne.x <= rectTwo.x + rectTwo.width && rectOne.x + rectOne.width >= rectTwo.x && rectOne.y <= rectTwo.y + rectTwo.height && rectOne.y + rectOne.height >= rectTwo.y;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
299
308
|
const EXCEEDED_HORIZONTAL_MIN = 0b0001;
|
|
300
309
|
const EXCEEDED_HORIZONTAL_MAX = 0b0010;
|
|
301
310
|
const EXCEEDED_VERTICAL_MIN = 0b0100;
|
|
@@ -334,12 +343,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
|
|
|
334
343
|
};
|
|
335
344
|
}
|
|
336
345
|
function handlePointerDown(event) {
|
|
346
|
+
const {
|
|
347
|
+
target
|
|
348
|
+
} = event;
|
|
337
349
|
const {
|
|
338
350
|
x,
|
|
339
351
|
y
|
|
340
352
|
} = getResizeEventCoordinates(event);
|
|
341
353
|
isPointerDown = true;
|
|
342
354
|
recalculateIntersectingHandles({
|
|
355
|
+
target,
|
|
343
356
|
x,
|
|
344
357
|
y
|
|
345
358
|
});
|
|
@@ -355,10 +368,15 @@ function handlePointerMove(event) {
|
|
|
355
368
|
y
|
|
356
369
|
} = getResizeEventCoordinates(event);
|
|
357
370
|
if (!isPointerDown) {
|
|
371
|
+
const {
|
|
372
|
+
target
|
|
373
|
+
} = event;
|
|
374
|
+
|
|
358
375
|
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
359
376
|
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
360
377
|
// but the same set of active handles should be locked until the pointer is released
|
|
361
378
|
recalculateIntersectingHandles({
|
|
379
|
+
target,
|
|
362
380
|
x,
|
|
363
381
|
y
|
|
364
382
|
});
|
|
@@ -372,6 +390,9 @@ function handlePointerMove(event) {
|
|
|
372
390
|
}
|
|
373
391
|
}
|
|
374
392
|
function handlePointerUp(event) {
|
|
393
|
+
const {
|
|
394
|
+
target
|
|
395
|
+
} = event;
|
|
375
396
|
const {
|
|
376
397
|
x,
|
|
377
398
|
y
|
|
@@ -381,33 +402,72 @@ function handlePointerUp(event) {
|
|
|
381
402
|
if (intersectingHandles.length > 0) {
|
|
382
403
|
event.preventDefault();
|
|
383
404
|
}
|
|
405
|
+
updateResizeHandlerStates("up", event);
|
|
384
406
|
recalculateIntersectingHandles({
|
|
407
|
+
target,
|
|
385
408
|
x,
|
|
386
409
|
y
|
|
387
410
|
});
|
|
388
|
-
updateResizeHandlerStates("up", event);
|
|
389
411
|
updateCursor();
|
|
390
412
|
updateListeners();
|
|
391
413
|
}
|
|
392
414
|
function recalculateIntersectingHandles({
|
|
415
|
+
target,
|
|
393
416
|
x,
|
|
394
417
|
y
|
|
395
418
|
}) {
|
|
396
419
|
intersectingHandles.splice(0);
|
|
420
|
+
let targetElement = null;
|
|
421
|
+
if (target instanceof HTMLElement) {
|
|
422
|
+
targetElement = target;
|
|
423
|
+
}
|
|
397
424
|
registeredResizeHandlers.forEach(data => {
|
|
398
425
|
const {
|
|
399
|
-
element,
|
|
426
|
+
element: dragHandleElement,
|
|
400
427
|
hitAreaMargins
|
|
401
428
|
} = data;
|
|
429
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
402
430
|
const {
|
|
403
431
|
bottom,
|
|
404
432
|
left,
|
|
405
433
|
right,
|
|
406
434
|
top
|
|
407
|
-
} =
|
|
435
|
+
} = dragHandleRect;
|
|
408
436
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
409
|
-
const
|
|
410
|
-
if (
|
|
437
|
+
const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
|
|
438
|
+
if (eventIntersects) {
|
|
439
|
+
// TRICKY
|
|
440
|
+
// We listen for pointers events at the root in order to support hit area margins
|
|
441
|
+
// (determining when the pointer is close enough to an element to be considered a "hit")
|
|
442
|
+
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
|
|
443
|
+
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
|
|
444
|
+
// and the element that was actually clicked/touched
|
|
445
|
+
if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
|
|
446
|
+
// Calculating stacking order has a cost, so we should avoid it if possible
|
|
447
|
+
// That is why we only check potentially intersecting handles,
|
|
448
|
+
// and why we skip if the event target is within the handle's DOM
|
|
449
|
+
stackingOrder.compare(targetElement, dragHandleElement) > 0) {
|
|
450
|
+
// If the target is above the drag handle, then we also need to confirm they overlap
|
|
451
|
+
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
|
|
452
|
+
//
|
|
453
|
+
// It's not enough to compare only the target
|
|
454
|
+
// The target might be a small element inside of a larger container
|
|
455
|
+
// (For example, a SPAN or a DIV inside of a larger modal dialog)
|
|
456
|
+
let currentElement = targetElement;
|
|
457
|
+
let didIntersect = false;
|
|
458
|
+
while (currentElement) {
|
|
459
|
+
if (currentElement.contains(dragHandleElement)) {
|
|
460
|
+
break;
|
|
461
|
+
} else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
|
|
462
|
+
didIntersect = true;
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
currentElement = currentElement.parentElement;
|
|
466
|
+
}
|
|
467
|
+
if (didIntersect) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
411
471
|
intersectingHandles.push(data);
|
|
412
472
|
}
|
|
413
473
|
});
|
|
@@ -2155,10 +2215,28 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2155
2215
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2156
2216
|
}
|
|
2157
2217
|
|
|
2218
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
2219
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
2220
|
+
return {
|
|
2221
|
+
x: 0,
|
|
2222
|
+
y: 0,
|
|
2223
|
+
width: 0,
|
|
2224
|
+
height: 0
|
|
2225
|
+
};
|
|
2226
|
+
}
|
|
2227
|
+
return {
|
|
2228
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2229
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2230
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2231
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2232
|
+
};
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2158
2235
|
exports.Panel = Panel;
|
|
2159
2236
|
exports.PanelGroup = PanelGroup;
|
|
2160
2237
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
2161
2238
|
exports.assert = assert;
|
|
2239
|
+
exports.getIntersectingRectangle = getIntersectingRectangle;
|
|
2162
2240
|
exports.getPanelElement = getPanelElement;
|
|
2163
2241
|
exports.getPanelElementsForGroup = getPanelElementsForGroup;
|
|
2164
2242
|
exports.getPanelGroupElement = getPanelGroupElement;
|
|
@@ -2166,3 +2244,4 @@ exports.getResizeHandleElement = getResizeHandleElement;
|
|
|
2166
2244
|
exports.getResizeHandleElementIndex = getResizeHandleElementIndex;
|
|
2167
2245
|
exports.getResizeHandleElementsForGroup = getResizeHandleElementsForGroup;
|
|
2168
2246
|
exports.getResizeHandlePanelIds = getResizeHandlePanelIds;
|
|
2247
|
+
exports.intersects = intersects;
|
|
@@ -3,11 +3,13 @@ export {
|
|
|
3
3
|
PanelGroup,
|
|
4
4
|
PanelResizeHandle,
|
|
5
5
|
assert,
|
|
6
|
+
getIntersectingRectangle,
|
|
6
7
|
getPanelElement,
|
|
7
8
|
getPanelElementsForGroup,
|
|
8
9
|
getPanelGroupElement,
|
|
9
10
|
getResizeHandleElement,
|
|
10
11
|
getResizeHandleElementIndex,
|
|
11
12
|
getResizeHandleElementsForGroup,
|
|
12
|
-
getResizeHandlePanelIds
|
|
13
|
+
getResizeHandlePanelIds,
|
|
14
|
+
intersects
|
|
13
15
|
} from "./react-resizable-panels.cjs.js";
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
+
var stackingOrder = require('stacking-order');
|
|
6
7
|
|
|
7
8
|
function _interopNamespace(e) {
|
|
8
9
|
if (e && e.__esModule) return e;
|
|
@@ -307,6 +308,14 @@ function getInputType() {
|
|
|
307
308
|
}
|
|
308
309
|
}
|
|
309
310
|
|
|
311
|
+
function intersects(rectOne, rectTwo, strict) {
|
|
312
|
+
if (strict) {
|
|
313
|
+
return rectOne.x < rectTwo.x + rectTwo.width && rectOne.x + rectOne.width > rectTwo.x && rectOne.y < rectTwo.y + rectTwo.height && rectOne.y + rectOne.height > rectTwo.y;
|
|
314
|
+
} else {
|
|
315
|
+
return rectOne.x <= rectTwo.x + rectTwo.width && rectOne.x + rectOne.width >= rectTwo.x && rectOne.y <= rectTwo.y + rectTwo.height && rectOne.y + rectOne.height >= rectTwo.y;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
310
319
|
const EXCEEDED_HORIZONTAL_MIN = 0b0001;
|
|
311
320
|
const EXCEEDED_HORIZONTAL_MAX = 0b0010;
|
|
312
321
|
const EXCEEDED_VERTICAL_MIN = 0b0100;
|
|
@@ -345,12 +354,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
|
|
|
345
354
|
};
|
|
346
355
|
}
|
|
347
356
|
function handlePointerDown(event) {
|
|
357
|
+
const {
|
|
358
|
+
target
|
|
359
|
+
} = event;
|
|
348
360
|
const {
|
|
349
361
|
x,
|
|
350
362
|
y
|
|
351
363
|
} = getResizeEventCoordinates(event);
|
|
352
364
|
isPointerDown = true;
|
|
353
365
|
recalculateIntersectingHandles({
|
|
366
|
+
target,
|
|
354
367
|
x,
|
|
355
368
|
y
|
|
356
369
|
});
|
|
@@ -366,10 +379,15 @@ function handlePointerMove(event) {
|
|
|
366
379
|
y
|
|
367
380
|
} = getResizeEventCoordinates(event);
|
|
368
381
|
if (!isPointerDown) {
|
|
382
|
+
const {
|
|
383
|
+
target
|
|
384
|
+
} = event;
|
|
385
|
+
|
|
369
386
|
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
370
387
|
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
371
388
|
// but the same set of active handles should be locked until the pointer is released
|
|
372
389
|
recalculateIntersectingHandles({
|
|
390
|
+
target,
|
|
373
391
|
x,
|
|
374
392
|
y
|
|
375
393
|
});
|
|
@@ -383,6 +401,9 @@ function handlePointerMove(event) {
|
|
|
383
401
|
}
|
|
384
402
|
}
|
|
385
403
|
function handlePointerUp(event) {
|
|
404
|
+
const {
|
|
405
|
+
target
|
|
406
|
+
} = event;
|
|
386
407
|
const {
|
|
387
408
|
x,
|
|
388
409
|
y
|
|
@@ -392,33 +413,72 @@ function handlePointerUp(event) {
|
|
|
392
413
|
if (intersectingHandles.length > 0) {
|
|
393
414
|
event.preventDefault();
|
|
394
415
|
}
|
|
416
|
+
updateResizeHandlerStates("up", event);
|
|
395
417
|
recalculateIntersectingHandles({
|
|
418
|
+
target,
|
|
396
419
|
x,
|
|
397
420
|
y
|
|
398
421
|
});
|
|
399
|
-
updateResizeHandlerStates("up", event);
|
|
400
422
|
updateCursor();
|
|
401
423
|
updateListeners();
|
|
402
424
|
}
|
|
403
425
|
function recalculateIntersectingHandles({
|
|
426
|
+
target,
|
|
404
427
|
x,
|
|
405
428
|
y
|
|
406
429
|
}) {
|
|
407
430
|
intersectingHandles.splice(0);
|
|
431
|
+
let targetElement = null;
|
|
432
|
+
if (target instanceof HTMLElement) {
|
|
433
|
+
targetElement = target;
|
|
434
|
+
}
|
|
408
435
|
registeredResizeHandlers.forEach(data => {
|
|
409
436
|
const {
|
|
410
|
-
element,
|
|
437
|
+
element: dragHandleElement,
|
|
411
438
|
hitAreaMargins
|
|
412
439
|
} = data;
|
|
440
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
413
441
|
const {
|
|
414
442
|
bottom,
|
|
415
443
|
left,
|
|
416
444
|
right,
|
|
417
445
|
top
|
|
418
|
-
} =
|
|
446
|
+
} = dragHandleRect;
|
|
419
447
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
420
|
-
const
|
|
421
|
-
if (
|
|
448
|
+
const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
|
|
449
|
+
if (eventIntersects) {
|
|
450
|
+
// TRICKY
|
|
451
|
+
// We listen for pointers events at the root in order to support hit area margins
|
|
452
|
+
// (determining when the pointer is close enough to an element to be considered a "hit")
|
|
453
|
+
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
|
|
454
|
+
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
|
|
455
|
+
// and the element that was actually clicked/touched
|
|
456
|
+
if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
|
|
457
|
+
// Calculating stacking order has a cost, so we should avoid it if possible
|
|
458
|
+
// That is why we only check potentially intersecting handles,
|
|
459
|
+
// and why we skip if the event target is within the handle's DOM
|
|
460
|
+
stackingOrder.compare(targetElement, dragHandleElement) > 0) {
|
|
461
|
+
// If the target is above the drag handle, then we also need to confirm they overlap
|
|
462
|
+
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
|
|
463
|
+
//
|
|
464
|
+
// It's not enough to compare only the target
|
|
465
|
+
// The target might be a small element inside of a larger container
|
|
466
|
+
// (For example, a SPAN or a DIV inside of a larger modal dialog)
|
|
467
|
+
let currentElement = targetElement;
|
|
468
|
+
let didIntersect = false;
|
|
469
|
+
while (currentElement) {
|
|
470
|
+
if (currentElement.contains(dragHandleElement)) {
|
|
471
|
+
break;
|
|
472
|
+
} else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
|
|
473
|
+
didIntersect = true;
|
|
474
|
+
break;
|
|
475
|
+
}
|
|
476
|
+
currentElement = currentElement.parentElement;
|
|
477
|
+
}
|
|
478
|
+
if (didIntersect) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
422
482
|
intersectingHandles.push(data);
|
|
423
483
|
}
|
|
424
484
|
});
|
|
@@ -2266,10 +2326,28 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2266
2326
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2267
2327
|
}
|
|
2268
2328
|
|
|
2329
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
2330
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
2331
|
+
return {
|
|
2332
|
+
x: 0,
|
|
2333
|
+
y: 0,
|
|
2334
|
+
width: 0,
|
|
2335
|
+
height: 0
|
|
2336
|
+
};
|
|
2337
|
+
}
|
|
2338
|
+
return {
|
|
2339
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2340
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2341
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2342
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2343
|
+
};
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2269
2346
|
exports.Panel = Panel;
|
|
2270
2347
|
exports.PanelGroup = PanelGroup;
|
|
2271
2348
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
2272
2349
|
exports.assert = assert;
|
|
2350
|
+
exports.getIntersectingRectangle = getIntersectingRectangle;
|
|
2273
2351
|
exports.getPanelElement = getPanelElement;
|
|
2274
2352
|
exports.getPanelElementsForGroup = getPanelElementsForGroup;
|
|
2275
2353
|
exports.getPanelGroupElement = getPanelGroupElement;
|
|
@@ -2277,3 +2355,4 @@ exports.getResizeHandleElement = getResizeHandleElement;
|
|
|
2277
2355
|
exports.getResizeHandleElementIndex = getResizeHandleElementIndex;
|
|
2278
2356
|
exports.getResizeHandleElementsForGroup = getResizeHandleElementsForGroup;
|
|
2279
2357
|
exports.getResizeHandlePanelIds = getResizeHandlePanelIds;
|
|
2358
|
+
exports.intersects = intersects;
|
|
@@ -3,11 +3,13 @@ export {
|
|
|
3
3
|
PanelGroup,
|
|
4
4
|
PanelResizeHandle,
|
|
5
5
|
assert,
|
|
6
|
+
getIntersectingRectangle,
|
|
6
7
|
getPanelElement,
|
|
7
8
|
getPanelElementsForGroup,
|
|
8
9
|
getPanelGroupElement,
|
|
9
10
|
getResizeHandleElement,
|
|
10
11
|
getResizeHandleElementIndex,
|
|
11
12
|
getResizeHandleElementsForGroup,
|
|
12
|
-
getResizeHandlePanelIds
|
|
13
|
+
getResizeHandlePanelIds,
|
|
14
|
+
intersects
|
|
13
15
|
} from "./react-resizable-panels.development.cjs.js";
|