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.
Files changed (38) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/declarations/src/PanelResizeHandle.d.ts +1 -0
  3. package/dist/declarations/src/PanelResizeHandleRegistry.d.ts +1 -2
  4. package/dist/declarations/src/index.d.ts +3 -1
  5. package/dist/declarations/src/utils/rects/getIntersectingRectangle.d.ts +2 -0
  6. package/dist/declarations/src/utils/rects/intersects.d.ts +2 -0
  7. package/dist/declarations/src/utils/rects/types.d.ts +6 -0
  8. package/dist/react-resizable-panels.browser.cjs.js +138 -56
  9. package/dist/react-resizable-panels.browser.cjs.mjs +3 -1
  10. package/dist/react-resizable-panels.browser.development.cjs.js +138 -56
  11. package/dist/react-resizable-panels.browser.development.cjs.mjs +3 -1
  12. package/dist/react-resizable-panels.browser.development.esm.js +137 -57
  13. package/dist/react-resizable-panels.browser.esm.js +137 -57
  14. package/dist/react-resizable-panels.cjs.js +138 -56
  15. package/dist/react-resizable-panels.cjs.mjs +3 -1
  16. package/dist/react-resizable-panels.development.cjs.js +138 -56
  17. package/dist/react-resizable-panels.development.cjs.mjs +3 -1
  18. package/dist/react-resizable-panels.development.esm.js +137 -57
  19. package/dist/react-resizable-panels.development.node.cjs.js +138 -56
  20. package/dist/react-resizable-panels.development.node.cjs.mjs +3 -1
  21. package/dist/react-resizable-panels.development.node.esm.js +137 -57
  22. package/dist/react-resizable-panels.esm.js +137 -57
  23. package/dist/react-resizable-panels.node.cjs.js +138 -56
  24. package/dist/react-resizable-panels.node.cjs.mjs +3 -1
  25. package/dist/react-resizable-panels.node.esm.js +137 -57
  26. package/package.json +4 -1
  27. package/src/Panel.test.tsx +63 -0
  28. package/src/PanelGroup.test.tsx +21 -1
  29. package/src/PanelResizeHandle.test.tsx +181 -22
  30. package/src/PanelResizeHandle.ts +44 -24
  31. package/src/PanelResizeHandleRegistry.ts +87 -30
  32. package/src/index.ts +4 -0
  33. package/src/utils/rects/getIntersectingRectangle.test.ts +198 -0
  34. package/src/utils/rects/getIntersectingRectangle.ts +28 -0
  35. package/src/utils/rects/intersects.test.ts +197 -0
  36. package/src/utils/rects/intersects.ts +23 -0
  37. package/src/utils/rects/types.ts +6 -0
  38. 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;
@@ -307,6 +308,14 @@ function getInputType() {
307
308
  }
308
309
  }
309
310
 
311
+ function intersects(rectOne, rectTwo, strict) {
312
+ if (strict) {
313
+ return rectOne.x < rectTwo.x + rectTwo.width && rectOne.x + rectOne.width > rectTwo.x && rectOne.y < rectTwo.y + rectTwo.height && rectOne.y + rectOne.height > rectTwo.y;
314
+ } else {
315
+ return rectOne.x <= rectTwo.x + rectTwo.width && rectOne.x + rectOne.width >= rectTwo.x && rectOne.y <= rectTwo.y + rectTwo.height && rectOne.y + rectOne.height >= rectTwo.y;
316
+ }
317
+ }
318
+
310
319
  const EXCEEDED_HORIZONTAL_MIN = 0b0001;
311
320
  const EXCEEDED_HORIZONTAL_MAX = 0b0010;
312
321
  const EXCEEDED_VERTICAL_MIN = 0b0100;
@@ -345,12 +354,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
345
354
  };
346
355
  }
