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