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
|
@@ -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;
|
|
@@ -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
|
+
stackingOrder.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
|
|
|
@@ -1929,6 +1977,12 @@ function PanelResizeHandle({
|
|
|
1929
1977
|
const [state, setState] = useState("inactive");
|
|
1930
1978
|
const [isFocused, setIsFocused] = useState(false);
|
|
1931
1979
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
1980
|
+
const committedValuesRef = useRef({
|
|
1981
|
+
state
|
|
1982
|
+
});
|
|
1983
|
+
useLayoutEffect(() => {
|
|
1984
|
+
committedValuesRef.current.state = state;
|
|
1985
|
+
});
|
|
1932
1986
|
useEffect(() => {
|
|
1933
1987
|
if (disabled) {
|
|
1934
1988
|
setResizeHandler(null);
|
|
@@ -1944,38 +1998,47 @@ function PanelResizeHandle({
|
|
|
1944
1998
|
}
|
|
1945
1999
|
const element = elementRef.current;
|
|
1946
2000
|
assert(element);
|
|
1947
|
-
const setResizeHandlerState = (action,
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
onDragging
|
|
2001
|
+
const setResizeHandlerState = (action, isActive, event) => {
|
|
2002
|
+
if (isActive) {
|
|
2003
|
+
switch (action) {
|
|
2004
|
+
case "down":
|
|
2005
|
+
{
|
|
2006
|
+
setState("drag");
|
|
2007
|
+
startDragging(resizeHandleId, event);
|
|
2008
|
+
const {
|
|
2009
|
+
onDragging
|
|
2010
|
+
} = callbacksRef.current;
|
|
2011
|
+
if (onDragging) {
|
|
2012
|
+
onDragging(true);
|
|
2013
|
+
}
|
|
2014
|
+
break;
|
|
1958
2015
|
}
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
2016
|
+
case "move":
|
|
2017
|
+
{
|
|
2018
|
+
const {
|
|
2019
|
+
state
|
|
2020
|
+
} = committedValuesRef.current;
|
|
2021
|
+
if (state !== "drag") {
|
|
2022
|
+
setState("hover");
|
|
2023
|
+
}
|
|
2024
|
+
resizeHandler(event);
|
|
2025
|
+
break;
|
|
1969
2026
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2027
|
+
case "up":
|
|
2028
|
+
{
|
|
2029
|
+
setState("hover");
|
|
2030
|
+
stopDragging();
|
|
2031
|
+
const {
|
|
2032
|
+
onDragging
|
|
2033
|
+
} = callbacksRef.current;
|
|
2034
|
+
if (onDragging) {
|
|
2035
|
+
onDragging(false);
|
|
2036
|
+
}
|
|
2037
|
+
break;
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
} else {
|
|
2041
|
+
setState("inactive");
|
|
1979
2042
|
}
|
|
1980
2043
|
};
|
|
1981
2044
|
return registerResizeHandle(resizeHandleId, element, direction, {
|
|
@@ -2032,10 +2095,28 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2032
2095
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2033
2096
|
}
|
|
2034
2097
|
|
|
2098
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
2099
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
2100
|
+
return {
|
|
2101
|
+
x: 0,
|
|
2102
|
+
y: 0,
|
|
2103
|
+
width: 0,
|
|
2104
|
+
height: 0
|
|
2105
|
+
};
|
|
2106
|
+
}
|
|
2107
|
+
return {
|
|
2108
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2109
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2110
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2111
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2035
2115
|
exports.Panel = Panel;
|
|
2036
2116
|
exports.PanelGroup = PanelGroup;
|
|
2037
2117
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
2038
2118
|
exports.assert = assert;
|
|
2119
|
+
exports.getIntersectingRectangle = getIntersectingRectangle;
|
|
2039
2120
|
exports.getPanelElement = getPanelElement;
|
|
2040
2121
|
exports.getPanelElementsForGroup = getPanelElementsForGroup;
|
|
2041
2122
|
exports.getPanelGroupElement = getPanelGroupElement;
|
|
@@ -2043,3 +2124,4 @@ exports.getResizeHandleElement = getResizeHandleElement;
|
|
|
2043
2124
|
exports.getResizeHandleElementIndex = getResizeHandleElementIndex;
|
|
2044
2125
|
exports.getResizeHandleElementsForGroup = getResizeHandleElementsForGroup;
|
|
2045
2126
|
exports.getResizeHandlePanelIds = getResizeHandlePanelIds;
|
|
2127
|
+
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.node.cjs.js";
|
|
@@ -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
|
|
|
@@ -246,6 +247,14 @@ function getInputType() {
|
|
|
246
247
|
}
|
|
247
248
|
}
|
|
248
249
|
|
|
250
|
+
function intersects(rectOne, rectTwo, strict) {
|
|
251
|
+
if (strict) {
|
|
252
|
+
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;
|
|
253
|
+
} else {
|
|
254
|
+
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;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
249
258
|
const EXCEEDED_HORIZONTAL_MIN = 0b0001;
|
|
250
259
|
const EXCEEDED_HORIZONTAL_MAX = 0b0010;
|
|
251
260
|
const EXCEEDED_VERTICAL_MIN = 0b0100;
|
|
@@ -284,12 +293,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
|
|
|
284
293
|
};
|
|
285
294
|
}
|
|
286
295
|
function handlePointerDown(event) {
|
|
296
|
+
const {
|
|
297
|
+
target
|
|
298
|
+
} = event;
|
|
287
299
|
const {
|
|
288
300
|
x,
|
|
289
301
|
y
|
|
290
302
|
} = getResizeEventCoordinates(event);
|
|
291
303
|
isPointerDown = true;
|
|
292
304
|
recalculateIntersectingHandles({
|
|
305
|
+
target,
|
|
293
306
|
x,
|
|
294
307
|
y
|
|
295
308
|
});
|
|
@@ -304,29 +317,32 @@ function handlePointerMove(event) {
|
|
|
304
317
|
x,
|
|
305
318
|
y
|
|
306
319
|
} = getResizeEventCoordinates(event);
|
|
307
|
-
if (isPointerDown) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
} = data;
|
|
312
|
-
setResizeHandlerState("move", "drag", event);
|
|
313
|
-
});
|
|
320
|
+
if (!isPointerDown) {
|
|
321
|
+
const {
|
|
322
|
+
target
|
|
323
|
+
} = event;
|
|
314
324
|
|
|
315
|
-
//
|
|
316
|
-
|
|
317
|
-
|
|
325
|
+
// Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
|
|
326
|
+
// at that point, the handles may not move with the pointer (depending on constraints)
|
|
327
|
+
// but the same set of active handles should be locked until the pointer is released
|
|
318
328
|
recalculateIntersectingHandles({
|
|
329
|
+
target,
|
|
319
330
|
x,
|
|
320
331
|
y
|
|
321
332
|
});
|
|
322
|
-
updateResizeHandlerStates("move", event);
|
|
323
|
-
updateCursor();
|
|
324
333
|
}
|
|
334
|
+
updateResizeHandlerStates("move", event);
|
|
335
|
+
|
|
336
|
+
// Update cursor based on return value(s) from active handles
|
|
337
|
+
updateCursor();
|
|
325
338
|
if (intersectingHandles.length > 0) {
|
|
326
339
|
event.preventDefault();
|
|
327
340
|
}
|
|
328
341
|
}
|
|
329
342
|
function handlePointerUp(event) {
|
|
343
|
+
const {
|
|
344
|
+
target
|
|
345
|
+
} = event;
|
|
330
346
|
const {
|
|
331
347
|
x,
|
|
332
348
|
y
|
|
@@ -336,33 +352,72 @@ function handlePointerUp(event) {
|
|
|
336
352
|
if (intersectingHandles.length > 0) {
|
|
337
353
|
event.preventDefault();
|
|
338
354
|
}
|
|
355
|
+
updateResizeHandlerStates("up", event);
|
|
339
356
|
recalculateIntersectingHandles({
|
|
357
|
+
target,
|
|
340
358
|
x,
|
|
341
359
|
y
|
|
342
360
|
});
|
|
343
|
-
updateResizeHandlerStates("up", event);
|
|
344
361
|
updateCursor();
|
|
345
362
|
updateListeners();
|
|
346
363
|
}
|
|
347
364
|
function recalculateIntersectingHandles({
|
|
365
|
+
target,
|
|
348
366
|
x,
|
|
349
367
|
y
|
|
350
368
|
}) {
|
|
351
369
|
intersectingHandles.splice(0);
|
|
370
|
+
let targetElement = null;
|
|
371
|
+
if (target instanceof HTMLElement) {
|
|
372
|
+
targetElement = target;
|
|
373
|
+
}
|
|
352
374
|
registeredResizeHandlers.forEach(data => {
|
|
353
375
|
const {
|
|
354
|
-
element,
|
|
376
|
+
element: dragHandleElement,
|
|
355
377
|
hitAreaMargins
|
|
356
378
|
} = data;
|
|
379
|
+
const dragHandleRect = dragHandleElement.getBoundingClientRect();
|
|
357
380
|
const {
|
|
358
381
|
bottom,
|
|
359
382
|
left,
|
|
360
383
|
right,
|
|
361
384
|
top
|
|
362
|
-
} =
|
|
385
|
+
} = dragHandleRect;
|
|
363
386
|
const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
|
|
364
|
-
const
|
|
365
|
-
if (
|
|
387
|
+
const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
|
|
388
|
+
if (eventIntersects) {
|
|
389
|
+
// TRICKY
|
|
390
|
+
// We listen for pointers events at the root in order to support hit area margins
|
|
391
|
+
// (determining when the pointer is close enough to an element to be considered a "hit")
|
|
392
|
+
// Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
|
|
393
|
+
// so at this point we need to compare stacking order of a potentially intersecting drag handle,
|
|
394
|
+
// and the element that was actually clicked/touched
|
|
395
|
+
if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
|
|
396
|
+
// Calculating stacking order has a cost, so we should avoid it if possible
|
|
397
|
+
// That is why we only check potentially intersecting handles,
|
|
398
|
+
// and why we skip if the event target is within the handle's DOM
|
|
399
|
+
compare(targetElement, dragHandleElement) > 0) {
|
|
400
|
+
// If the target is above the drag handle, then we also need to confirm they overlap
|
|
401
|
+
// If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
|
|
402
|
+
//
|
|
403
|
+
// It's not enough to compare only the target
|
|
404
|
+
// The target might be a small element inside of a larger container
|
|
405
|
+
// (For example, a SPAN or a DIV inside of a larger modal dialog)
|
|
406
|
+
let currentElement = targetElement;
|
|
407
|
+
let didIntersect = false;
|
|
408
|
+
while (currentElement) {
|
|
409
|
+
if (currentElement.contains(dragHandleElement)) {
|
|
410
|
+
break;
|
|
411
|
+
} else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
|
|
412
|
+
didIntersect = true;
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
currentElement = currentElement.parentElement;
|
|
416
|
+
}
|
|
417
|
+
if (didIntersect) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
366
421
|
intersectingHandles.push(data);
|
|
367
422
|
}
|
|
368
423
|
});
|
|
@@ -454,15 +509,8 @@ function updateResizeHandlerStates(action, event) {
|
|
|
454
509
|
const {
|
|
455
510
|
setResizeHandlerState
|
|
456
511
|
} = data;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
setResizeHandlerState(action, "drag", event);
|
|
460
|
-
} else {
|
|
461
|
-
setResizeHandlerState(action, "hover", event);
|
|
462
|
-
}
|
|
463
|
-
} else {
|
|
464
|
-
setResizeHandlerState(action, "inactive", event);
|
|
465
|
-
}
|
|
512
|
+
const isActive = intersectingHandles.includes(data);
|
|
513
|
+
setResizeHandlerState(action, isActive, event);
|
|
466
514
|
});
|
|
467
515
|
}
|
|
468
516
|
|
|
@@ -1905,6 +1953,12 @@ function PanelResizeHandle({
|
|
|
1905
1953
|
const [state, setState] = useState("inactive");
|
|
1906
1954
|
const [isFocused, setIsFocused] = useState(false);
|
|
1907
1955
|
const [resizeHandler, setResizeHandler] = useState(null);
|
|
1956
|
+
const committedValuesRef = useRef({
|
|
1957
|
+
state
|
|
1958
|
+
});
|
|
1959
|
+
useLayoutEffect(() => {
|
|
1960
|
+
committedValuesRef.current.state = state;
|
|
1961
|
+
});
|
|
1908
1962
|
useEffect(() => {
|
|
1909
1963
|
if (disabled) {
|
|
1910
1964
|
setResizeHandler(null);
|
|
@@ -1920,38 +1974,47 @@ function PanelResizeHandle({
|
|
|
1920
1974
|
}
|
|
1921
1975
|
const element = elementRef.current;
|
|
1922
1976
|
assert(element);
|
|
1923
|
-
const setResizeHandlerState = (action,
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
onDragging
|
|
1977
|
+
const setResizeHandlerState = (action, isActive, event) => {
|
|
1978
|
+
if (isActive) {
|
|
1979
|
+
switch (action) {
|
|
1980
|
+
case "down":
|
|
1981
|
+
{
|
|
1982
|
+
setState("drag");
|
|
1983
|
+
startDragging(resizeHandleId, event);
|
|
1984
|
+
const {
|
|
1985
|
+
onDragging
|
|
1986
|
+
} = callbacksRef.current;
|
|
1987
|
+
if (onDragging) {
|
|
1988
|
+
onDragging(true);
|
|
1989
|
+
}
|
|
1990
|
+
break;
|
|
1934
1991
|
}
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1992
|
+
case "move":
|
|
1993
|
+
{
|
|
1994
|
+
const {
|
|
1995
|
+
state
|
|
1996
|
+
} = committedValuesRef.current;
|
|
1997
|
+
if (state !== "drag") {
|
|
1998
|
+
setState("hover");
|
|
1999
|
+
}
|
|
2000
|
+
resizeHandler(event);
|
|
2001
|
+
break;
|
|
1945
2002
|
}
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
2003
|
+
case "up":
|
|
2004
|
+
{
|
|
2005
|
+
setState("hover");
|
|
2006
|
+
stopDragging();
|
|
2007
|
+
const {
|
|
2008
|
+
onDragging
|
|
2009
|
+
} = callbacksRef.current;
|
|
2010
|
+
if (onDragging) {
|
|
2011
|
+
onDragging(false);
|
|
2012
|
+
}
|
|
2013
|
+
break;
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
} else {
|
|
2017
|
+
setState("inactive");
|
|
1955
2018
|
}
|
|
1956
2019
|
};
|
|
1957
2020
|
return registerResizeHandle(resizeHandleId, element, direction, {
|
|
@@ -2008,4 +2071,21 @@ function getPanelElementsForGroup(groupId, scope = document) {
|
|
|
2008
2071
|
return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
2009
2072
|
}
|
|
2010
2073
|
|
|
2011
|
-
|
|
2074
|
+
function getIntersectingRectangle(rectOne, rectTwo, strict) {
|
|
2075
|
+
if (!intersects(rectOne, rectTwo, strict)) {
|
|
2076
|
+
return {
|
|
2077
|
+
x: 0,
|
|
2078
|
+
y: 0,
|
|
2079
|
+
width: 0,
|
|
2080
|
+
height: 0
|
|
2081
|
+
};
|
|
2082
|
+
}
|
|
2083
|
+
return {
|
|
2084
|
+
x: Math.max(rectOne.x, rectTwo.x),
|
|
2085
|
+
y: Math.max(rectOne.y, rectTwo.y),
|
|
2086
|
+
width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
|
|
2087
|
+
height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
export { Panel, PanelGroup, PanelResizeHandle, assert, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects };
|