347
356
  function handlePointerDown(event) {
357
+ const {
358
+ target
359
+ } = event;
348
360
  const {
349
361
  x,
350
362
  y
351
363
  } = getResizeEventCoordinates(event);
352
364
  isPointerDown = true;
353
365
  recalculateIntersectingHandles({
366
+ target,
354
367
  x,
355
368
  y
356
369
  });
@@ -365,29 +378,32 @@ function handlePointerMove(event) {
365
378
  x,
366
379
  y
367
380
  } = getResizeEventCoordinates(event);
368
- if (isPointerDown) {
369
- intersectingHandles.forEach(data => {
370
- const {
371
- setResizeHandlerState
372
- } = data;
373
- setResizeHandlerState("move", "drag", event);
374
- });
381
+ if (!isPointerDown) {
382
+ const {
383
+ target
384
+ } = event;
375
385
 
376
- // Update cursor based on return value(s) from active handles
377
- updateCursor();
378
- } else {
386
+ // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
387
+ // at that point, the handles may not move with the pointer (depending on constraints)
388
+ // but the same set of active handles should be locked until the pointer is released
379
389
  recalculateIntersectingHandles({
390
+ target,
380
391
  x,
381
392
  y
382
393
  });
383
- updateResizeHandlerStates("move", event);
384
- updateCursor();
385
394
  }
395
+ updateResizeHandlerStates("move", event);
396
+
397
+ // Update cursor based on return value(s) from active handles
398
+ updateCursor();
386
399
  if (intersectingHandles.length > 0) {
387
400
  event.preventDefault();
388
401
  }
389
402
  }
390
403
  function handlePointerUp(event) {
404
+ const {
405
+ target
406
+ } = event;
391
407
  const {
392
408
  x,
393
409
  y
@@ -397,33 +413,72 @@ function handlePointerUp(event) {
397
413
  if (intersectingHandles.length > 0) {
398
414
  event.preventDefault();
399
415
  }
416
+ updateResizeHandlerStates("up", event);
400
417
  recalculateIntersectingHandles({
418
+ target,
401
419
  x,
402
420
  y
403
421
  });
404
- updateResizeHandlerStates("up", event);
405
422
  updateCursor();
406
423
  updateListeners();
407
424
  }
408
425
  function recalculateIntersectingHandles({
426
+ target,
409
427
  x,
410
428
  y
411
429
  }) {
412
430
  intersectingHandles.splice(0);
431
+ let targetElement = null;
432
+ if (target instanceof HTMLElement) {
433
+ targetElement = target;
434
+ }
413
435
  registeredResizeHandlers.forEach(data => {
414
436
  const {
415
- element,
437
+ element: dragHandleElement,
416
438
  hitAreaMargins
417
439
  } = data;
440
+ const dragHandleRect = dragHandleElement.getBoundingClientRect();
418
441
  const {
419
442
  bottom,
420
443
  left,
421
444
  right,
422
445
  top
423
- } = element.getBoundingClientRect();
446
+ } = dragHandleRect;
424
447
  const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
425
- const intersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
426
- if (intersects) {
448
+ const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
449
+ if (eventIntersects) {
450
+ // TRICKY
451
+ // We listen for pointers events at the root in order to support hit area margins
452
+ // (determining when the pointer is close enough to an element to be considered a "hit")
453
+ // Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
454
+ // so at this point we need to compare stacking order of a potentially intersecting drag handle,
455
+ // and the element that was actually clicked/touched
456
+ if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
457
+ // Calculating stacking order has a cost, so we should avoid it if possible
458
+ // That is why we only check potentially intersecting handles,
459
+ // and why we skip if the event target is within the handle's DOM
460
+ stackingOrder.compare(targetElement, dragHandleElement) > 0) {
461
+ // If the target is above the drag handle, then we also need to confirm they overlap
462
+ // If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
463
+ //
464
+ // It's not enough to compare only the target
465
+ // The target might be a small element inside of a larger container
466
+ // (For example, a SPAN or a DIV inside of a larger modal dialog)
467
+ let currentElement = targetElement;
468
+ let didIntersect = false;
469
+ while (currentElement) {
470
+ if (currentElement.contains(dragHandleElement)) {
471
+ break;
472
+ } else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
473
+ didIntersect = true;
474
+ break;
475
+ }
476
+ currentElement = currentElement.parentElement;
477
+ }
478
+ if (didIntersect) {
479
+ return;
480
+ }
481
+ }
427
482
  intersectingHandles.push(data);
428
483
  }
429
484
  });
@@ -515,15 +570,8 @@ function updateResizeHandlerStates(action, event) {
515
570
  const {
516
571
  setResizeHandlerState
517
572
  } = data;
518
- if (intersectingHandles.includes(data)) {
519
- if (isPointerDown) {
520
- setResizeHandlerState(action, "drag", event);
521
- } else {
522
- setResizeHandlerState(action, "hover", event);
523
- }
524
- } else {
525
- setResizeHandlerState(action, "inactive", event);
526
- }
573
+ const isActive = intersectingHandles.includes(data);
574
+ setResizeHandlerState(action, isActive, event);
527
575
  });
528
576
  }
