react-resizable-panels 2.0.3 → 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 +8 -0
- package/dist/declarations/src/PanelResizeHandle.d.ts +1 -0
- package/dist/declarations/src/PanelResizeHandleRegistry.d.ts +1 -2
- 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 +138 -56
- package/dist/react-resizable-panels.browser.cjs.mjs +3 -1
- package/dist/react-resizable-panels.browser.development.cjs.js +138 -56
- package/dist/react-resizable-panels.browser.development.cjs.mjs +3 -1
- package/dist/react-resizable-panels.browser.development.esm.js +137 -57
- package/dist/react-resizable-panels.browser.esm.js +137 -57
- package/dist/react-resizable-panels.cjs.js +138 -56
- package/dist/react-resizable-panels.cjs.mjs +3 -1
- package/dist/react-resizable-panels.development.cjs.js +138 -56
- package/dist/react-resizable-panels.development.cjs.mjs +3 -1
- package/dist/react-resizable-panels.development.esm.js +137 -57
- package/dist/react-resizable-panels.development.node.cjs.js +138 -56
- package/dist/react-resizable-panels.development.node.cjs.mjs +3 -1
- package/dist/react-resizable-panels.development.node.esm.js +137 -57
- package/dist/react-resizable-panels.esm.js +137 -57
- package/dist/react-resizable-panels.node.cjs.js +138 -56
- package/dist/react-resizable-panels.node.cjs.mjs +3 -1
- package/dist/react-resizable-panels.node.esm.js +137 -57
- package/package.json +4 -1
- package/src/Panel.test.tsx +63 -0
- package/src/PanelGroup.test.tsx +21 -1
- package/src/PanelResizeHandle.test.tsx +181 -22
- package/src/PanelResizeHandle.ts +44 -24
- package/src/PanelResizeHandleRegistry.ts +87 -30
- 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
- package/src/utils/test-utils.ts +39 -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
|
});
|
|
@@ -328,29 +341,32 @@ function handlePointerMove(event) {
|
|
|
328
341
|
x,
|
|
329
342
|
y
|
|
330
343
|
} = getResizeEventCoordinates(event);
|
|
331
|
-
if (isPointerDown) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
} = data;
|
|
336
|
-
setResizeHandlerState("move", "drag", event);
|
|
337
|
-
});
|
|
344
|
+
if (!isPointerDown) {
|
|
345
|
+
const {
|
|
346
|
+
target
|
|
347
|
+
} = event;
|
|
338
348
|
|
|
339
|
-
//
|
|
340
|
-
|
|
341
|
-
|
|
349
|
+
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
350
|
+
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
351
|
+
// but the same set of active handles should be locked until the pointer is released
|
|
342
352
|
recalculateIntersectingHandles({
|
|
353
|
+
target,
|
|
343
354
|
x,
|
|
344
355
|
y
|
|
345
356
|
});
|
|
346
|
-
updateResizeHandlerStates("move", event);
|
|
347
|
-
updateCursor();
|
|
348
357
|
}
|
|
358
|
+
updateResizeHandlerStates("move", event);
|
|
359
|
+
|
|
360
|
+
// Update cursor based on return value(s) from active handles
|
|
361
|
+
updateCursor();
|
|
349
362
|
if (intersectingHandles.length > 0) {
|
|
350
363
|
event.preventDefault();
|
|
351
364
|
}
|
|
352
365
|
}
|
|
353
366
|
function handlePointerUp(event) {
|
|
367
|
+
const {
|
|
368
|
+
target
|
|
369
|
+
} = event;
|
|
354
370
|
const {
|
|
355
371
|
x,
|
|
356
372
|
y
|
|
@@ -360,33 +376,72 @@ function handlePointerUp(event) {
|
|
|
360
376
|
if (intersectingHandles.length > 0) {
|
|
361
377
|
event.preventDefault();
|
|
362
378
|
}
|
|
379
|
+
updateResizeHandlerStates("up", event);
|
|
363
380
|
recalculateIntersectingHandles({
|
|
381
|
+
target,
|
|
364
382
|
x,
|
|
365
383
|
y
|
|
366
384
|
});
|
|
367
|
-
updateResizeHandlerStates("up", event);
|
|
368
385
|
updateCursor();
|
|
369
386
|
updateListeners();
|
|
370
387
|
}
|
|
371
388
|
function recalculateIntersectingHandles({
|
|
389
|
+
target,
|
|
372
390
|
x,
|
|
373
391
|
y
|
|
374
392
|
}) {
|
|
375
393
|
intersectingHandles.splice(0);
|
|
394
|
+
let targetElement = null;
|
|
395
|
+
if (target instanceof HTMLElement) {
|
|
396
|
+
targetElement = target;
|
|
397
|
+
}
|
|
376
398
|
registeredResizeHandlers.forEach(data => {
|
|
377
399
|
const {
|
|
378
|
-
element,
|
|
400
|
+
element: dragHandleElement,
|
|
379
401
|
hitAreaMargins
|
|
380
402
|
} = data;
|
|
403
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
381
404
|
const {
|
|
382
405
|
bottom,
|
|
383
406
|
left,
|
|
384
407
|
right,
|
|
385
408
|
top
|
|
386
|
-
} =
|
|
409
|
+
} = dragHandleRect;
|
|
387
410
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
388
|
-
const
|
|
389
|
-
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
|
+
}
|
|
390
445
|
intersectingHandles.push(data);
|
|
391
446
|
}
|
|
392
447
|
});
|
|
@@ -478,15 +533,8 @@ function updateResizeHandlerStates(action, event) {
|
|
|
478
533
|
const {
|
|
479
534
|
setResizeHandlerState
|
|
480
535
|
} = data;
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
setResizeHandlerState(action, "drag", event);
|
|
484
|
-
} else {
|
|
485
|
-
setResizeHandlerState(action, "hover", event);
|
|
486
|
-
}
|
|
487
|
-
} else {
|
|
488
|
-
setResizeHandlerState(action, "inactive", event);
|
|
489
|
-
}
|
|
536
|
+
const isActive = intersectingHandles.includes(data);
|
|
537
|
+
setResizeHandlerState(action, isActive, event);
|
|
490
538
|
});
|
|
491
539
|
}
|
|
492
540
|
|
|
@@ -2023,6 +2071,12 @@ function PanelResizeHandle({
|
|
|
2023
2071
|
const [state, setState] = useState("inactive");
|
|
2024
2072
|
const [isFocused, setIsFocused] = useState(false);
|
|
2025
2073
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
2074
|
+
const committedValuesRef = useRef({
|
|
2075
|
+
state
|
|
2076
|
+
});
|
|
2077
|
+
useLayoutEffect(() => {
|
|
2078
|
+
committedValuesRef.current.state = state;
|
|
2079
|
+
});
|
|
2026
2080
|
useEffect(() => {
|
|
2027
2081
|
if (disabled) {
|
|
2028
2082
|
setResizeHandler(null);
|
|
@@ -2038,38 +2092,47 @@ function PanelResizeHandle({
|
|
|
2038
2092
|
}
|
|
2039
2093
|
const element = elementRef.current;
|
|
2040
2094
|
assert(element);
|
|
2041
|
-
const setResizeHandlerState = (action,
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
onDragging
|
|
2095
|
+
const setResizeHandlerState = (action, isActive, event) => {
|
|
2096
|
+
if (isActive) {
|
|
2097
|
+
switch (action) {
|
|
2098
|
+
case "down":
|
|
2099
|
+
{
|
|
2100
|
+
setState("drag");
|
|
2101
|
+
startDragging(resizeHandleId, event);
|
|
2102
|
+
const {
|
|
2103
|
+
onDragging
|
|
2104
|
+
} = callbacksRef.current;
|
|
2105
|
+
if (onDragging) {
|
|
2106
|
+
onDragging(true);
|
|
2107
|
+
}
|
|
2108
|
+
break;
|
|
2052
2109
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2110
|
+
case "move":
|
|
2111
|
+
{
|
|
2112
|
+
const {
|
|
2113
|
+
state
|
|
2114
|
+
} = committedValuesRef.current;
|
|
2115
|
+
if (state !== "drag") {
|
|
2116
|
+
setState("hover");
|
|
2117
|
+
}
|
|
2118
|
+
resizeHandler(event);
|
|
2119
|
+
break;
|
|
2063
2120
|
}
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2121
|
+
case "up":
|
|
2122
|
+
{
|
|
2123
|
+
setState("hover");
|
|
2124
|
+
stopDragging();
|
|
2125
|
+
const {
|
|
2126
|
+
onDragging
|
|
2127
|
+
} = callbacksRef.current;
|
|
2128
|
+
if (onDragging) {
|
|
2129
|
+
onDragging(false);
|
|
2130
|
+
}
|
|
2131
|
+
break;
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
} else {
|
|
2135
|
+
setState("inactive");
|
|
2073
2136
|
}
|
|
2074
2137
|
};
|
|
2075
2138
|
return registerResizeHandle(resizeHandleId, element, direction, {
|
|
@@ -2126,4 +2189,21 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2126
2189
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2127
2190
|
}
|
|
2128
2191
|
|
|
2129
|
-
|
|
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
|
});
|
|
@@ -354,29 +367,32 @@ function handlePointerMove(event) {
|
|
|
354
367
|
x,
|
|
355
368
|
y
|
|
356
369
|
} = getResizeEventCoordinates(event);
|
|
357
|
-
if (isPointerDown) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
} = data;
|
|
362
|
-
setResizeHandlerState("move", "drag", event);
|
|
363
|
-
});
|
|
370
|
+
if (!isPointerDown) {
|
|
371
|
+
const {
|
|
372
|
+
target
|
|
373
|
+
} = event;
|
|
364
374
|
|
|
365
|
-
//
|
|
366
|
-
|
|
367
|
-
|
|
375
|
+
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
376
|
+
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
377
|
+
// but the same set of active handles should be locked until the pointer is released
|
|
368
378
|
recalculateIntersectingHandles({
|
|
379
|
+
target,
|
|
369
380
|
x,
|
|
370
381
|
y
|
|
371
382
|
});
|
|
372
|
-
updateResizeHandlerStates("move", event);
|
|
373
|
-
updateCursor();
|
|
374
383
|
}
|
|
384
|
+
updateResizeHandlerStates("move", event);
|
|
385
|
+
|
|
386
|
+
// Update cursor based on return value(s) from active handles
|
|
387
|
+
updateCursor();
|
|
375
388
|
if (intersectingHandles.length > 0) {
|
|
376
389
|
event.preventDefault();
|
|
377
390
|
}
|
|
378
391
|
}
|
|
379
392
|
function handlePointerUp(event) {
|
|
393
|
+
const {
|
|
394
|
+
target
|
|
395
|
+
} = event;
|
|
380
396
|
const {
|
|
381
397
|
x,
|
|
382
398
|
y
|
|
@@ -386,33 +402,72 @@ function handlePointerUp(event) {
|
|
|
386
402
|
if (intersectingHandles.length > 0) {
|
|
387
403
|
event.preventDefault();
|
|
388
404
|
}
|
|
405
|
+
updateResizeHandlerStates("up", event);
|
|
389
406
|
recalculateIntersectingHandles({
|
|
407
|
+
target,
|
|
390
408
|
x,
|
|
391
409
|
y
|
|
392
410
|
});
|
|
393
|
-
updateResizeHandlerStates("up", event);
|
|
394
411
|
updateCursor();
|
|
395
412
|
updateListeners();
|
|
396
413
|
}
|
|
397
414
|
function recalculateIntersectingHandles({
|
|
415
|
+
target,
|
|
398
416
|
x,
|
|
399
417
|
y
|
|
400
418
|
}) {
|
|
401
419
|
intersectingHandles.splice(0);
|
|
420
|
+
let targetElement = null;
|
|
421
|
+
if (target instanceof HTMLElement) {
|
|
422
|
+
targetElement = target;
|
|
423
|
+
}
|
|
402
424
|
registeredResizeHandlers.forEach(data => {
|
|
403
425
|
const {
|
|
404
|
-
element,
|
|
426
|
+
element: dragHandleElement,
|
|
405
427
|
hitAreaMargins
|
|
406
428
|
} = data;
|
|
429
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
407
430
|
const {
|
|
408
431
|
bottom,
|
|
409
432
|
left,
|
|
410
433
|
right,
|
|
411
434
|
top
|
|
412
|
-
} =
|
|
435
|
+
} = dragHandleRect;
|
|
413
436
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
414
|
-
const
|
|
415
|
-
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
|
+
}
|
|
416
471
|
intersectingHandles.push(data);
|
|
417
472
|
}
|
|
418
473
|
});
|
|
@@ -504,15 +559,8 @@ function updateResizeHandlerStates(action, event) {
|
|
|
504
559
|
const {
|
|
505
560
|
setResizeHandlerState
|
|
506
561
|
} = data;
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
setResizeHandlerState(action, "drag", event);
|
|
510
|
-
} else {
|
|
511
|
-
setResizeHandlerState(action, "hover", event);
|
|
512
|
-
}
|
|
513
|
-
} else {
|
|
514
|
-
setResizeHandlerState(action, "inactive", event);
|
|
515
|
-
}
|
|
562
|
+
const isActive = intersectingHandles.includes(data);
|
|
563
|
+
setResizeHandlerState(action, isActive, event);
|
|
516
564
|
});
|
|
517
565
|
}
|
|
518
566
|
|
|
@@ -2049,6 +2097,12 @@ function PanelResizeHandle({
|
|
|
2049
2097
|
const [state, setState] = useState("inactive");
|
|
2050
2098
|
const [isFocused, setIsFocused] = useState(false);
|
|
2051
2099
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
2100
|
+
const committedValuesRef = useRef({
|
|
2101
|
+
state
|
|
2102
|
+
});
|
|
2103
|
+
useLayoutEffect(() => {
|
|
2104
|
+
committedValuesRef.current.state = state;
|
|
2105
|
+
});
|
|
2052
2106
|
useEffect(() => {
|
|
2053
2107
|
if (disabled) {
|
|
2054
2108
|
setResizeHandler(null);
|
|
@@ -2064,38 +2118,47 @@ function PanelResizeHandle({
|
|
|
2064
2118
|
}
|
|
2065
2119
|
const element = elementRef.current;
|
|
2066
2120
|
assert(element);
|
|
2067
|
-
const setResizeHandlerState = (action,
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
onDragging
|
|
2121
|
+
const setResizeHandlerState = (action, isActive, event) => {
|
|
2122
|
+
if (isActive) {
|
|
2123
|
+
switch (action) {
|
|
2124
|
+
case "down":
|
|
2125
|
+
{
|
|
2126
|
+
setState("drag");
|
|
2127
|
+
startDragging(resizeHandleId, event);
|
|
2128
|
+
const {
|
|
2129
|
+
onDragging
|
|
2130
|
+
} = callbacksRef.current;
|
|
2131
|
+
if (onDragging) {
|
|
2132
|
+
onDragging(true);
|
|
2133
|
+
}
|
|
2134
|
+
break;
|
|
2078
2135
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2136
|
+
case "move":
|
|
2137
|
+
{
|
|
2138
|
+
const {
|
|
2139
|
+
state
|
|
2140
|
+
} = committedValuesRef.current;
|
|
2141
|
+
if (state !== "drag") {
|
|
2142
|
+
setState("hover");
|
|
2143
|
+
}
|
|
2144
|
+
resizeHandler(event);
|
|
2145
|
+
break;
|
|
2089
2146
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2147
|
+
case "up":
|
|
2148
|
+
{
|
|
2149
|
+
setState("hover");
|
|
2150
|
+
stopDragging();
|
|
2151
|
+
const {
|
|
2152
|
+
onDragging
|
|
2153
|
+
} = callbacksRef.current;
|
|
2154
|
+
if (onDragging) {
|
|
2155
|
+
onDragging(false);
|
|
2156
|
+
}
|
|
2157
|
+
break;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
} else {
|
|
2161
|
+
setState("inactive");
|
|
2099
2162
|
}
|
|
2100
2163
|
};
|
|
2101
2164
|
return registerResizeHandle(resizeHandleId, element, direction, {
|
|
@@ -2152,10 +2215,28 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2152
2215
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2153
2216
|
}
|
|
2154
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
|
+
|
|
2155
2235
|
exports.Panel = Panel;
|
|
2156
2236
|
exports.PanelGroup = PanelGroup;
|
|
2157
2237
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
2158
2238
|
exports.assert = assert;
|
|
2239
|
+
exports.getIntersectingRectangle = getIntersectingRectangle;
|
|
2159
2240
|
exports.getPanelElement = getPanelElement;
|
|
2160
2241
|
exports.getPanelElementsForGroup = getPanelElementsForGroup;
|
|
2161
2242
|
exports.getPanelGroupElement = getPanelGroupElement;
|
|
@@ -2163,3 +2244,4 @@ exports.getResizeHandleElement = getResizeHandleElement;
|
|
|
2163
2244
|
exports.getResizeHandleElementIndex = getResizeHandleElementIndex;
|
|
2164
2245
|
exports.getResizeHandleElementsForGroup = getResizeHandleElementsForGroup;
|
|
2165
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";
|