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
|
const isBrowser = typeof window !== "undefined";
|
|
4
5
|
|
|
@@ -272,6 +273,14 @@ function getInputType() {
|
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
|
|
276
|
+
function intersects(rectOne, rectTwo, strict) {
|
|
277
|
+
if (strict) {
|
|
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
|
+
} else {
|
|
280
|
+
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;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
275
284
|
const EXCEEDED_HORIZONTAL_MIN = 0b0001;
|
|
276
285
|
const EXCEEDED_HORIZONTAL_MAX = 0b0010;
|
|
277
286
|
const EXCEEDED_VERTICAL_MIN = 0b0100;
|
|
@@ -310,12 +319,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
|
|
|
310
319
|
};
|
|
311
320
|
}
|
|
312
321
|
function handlePointerDown(event) {
|
|
322
|
+
const {
|
|
323
|
+
target
|
|
324
|
+
} = event;
|
|
313
325
|
const {
|
|
314
326
|
x,
|
|
315
327
|
y
|
|
316
328
|
} = getResizeEventCoordinates(event);
|
|
317
329
|
isPointerDown = true;
|
|
318
330
|
recalculateIntersectingHandles({
|
|
331
|
+
target,
|
|
319
332
|
x,
|
|
320
333
|
y
|
|
321
334
|
});
|
|
@@ -330,29 +343,32 @@ function handlePointerMove(event) {
|
|
|
330
343
|
x,
|
|
331
344
|
y
|
|
332
345
|
} = getResizeEventCoordinates(event);
|
|
333
|
-
if (isPointerDown) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
} = data;
|
|
338
|
-
setResizeHandlerState("move", "drag", event);
|
|
339
|
-
});
|
|
346
|
+
if (!isPointerDown) {
|
|
347
|
+
const {
|
|
348
|
+
target
|
|
349
|
+
} = event;
|
|
340
350
|
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
351
|
+
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
352
|
+
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
353
|
+
// but the same set of active handles should be locked until the pointer is released
|
|
344
354
|
recalculateIntersectingHandles({
|
|
355
|
+
target,
|
|
345
356
|
x,
|
|
346
357
|
y
|
|
347
358
|
});
|
|
348
|
-
updateResizeHandlerStates("move", event);
|
|
349
|
-
updateCursor();
|
|
350
359
|
}
|
|
360
|
+
updateResizeHandlerStates("move", event);
|
|
361
|
+
|
|
362
|
+
// Update cursor based on return value(s) from active handles
|
|
363
|
+
updateCursor();
|
|
351
364
|
if (intersectingHandles.length > 0) {
|
|
352
365
|
event.preventDefault();
|
|
353
366
|
}
|
|
354
367
|
}
|
|
355
368
|
function handlePointerUp(event) {
|
|
369
|
+
const {
|
|
370
|
+
target
|
|
371
|
+
} = event;
|
|
356
372
|
const {
|
|
357
373
|
x,
|
|
358
374
|
y
|
|
@@ -362,33 +378,72 @@ function handlePointerUp(event) {
|
|
|
362
378
|
if (intersectingHandles.length > 0) {
|
|
363
379
|
event.preventDefault();
|
|
364
380
|
}
|
|
381
|
+
updateResizeHandlerStates("up", event);
|
|
365
382
|
recalculateIntersectingHandles({
|
|
383
|
+
target,
|
|
366
384
|
x,
|
|
367
385
|
y
|
|
368
386
|
});
|
|
369
|
-
updateResizeHandlerStates("up", event);
|
|
370
387
|
updateCursor();
|
|
371
388
|
updateListeners();
|
|
372
389
|
}
|
|
373
390
|
function recalculateIntersectingHandles({
|
|
391
|
+
target,
|
|
374
392
|
x,
|
|
375
393
|
y
|
|
376
394
|
}) {
|
|
377
395
|
intersectingHandles.splice(0);
|
|
396
|
+
let targetElement = null;
|
|
397
|
+
if (target instanceof HTMLElement) {
|
|
398
|
+
targetElement = target;
|
|
399
|
+
}
|
|
378
400
|
registeredResizeHandlers.forEach(data => {
|
|
379
401
|
const {
|
|
380
|
-
element,
|
|
402
|
+
element: dragHandleElement,
|
|
381
403
|
hitAreaMargins
|
|
382
404
|
} = data;
|
|
405
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
383
406
|
const {
|
|
384
407
|
bottom,
|
|
385
408
|
left,
|
|
386
409
|
right,
|
|
387
410
|
top
|
|
388
|
-
} =
|
|
411
|
+
} = dragHandleRect;
|
|
389
412
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
390
|
-
const
|
|
391
|
-
if (
|
|
413
|
+
const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
|
|
414
|
+
if (eventIntersects) {
|
|
415
|
+
// TRICKY
|
|
416
|
+
// We listen for pointers events at the root in order to support hit area margins
|
|
417
|
+
// (determining when the pointer is close enough to an element to be considered a "hit")
|
|
418
|
+
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
|
|
419
|
+
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
|
|
420
|
+
// and the element that was actually clicked/touched
|
|
421
|
+
if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
|
|
422
|
+
// Calculating stacking order has a cost, so we should avoid it if possible
|
|
423
|
+
// That is why we only check potentially intersecting handles,
|
|
424
|
+
// and why we skip if the event target is within the handle's DOM
|
|
425
|
+
compare(targetElement, dragHandleElement) > 0) {
|
|
426
|
+
// If the target is above the drag handle, then we also need to confirm they overlap
|
|
427
|
+
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
|
|
428
|
+
//
|
|
429
|
+
// It's not enough to compare only the target
|
|
430
|
+
// The target might be a small element inside of a larger container
|
|
431
|
+
// (For example, a SPAN or a DIV inside of a larger modal dialog)
|
|
432
|
+
let currentElement = targetElement;
|
|
433
|
+
let didIntersect = false;
|
|
434
|
+
while (currentElement) {
|
|
435
|
+
if (currentElement.contains(dragHandleElement)) {
|
|
436
|
+
break;
|
|
437
|
+
} else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
|
|
438
|
+
didIntersect = true;
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
currentElement = currentElement.parentElement;
|
|
442
|
+
}
|
|
443
|
+
if (didIntersect) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
392
447
|
intersectingHandles.push(data);
|
|
393
448
|
}
|
|
394
449
|
});
|
|
@@ -480,15 +535,8 @@ function updateResizeHandlerStates(action, event) {
|
|
|
480
535
|
const {
|
|
481
536
|
setResizeHandlerState
|
|
482
537
|
} = data;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
setResizeHandlerState(action, "drag", event);
|
|
486
|
-
} else {
|
|
487
|
-
setResizeHandlerState(action, "hover", event);
|
|
488
|
-
}
|
|
489
|
-
} else {
|
|
490
|
-
setResizeHandlerState(action, "inactive", event);
|
|
491
|
-
}
|
|
538
|
+
const isActive = intersectingHandles.includes(data);
|
|
539
|
+
setResizeHandlerState(action, isActive, event);
|
|
492
540
|
});
|
|
493
541
|
}
|
|
494
542
|
|
|
@@ -2025,6 +2073,12 @@ function PanelResizeHandle({
|
|
|
2025
2073
|
const [state, setState] = useState("inactive");
|
|
2026
2074
|
const [isFocused, setIsFocused] = useState(false);
|
|
2027
2075
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
2076
|
+
const committedValuesRef = useRef({
|
|
2077
|
+
state
|
|
2078
|
+
});
|
|
2079
|
+
useLayoutEffect(() => {
|
|
2080
|
+
committedValuesRef.current.state = state;
|
|
2081
|
+
});
|
|
2028
2082
|
useEffect(() => {
|
|
2029
2083
|
if (disabled) {
|
|
2030
2084
|
setResizeHandler(null);
|
|
@@ -2040,38 +2094,47 @@ function PanelResizeHandle({
|
|
|
2040
2094
|
}
|
|
2041
2095
|
const element = elementRef.current;
|
|
2042
2096
|
assert(element);
|
|
2043
|
-
const setResizeHandlerState = (action,
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
onDragging
|
|
2097
|
+
const setResizeHandlerState = (action, isActive, event) => {
|
|
2098
|
+
if (isActive) {
|
|
2099
|
+
switch (action) {
|
|
2100
|
+
case "down":
|
|
2101
|
+
{
|
|
2102
|
+
setState("drag");
|
|
2103
|
+
startDragging(resizeHandleId, event);
|
|
2104
|
+
const {
|
|
2105
|
+
onDragging
|
|
2106
|
+
} = callbacksRef.current;
|
|
2107
|
+
if (onDragging) {
|
|
2108
|
+
onDragging(true);
|
|
2109
|
+
}
|
|
2110
|
+
break;
|
|
2054
2111
|
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2112
|
+
case "move":
|
|
2113
|
+
{
|
|
2114
|
+
const {
|
|
2115
|
+
state
|
|
2116
|
+
} = committedValuesRef.current;
|
|
2117
|
+
if (state !== "drag") {
|
|
2118
|
+
setState("hover");
|
|
2119
|
+
}
|
|
2120
|
+
resizeHandler(event);
|
|
2121
|
+
break;
|
|
2065
2122
|
}
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2123
|
+
case "up":
|
|
2124
|
+
{
|
|
2125
|
+
setState("hover");
|
|
2126
|
+
stopDragging();
|
|
2127
|
+
const {
|
|
2128
|
+
onDragging
|
|
2129
|
+
} = callbacksRef.current;
|
|
2130
|
+
if (onDragging) {
|
|
2131
|
+
onDragging(false);
|
|
2132
|
+
}
|
|
2133
|
+
break;
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
} else {
|
|
2137
|
+
setState("inactive");
|
|
2075
2138
|
}
|
|
2076
2139
|
};
|
|
2077
2140
|
return registerResizeHandle(resizeHandleId, element, direction, {
|
|
@@ -2128,4 +2191,21 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2128
2191
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2129
2192
|
}
|
|
2130
2193
|
|
|
2131
|
-
|
|
2194
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
2195
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
2196
|
+
return {
|
|
2197
|
+
x: 0,
|
|
2198
|
+
y: 0,
|
|
2199
|
+
width: 0,
|
|
2200
|
+
height: 0
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
return {
|
|
2204
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2205
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2206
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2207
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2208
|
+
};
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
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;
|
|
@@ -259,6 +260,14 @@ function getInputType() {
|
|
|
259
260
|
}
|
|
260
261
|
}
|
|
261
262
|
|
|
263
|
+
function intersects(rectOne, rectTwo, strict) {
|
|
264
|
+
if (strict) {
|
|
265
|
+
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;
|
|
266
|
+
} else {
|
|
267
|
+
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;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
262
271
|
const EXCEEDED_HORIZONTAL_MIN = 0b0001;
|
|
263
272
|
const EXCEEDED_HORIZONTAL_MAX = 0b0010;
|
|
264
273
|
const EXCEEDED_VERTICAL_MIN = 0b0100;
|
|
@@ -297,12 +306,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
|
|
|
297
306
|
};
|
|
298
307
|
}
|
|
299
308
|
function handlePointerDown(event) {
|
|
309
|
+
const {
|
|
310
|
+
target
|
|
311
|
+
} = event;
|
|
300
312
|
const {
|
|
301
313
|
x,
|
|
302
314
|
y
|
|
303
315
|
} = getResizeEventCoordinates(event);
|
|
304
316
|
isPointerDown = true;
|
|
305
317
|
recalculateIntersectingHandles({
|
|
318
|
+
target,
|
|
306
319
|
x,
|
|
307
320
|
y
|
|
308
321
|
});
|
|
@@ -317,29 +330,32 @@ function handlePointerMove(event) {
|
|
|
317
330
|
x,
|
|
318
331
|
y
|
|
319
332
|
} = getResizeEventCoordinates(event);
|
|
320
|
-
if (isPointerDown) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
} = data;
|
|
325
|
-
setResizeHandlerState("move", "drag", event);
|
|
326
|
-
});
|
|
333
|
+
if (!isPointerDown) {
|
|
334
|
+
const {
|
|
335
|
+
target
|
|
336
|
+
} = event;
|
|
327
337
|
|
|
328
|
-
//
|
|
329
|
-
|
|
330
|
-
|
|
338
|
+
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
339
|
+
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
340
|
+
// but the same set of active handles should be locked until the pointer is released
|
|
331
341
|
recalculateIntersectingHandles({
|
|
342
|
+
target,
|
|
332
343
|
x,
|
|
333
344
|
y
|
|
334
345
|
});
|
|
335
|
-
updateResizeHandlerStates("move", event);
|
|
336
|
-
updateCursor();
|
|
337
346
|
}
|
|
347
|
+
updateResizeHandlerStates("move", event);
|
|
348
|
+
|
|
349
|
+
// Update cursor based on return value(s) from active handles
|
|
350
|
+
updateCursor();
|
|
338
351
|
if (intersectingHandles.length > 0) {
|
|
339
352
|
event.preventDefault();
|
|
340
353
|
}
|
|
341
354
|
}
|
|
342
355
|
function handlePointerUp(event) {
|
|
356
|
+
const {
|
|
357
|
+
target
|
|
358
|
+
} = event;
|
|
343
359
|
const {
|
|
344
360
|
x,
|
|
345
361
|
y
|
|
@@ -349,33 +365,72 @@ function handlePointerUp(event) {
|
|
|
349
365
|
if (intersectingHandles.length > 0) {
|
|
350
366
|
event.preventDefault();
|
|
351
367
|
}
|
|
368
|
+
updateResizeHandlerStates("up", event);
|
|
352
369
|
recalculateIntersectingHandles({
|
|
370
|
+
target,
|
|
353
371
|
x,
|
|
354
372
|
y
|
|
355
373
|
});
|
|
356
|
-
updateResizeHandlerStates("up", event);
|
|
357
374
|
updateCursor();
|
|
358
375
|
updateListeners();
|
|
359
376
|
}
|
|
360
377
|
function recalculateIntersectingHandles({
|
|
378
|
+
target,
|
|
361
379
|
x,
|
|
362
380
|
y
|
|
363
381
|
}) {
|
|
364
382
|
intersectingHandles.splice(0);
|
|
383
|
+
let targetElement = null;
|
|
384
|
+
if (target instanceof HTMLElement) {
|
|
385
|
+
targetElement = target;
|
|
386
|
+
}
|
|
365
387
|
registeredResizeHandlers.forEach(data => {
|
|
366
388
|
const {
|
|
367
|
-
element,
|
|
389
|
+
element: dragHandleElement,
|
|
368
390
|
hitAreaMargins
|
|
369
391
|
} = data;
|
|
392
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
370
393
|
const {
|
|
371
394
|
bottom,
|
|
372
395
|
left,
|
|
373
396
|
right,
|
|
374
397
|
top
|
|
375
|
-
} =
|
|
398
|
+
} = dragHandleRect;
|
|
376
399
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
377
|
-
const
|
|
378
|
-
if (
|
|
400
|
+
const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
|
|
401
|
+
if (eventIntersects) {
|
|
402
|
+
// TRICKY
|
|
403
|
+
// We listen for pointers events at the root in order to support hit area margins
|
|
404
|
+
// (determining when the pointer is close enough to an element to be considered a "hit")
|
|
405
|
+
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
|
|
406
|
+
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
|
|
407
|
+
// and the element that was actually clicked/touched
|
|
408
|
+
if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
|
|
409
|
+
// Calculating stacking order has a cost, so we should avoid it if possible
|
|
410
|
+
// That is why we only check potentially intersecting handles,
|
|
411
|
+
// and why we skip if the event target is within the handle's DOM
|
|
412
|
+
stackingOrder.compare(targetElement, dragHandleElement) > 0) {
|
|
413
|
+
// If the target is above the drag handle, then we also need to confirm they overlap
|
|
414
|
+
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
|
|
415
|
+
//
|
|
416
|
+
// It's not enough to compare only the target
|
|
417
|
+
// The target might be a small element inside of a larger container
|
|
418
|
+
// (For example, a SPAN or a DIV inside of a larger modal dialog)
|
|
419
|
+
let currentElement = targetElement;
|
|
420
|
+
let didIntersect = false;
|
|
421
|
+
while (currentElement) {
|
|
422
|
+
if (currentElement.contains(dragHandleElement)) {
|
|
423
|
+
break;
|
|
424
|
+
} else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
|
|
425
|
+
didIntersect = true;
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
currentElement = currentElement.parentElement;
|
|
429
|
+
}
|
|
430
|
+
if (didIntersect) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
379
434
|
intersectingHandles.push(data);
|
|
380
435
|
}
|
|
381
436
|
});
|
|
@@ -467,15 +522,8 @@ function updateResizeHandlerStates(action, event) {
|
|
|
467
522
|
const {
|
|
468
523
|
setResizeHandlerState
|
|
469
524
|
} = data;
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
setResizeHandlerState(action, "drag", event);
|
|
473
|
-
} else {
|
|
474
|
-
setResizeHandlerState(action, "hover", event);
|
|
475
|
-
}
|
|
476
|
-
} else {
|
|
477
|
-
setResizeHandlerState(action, "inactive", event);
|
|
478
|
-
}
|
|
525
|
+
const isActive = intersectingHandles.includes(data);
|
|
526
|
+
setResizeHandlerState(action, isActive, event);
|
|
479
527
|
});
|
|
480
528
|
}
|
|
481
529
|
|
|
@@ -1828,6 +1876,12 @@ function PanelResizeHandle({
|
|
|
1828
1876
|
const [state, setState] = useState("inactive");
|
|
1829
1877
|
const [isFocused, setIsFocused] = useState(false);
|
|
1830
1878
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
1879
|
+
const committedValuesRef = useRef({
|
|
1880
|
+
state
|
|
1881
|
+
});
|
|
1882
|
+
useLayoutEffect(() => {
|
|
1883
|
+
committedValuesRef.current.state = state;
|
|
1884
|
+
});
|
|
1831
1885
|
useEffect(() => {
|
|
1832
1886
|
if (disabled) {
|
|
1833
1887
|
setResizeHandler(null);
|
|
@@ -1843,38 +1897,47 @@ function PanelResizeHandle({
|
|
|
1843
1897
|
}
|
|
1844
1898
|
const element = elementRef.current;
|
|
1845
1899
|
assert(element);
|
|
1846
|
-
const setResizeHandlerState = (action,
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
onDragging
|
|
1900
|
+
const setResizeHandlerState = (action, isActive, event) => {
|
|
1901
|
+
if (isActive) {
|
|
1902
|
+
switch (action) {
|
|
1903
|
+
case "down":
|
|
1904
|
+
{
|
|
1905
|
+
setState("drag");
|
|
1906
|
+
startDragging(resizeHandleId, event);
|
|
1907
|
+
const {
|
|
1908
|
+
onDragging
|
|
1909
|
+
} = callbacksRef.current;
|
|
1910
|
+
if (onDragging) {
|
|
1911
|
+
onDragging(true);
|
|
1912
|
+
}
|
|
1913
|
+
break;
|
|
1857
1914
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1915
|
+
case "move":
|
|
1916
|
+
{
|
|
1917
|
+
const {
|
|
1918
|
+
state
|
|
1919
|
+
} = committedValuesRef.current;
|
|
1920
|
+
if (state !== "drag") {
|
|
1921
|
+
setState("hover");
|
|
1922
|
+
}
|
|
1923
|
+
resizeHandler(event);
|
|
1924
|
+
break;
|
|
1868
1925
|
}
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1926
|
+
case "up":
|
|
1927
|
+
{
|
|
1928
|
+
setState("hover");
|
|
1929
|
+
stopDragging();
|
|
1930
|
+
const {
|
|
1931
|
+
onDragging
|
|
1932
|
+
} = callbacksRef.current;
|
|
1933
|
+
if (onDragging) {
|
|
1934
|
+
onDragging(false);
|
|
1935
|
+
}
|
|
1936
|
+
break;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
} else {
|
|
1940
|
+
setState("inactive");
|
|
1878
1941
|
}
|
|
1879
1942
|
};
|
|
1880
1943
|
return registerResizeHandle(resizeHandleId, element, direction, {
|
|
@@ -1931,10 +1994,28 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
1931
1994
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
1932
1995
|
}
|
|
1933
1996
|
|
|
1997
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
1998
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
1999
|
+
return {
|
|
2000
|
+
x: 0,
|
|
2001
|
+
y: 0,
|
|
2002
|
+
width: 0,
|
|
2003
|
+
height: 0
|
|
2004
|
+
};
|
|
2005
|
+
}
|
|
2006
|
+
return {
|
|
2007
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2008
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2009
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2010
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2011
|
+
};
|
|
2012
|
+
}
|
|
2013
|
+
|
|
1934
2014
|
exports.Panel = Panel;
|
|
1935
2015
|
exports.PanelGroup = PanelGroup;
|
|
1936
2016
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
1937
2017
|
exports.assert = assert;
|
|
2018
|
+
exports.getIntersectingRectangle = getIntersectingRectangle;
|
|
1938
2019
|
exports.getPanelElement = getPanelElement;
|
|
1939
2020
|
exports.getPanelElementsForGroup = getPanelElementsForGroup;
|
|
1940
2021
|
exports.getPanelGroupElement = getPanelGroupElement;
|
|
@@ -1942,3 +2023,4 @@ exports.getResizeHandleElement = getResizeHandleElement;
|
|
|
1942
2023
|
exports.getResizeHandleElementIndex = getResizeHandleElementIndex;
|
|
1943
2024
|
exports.getResizeHandleElementsForGroup = getResizeHandleElementsForGroup;
|
|
1944
2025
|
exports.getResizeHandlePanelIds = getResizeHandlePanelIds;
|
|
2026
|
+
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.node.cjs.js";
|