529
577
 
@@ -2160,6 +2208,12 @@ function PanelResizeHandle({
2160
2208
  const [state, setState] = useState("inactive");
2161
2209
  const [isFocused, setIsFocused] = useState(false);
2162
2210
  const [resizeHandler, setResizeHandler] = useState(null);
2211
+ const committedValuesRef = useRef({
2212
+ state
2213
+ });
2214
+ useLayoutEffect(() => {
2215
+ committedValuesRef.current.state = state;
2216
+ });
2163
2217
  useEffect(() => {
2164
2218
  if (disabled) {
2165
2219
  setResizeHandler(null);
@@ -2175,38 +2229,47 @@ function PanelResizeHandle({
2175
2229
  }
2176
2230
  const element = elementRef.current;
2177
2231
  assert(element);
2178
- const setResizeHandlerState = (action, state, event) => {
2179
- setState(state);
2180
- switch (action) {
2181
- case "down":
2182
- {
2183
- startDragging(resizeHandleId, event);
2184
- const {
2185
- onDragging
2186
- } = callbacksRef.current;
2187
- if (onDragging) {
2188
- onDragging(true);
2232
+ const setResizeHandlerState = (action, isActive, event) => {
2233
+ if (isActive) {
2234
+ switch (action) {
2235
+ case "down":
2236
+ {
2237
+ setState("drag");
2238
+ startDragging(resizeHandleId, event);
2239
+ const {
2240
+ onDragging
2241
+ } = callbacksRef.current;
2242
+ if (onDragging) {
2243
+ onDragging(true);
2244
+ }
2245
+ break;
2189
2246
  }
2190
- break;
2191
- }
2192
- case "up":
2193
- {
2194
- stopDragging();
2195
- const {
2196
- onDragging
2197
- } = callbacksRef.current;
2198
- if (onDragging) {
2199
- onDragging(false);
2247
+ case "move":
2248
+ {
2249
+ const {
2250
+ state
2251
+ } = committedValuesRef.current;
2252
+ if (state !== "drag") {
2253
+ setState("hover");
2254
+ }
2255
+ resizeHandler(event);
2256
+ break;
2200
2257
  }
2201
- break;
2202
- }
2203
- }
2204
- switch (state) {
2205
- case "drag":
2206
- {
2207
- resizeHandler(event);
2208
- break;
2209
- }
2258
+ case "up":
2259
+ {
2260
+ setState("hover");
2261
+ stopDragging();
2262
+ const {
2263
+ onDragging
2264
+ } = callbacksRef.current;
2265
+ if (onDragging) {
2266
+ onDragging(false);
2267
+ }
2268
+ break;
2269
+ }
2270
+ }
2271
+ } else {
2272
+ setState("inactive");
2210
2273
  }
2211
2274
  };
2212
2275
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2263,10 +2326,28 @@ function getPanelElementsForGroup(groupId, scope = document) {
2263
2326
  return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
2264
2327
  }
2265
2328
 
2329
+ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2330
+ if (!intersects(rectOne, rectTwo, strict)) {
2331
+ return {
2332
+ x: 0,
2333
+ y: 0,
2334
+ width: 0,
2335
+ height: 0
2336
+ };
2337
+ }
2338
+ return {
2339
+ x: Math.max(rectOne.x, rectTwo.x),
2340
+ y: Math.max(rectOne.y, rectTwo.y),
2341
+ width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
2342
+ height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
2343
+ };
2344
+ }
2345
+
2266
2346
  exports.Panel = Panel;
2267
2347
  exports.PanelGroup = PanelGroup;
2268
2348
  exports.PanelResizeHandle = PanelResizeHandle;
2269
2349
  exports.assert = assert;
2350
+ exports.getIntersectingRectangle = getIntersectingRectangle;
2270
2351
  exports.getPanelElement = getPanelElement;
2271
2352
  exports.getPanelElementsForGroup = getPanelElementsForGroup;
2272
2353
  exports.getPanelGroupElement = getPanelGroupElement;
@@ -2274,3 +2355,4 @@ exports.getResizeHandleElement = getResizeHandleElement;
2274
2355
  exports.getResizeHandleElementIndex = getResizeHandleElementIndex;
2275
2356
  exports.getResizeHandleElementsForGroup = getResizeHandleElementsForGroup;
2276
2357
  exports.getResizeHandlePanelIds = getResizeHandlePanelIds;
2358
+ exports.intersects = intersects;
@@ -3,11 +3,13 @@ export {
3
3
  PanelGroup,
4
4
  PanelResizeHandle,
5
5
  assert,
6
+ getIntersectingRectangle,
6
7
  getPanelElement,
7
8
  getPanelElementsForGroup,
8
9
  getPanelGroupElement,
9
10
  getResizeHandleElement,
10
11
  getResizeHandleElementIndex,
11
12
  getResizeHandleElementsForGroup,
12
- getResizeHandlePanelIds
13
+ getResizeHandlePanelIds,
14
+ intersects
13
15
  } from "./react-resizable-panels.development.cjs.js";
@@ -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
 
@@ -283,6 +284,14 @@ function getInputType() {
283
284
  }
284
285
  }
285
286
 
287
+ function intersects(rectOne, rectTwo, strict) {
288
+ if (strict) {
289
+ 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;
290
+ } else {
291
+ 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;
292
+ }
293
+ }
294
+
286
295
  const EXCEEDED_HORIZONTAL_MIN = 0b0001;
287
296
  const EXCEEDED_HORIZONTAL_MAX = 0b0010;
288
297
  const EXCEEDED_VERTICAL_MIN = 0b0100;
@@ -321,12 +330,16 @@ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins
321
330
  };
322
331
  }
323
332
  function handlePointerDown(event) {
333
+ const {
334
+ target
335
+ } = event;
324
336
  const {
325
337
  x,
326
338
  y
327
339
  } = getResizeEventCoordinates(event);
328
340
  isPointerDown = true;
329
341
  recalculateIntersectingHandles({
342
+ target,
330
343
  x,
331
344
  y
332
345
  });
@@ -341,29 +354,32 @@ function handlePointerMove(event) {
341
354
  x,
342
355
  y
343
356
  } = getResizeEventCoordinates(event);
344
- if (isPointerDown) {
345
- intersectingHandles.forEach(data => {
346
- const {
347
- setResizeHandlerState
348
- } = data;
349
- setResizeHandlerState("move", "drag", event);
350
- });
357
+ if (!isPointerDown) {
358
+ const {
359
+ target
360
+ } = event;
351
361
 
352
- // Update cursor based on return value(s) from active handles
353
- updateCursor();
354
- } else {
362
+ // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
363
+ // at that point, the handles may not move with the pointer (depending on constraints)
364
+ // but the same set of active handles should be locked until the pointer is released
355
365
  recalculateIntersectingHandles({
366
+ target,
356
367
  x,
357
368
  y
358
369
  });
359
- updateResizeHandlerStates("move", event);
360
- updateCursor();
361
370
  }
371
+ updateResizeHandlerStates("move", event);
372
+
373
+ // Update cursor based on return value(s) from active handles
374
+ updateCursor();
362
375
  if (intersectingHandles.length > 0) {
363
376
  event.preventDefault();
364
377
  }
365
378
  }
366
379
  function handlePointerUp(event) {
380
+ const {
381
+ target
382
+ } = event;
367
383
  const {
368
384
  x,
369
385
  y
@@ -373,33 +389,72 @@ function handlePointerUp(event) {
373
389
  if (intersectingHandles.length > 0) {
374
390
  event.preventDefault();
375
391
  }
392
+ updateResizeHandlerStates("up", event);
376
393
  recalculateIntersectingHandles({
394
+ target,
377
395
  x,
378
396
  y
379
397
  });
380
- updateResizeHandlerStates("up", event);
381
398
  updateCursor();
382
399
  updateListeners();
383
400
  }
384
401
  function recalculateIntersectingHandles({
402
+ target,
385
403
  x,
386
404
  y
387
405
  }) {
388
406
  intersectingHandles.splice(0);
407
+ let targetElement = null;
408
+ if (target instanceof HTMLElement) {
409
+ targetElement = target;
410
+ }
389
411
  registeredResizeHandlers.forEach(data => {
390
412
  const {
391
- element,
413
+ element: dragHandleElement,
392
414
  hitAreaMargins
393
415
  } = data;
416
+ const dragHandleRect = dragHandleElement.getBoundingClientRect();
394
417
  const {
395
418
  bottom,
396
419
  left,
397
420
  right,
398
421
  top
399
- } = element.getBoundingClientRect();
422
+ } = dragHandleRect;
400
423
  const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
401
- const intersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
402
- if (intersects) {
424
+ const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
425
+ if (eventIntersects) {
426
+ // TRICKY
427
+ // We listen for pointers events at the root in order to support hit area margins
428
+ // (determining when the pointer is close enough to an element to be considered a "hit")
429
+ // Clicking on an element "above" a handle (e.g. a modal) should prevent a hit though
430
+ // so at this point we need to compare stacking order of a potentially intersecting drag handle,
431
+ // and the element that was actually clicked/touched
432
+ if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) &&
433
+ // Calculating stacking order has a cost, so we should avoid it if possible
434
+ // That is why we only check potentially intersecting handles,
435
+ // and why we skip if the event target is within the handle's DOM
436
+ compare(targetElement, dragHandleElement) > 0) {
437
+ // If the target is above the drag handle, then we also need to confirm they overlap
438
+ // If they are beside each other (e.g. a panel and its drag handle) then the handle is still interactive
439
+ //
440
+ // It's not enough to compare only the target
441
+ // The target might be a small element inside of a larger container
442
+ // (For example, a SPAN or a DIV inside of a larger modal dialog)
443
+ let currentElement = targetElement;
444
+ let didIntersect = false;
445
+ while (currentElement) {
446
+ if (currentElement.contains(dragHandleElement)) {
447
+ break;
448
+ } else if (intersects(currentElement.getBoundingClientRect(), dragHandleRect, true)) {
449
+ didIntersect = true;
450
+ break;
451
+ }
452
+ currentElement = currentElement.parentElement;
453
+ }
454
+ if (didIntersect) {
455
+ return;
456
+ }
457
+ }
403
458
  intersectingHandles.push(data);
404
459
  }
405
460
  });
@@ -491,15 +546,8 @@ function updateResizeHandlerStates(action, event) {
491
546
  const {
492
547
  setResizeHandlerState
493
548
  } = data;
494
- if (intersectingHandles.includes(data)) {
495
- if (isPointerDown) {
496
- setResizeHandlerState(action, "drag", event);
497
- } else {
498
- setResizeHandlerState(action, "hover", event);
499
- }
500
- } else {
501
- setResizeHandlerState(action, "inactive", event);
502
- }
549
+ const isActive = intersectingHandles.includes(data);
550
+ setResizeHandlerState(action, isActive, event);
503
551
  });
504
552
  }
505
553
 
@@ -2136,6 +2184,12 @@ function PanelResizeHandle({
2136
2184
  const [state, setState] = useState("inactive");
2137
2185
  const [isFocused, setIsFocused] = useState(false);
2138
2186
  const [resizeHandler, setResizeHandler] = useState(null);
2187
+ const committedValuesRef = useRef({
2188
+ state
2189
+ });
2190
+ useLayoutEffect(() => {
2191
+ committedValuesRef.current.state = state;
2192
+ });
2139
2193
  useEffect(() => {
2140
2194
  if (disabled) {
2141
2195
  setResizeHandler(null);
@@ -2151,38 +2205,47 @@ function PanelResizeHandle({
2151
2205
  }
2152
2206
  const element = elementRef.current;
2153
2207
  assert(element);
2154
- const setResizeHandlerState = (action, state, event) => {
2155
- setState(state);
2156
- switch (action) {
2157
- case "down":
2158
- {
2159
- startDragging(resizeHandleId, event);
2160
- const {
2161
- onDragging
2162
- } = callbacksRef.current;
2163
- if (onDragging) {
2164
- onDragging(true);
2208
+ const setResizeHandlerState = (action, isActive, event) => {
2209
+ if (isActive) {
2210
+ switch (action) {
2211
+ case "down":
2212
+ {
2213
+ setState("drag");
2214
+ startDragging(resizeHandleId, event);
2215
+ const {
2216
+ onDragging
2217
+ } = callbacksRef.current;
2218
+ if (onDragging) {
2219
+ onDragging(true);
2220
+ }
2221
+ break;
2165
2222
  }
2166
- break;
2167
- }
2168
- case "up":
2169
- {
2170
- stopDragging();
2171
- const {
2172
- onDragging
2173
- } = callbacksRef.current;
2174
- if (onDragging) {
2175
- onDragging(false);
2223
+ case "move":
2224
+ {
2225
+ const {
2226
+ state
2227
+ } = committedValuesRef.current;
2228
+ if (state !== "drag") {
2229
+ setState("hover");
2230
+ }
2231
+ resizeHandler(event);
2232
+ break;
2176
2233
  }
2177
- break;
2178
- }
2179
- }
2180
- switch (state) {
2181
- case "drag":
2182
- {
2183
- resizeHandler(event);
2184
- break;
2185
- }
2234
+ case "up":
2235
+ {
2236
+ setState("hover");
2237
+ stopDragging();
2238
+ const {
2239
+ onDragging
2240
+ } = callbacksRef.current;
2241
+ if (onDragging) {
2242
+ onDragging(false);
2243
+ }
2244
+ break;
2245
+ }
2246
+ }
2247
+ } else {
2248
+ setState("inactive");
2186
2249
  }
2187
2250
  };
2188
2251
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2239,4 +2302,21 @@ function getPanelElementsForGroup(groupId, scope = document) {
2239
2302
  return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
2240
2303
  }
2241
2304
 
2242
- export { Panel, PanelGroup, PanelResizeHandle, assert, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds };
2305
+ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2306
+ if (!intersects(rectOne, rectTwo, strict)) {
2307
+ return {
2308
+ x: 0,
2309
+ y: 0,
2310
+ width: 0,
2311
+ height: 0
2312
+ };
2313
+ }
2314
+ return {
2315
+ x: Math.max(rectOne.x, rectTwo.x),
2316
+ y: Math.max(rectOne.y, rectTwo.y),
2317
+ width: Math.min(rectOne.x + rectOne.width, rectTwo.x + rectTwo.width) - Math.max(rectOne.x, rectTwo.x),
2318
+ height: Math.min(rectOne.y + rectOne.height, rectTwo.y + rectTwo.height) - Math.max(rectOne.y, rectTwo.y)
2319
+ };
2320
+ }
2321
+
2322
+ export { Panel, PanelGroup, PanelResizeHandle, assert, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects };