react-resizable-panels 1.0.9 → 2.0.0

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 (28) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +29 -104
  3. package/dist/declarations/src/PanelResizeHandle.d.ts +3 -1
  4. package/dist/declarations/src/PanelResizeHandleRegistry.d.ts +20 -0
  5. package/dist/react-resizable-panels.browser.cjs.js +367 -140
  6. package/dist/react-resizable-panels.browser.development.cjs.js +367 -140
  7. package/dist/react-resizable-panels.browser.development.esm.js +367 -140
  8. package/dist/react-resizable-panels.browser.esm.js +367 -140
  9. package/dist/react-resizable-panels.cjs.js +367 -140
  10. package/dist/react-resizable-panels.development.cjs.js +367 -140
  11. package/dist/react-resizable-panels.development.esm.js +367 -140
  12. package/dist/react-resizable-panels.development.node.cjs.js +367 -140
  13. package/dist/react-resizable-panels.development.node.esm.js +367 -140
  14. package/dist/react-resizable-panels.esm.js +367 -140
  15. package/dist/react-resizable-panels.node.cjs.js +367 -140
  16. package/dist/react-resizable-panels.node.esm.js +367 -140
  17. package/package.json +1 -1
  18. package/src/Panel.test.tsx +52 -0
  19. package/src/PanelGroup.ts +23 -16
  20. package/src/PanelResizeHandle.ts +64 -82
  21. package/src/PanelResizeHandleRegistry.ts +263 -0
  22. package/src/utils/calculateDragOffsetPercentage.ts +1 -1
  23. package/src/utils/cursor.ts +63 -33
  24. package/src/utils/events/getResizeEventCoordinates.ts +24 -0
  25. package/src/utils/events/getResizeEventCursorPosition.ts +14 -0
  26. package/src/utils/{events.ts → events/index.ts} +1 -1
  27. package/src/utils/getInputType.ts +5 -0
  28. package/src/utils/getResizeEventCursorPosition.ts +0 -21
@@ -139,6 +139,322 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
139
139
  PanelWithForwardedRef.displayName = "Panel";
140
140
  Panel.displayName = "forwardRef(Panel)";
141
141
 
142
+ let currentCursorStyle = null;
143
+ let styleElement = null;
144
+ function getCursorStyle(state, constraintFlags) {
145
+ if (constraintFlags) {
146
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
147
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
148
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
149
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
150
+ if (horizontalMin) {
151
+ if (verticalMin) {
152
+ return "se-resize";
153
+ } else if (verticalMax) {
154
+ return "ne-resize";
155
+ } else {
156
+ return "e-resize";
157
+ }
158
+ } else if (horizontalMax) {
159
+ if (verticalMin) {
160
+ return "sw-resize";
161
+ } else if (verticalMax) {
162
+ return "nw-resize";
163
+ } else {
164
+ return "w-resize";
165
+ }
166
+ } else if (verticalMin) {
167
+ return "s-resize";
168
+ } else if (verticalMax) {
169
+ return "n-resize";
170
+ }
171
+ }
172
+ switch (state) {
173
+ case "horizontal":
174
+ return "ew-resize";
175
+ case "intersection":
176
+ return "move";
177
+ case "vertical":
178
+ return "ns-resize";
179
+ }
180
+ }
181
+ function resetGlobalCursorStyle() {
182
+ if (styleElement !== null) {
183
+ document.head.removeChild(styleElement);
184
+ currentCursorStyle = null;
185
+ styleElement = null;
186
+ }
187
+ }
188
+ function setGlobalCursorStyle(state, constraintFlags) {
189
+ const style = getCursorStyle(state, constraintFlags);
190
+ if (currentCursorStyle === style) {
191
+ return;
192
+ }
193
+ currentCursorStyle = style;
194
+ if (styleElement === null) {
195
+ styleElement = document.createElement("style");
196
+ document.head.appendChild(styleElement);
197
+ }
198
+ styleElement.innerHTML = `*{cursor: ${style}!important;}`;
199
+ }
200
+
201
+ function isKeyDown(event) {
202
+ return event.type === "keydown";
203
+ }
204
+ function isMouseEvent(event) {
205
+ return event.type.startsWith("mouse");
206
+ }
207
+ function isTouchEvent(event) {
208
+ return event.type.startsWith("touch");
209
+ }
210
+
211
+ function getResizeEventCoordinates(event) {
212
+ if (isMouseEvent(event)) {
213
+ return {
214
+ x: event.pageX,
215
+ y: event.pageY
216
+ };
217
+ } else if (isTouchEvent(event)) {
218
+ const touch = event.touches[0];
219
+ if (touch && touch.pageX && touch.pageY) {
220
+ return {
221
+ x: touch.pageX,
222
+ y: touch.pageY
223
+ };
224
+ }
225
+ }
226
+ return {
227
+ x: Infinity,
228
+ y: Infinity
229
+ };
230
+ }
231
+
232
+ function getInputType() {
233
+ if (typeof matchMedia === "function") {
234
+ return matchMedia("(pointer:coarse)").matches ? "coarse" : "fine";
235
+ }
236
+ }
237
+
238
+ const EXCEEDED_HORIZONTAL_MIN = 0b0001;
239
+ const EXCEEDED_HORIZONTAL_MAX = 0b0010;
240
+ const EXCEEDED_VERTICAL_MIN = 0b0100;
241
+ const EXCEEDED_VERTICAL_MAX = 0b1000;
242
+ const isCoarsePointer = getInputType() === "coarse";
243
+ let intersectingHandles = [];
244
+ let isPointerDown = false;
245
+ let ownerDocumentCounts = new Map();
246
+ let panelConstraintFlags = new Map();
247
+ const registeredResizeHandlers = new Set();
248
+ function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins, setResizeHandlerState) {
249
+ var _ownerDocumentCounts$;
250
+ const {
251
+ ownerDocument
252
+ } = element;
253
+ const data = {
254
+ direction,
255
+ element,
256
+ hitAreaMargins,
257
+ setResizeHandlerState
258
+ };
259
+ const count = (_ownerDocumentCounts$ = ownerDocumentCounts.get(ownerDocument)) !== null && _ownerDocumentCounts$ !== void 0 ? _ownerDocumentCounts$ : 0;
260
+ ownerDocumentCounts.set(ownerDocument, count + 1);
261
+ registeredResizeHandlers.add(data);
262
+ updateListeners();
263
+ return function unregisterResizeHandle() {
264
+ var _ownerDocumentCounts$2;
265
+ panelConstraintFlags.delete(resizeHandleId);
266
+ registeredResizeHandlers.delete(data);
267
+ const count = (_ownerDocumentCounts$2 = ownerDocumentCounts.get(ownerDocument)) !== null && _ownerDocumentCounts$2 !== void 0 ? _ownerDocumentCounts$2 : 1;
268
+ ownerDocumentCounts.set(ownerDocument, count - 1);
269
+ updateListeners();
270
+ if (count === 1) {
271
+ ownerDocumentCounts.delete(ownerDocument);
272
+ }
273
+ };
274
+ }
275
+ function handlePointerDown(event) {
276
+ const {
277
+ x,
278
+ y
279
+ } = getResizeEventCoordinates(event);
280
+ isPointerDown = true;
281
+ updateResizeHandlerStates("down", event);
282
+ recalculateIntersectingHandles({
283
+ x,
284
+ y
285
+ });
286
+ updateListeners();
287
+ if (intersectingHandles.length > 0) {
288
+ event.preventDefault();
289
+ }
290
+ }
291
+ function handlePointerMove(event) {
292
+ const {
293
+ x,
294
+ y
295
+ } = getResizeEventCoordinates(event);
296
+ if (isPointerDown) {
297
+ intersectingHandles.forEach(data => {
298
+ const {
299
+ setResizeHandlerState
300
+ } = data;
301
+ setResizeHandlerState("move", "drag", event);
302
+ });
303
+
304
+ // Update cursor based on return value(s) from active handles
305
+ updateCursor();
306
+ } else {
307
+ recalculateIntersectingHandles({
308
+ x,
309
+ y
310
+ });
311
+ updateResizeHandlerStates("move", event);
312
+ updateCursor();
313
+ }
314
+ if (intersectingHandles.length > 0) {
315
+ event.preventDefault();
316
+ }
317
+ }
318
+ function handlePointerUp(event) {
319
+ const {
320
+ x,
321
+ y
322
+ } = getResizeEventCoordinates(event);
323
+ panelConstraintFlags.clear();
324
+ isPointerDown = false;
325
+ if (intersectingHandles.length > 0) {
326
+ event.preventDefault();
327
+ }
328
+ recalculateIntersectingHandles({
329
+ x,
330
+ y
331
+ });
332
+ updateResizeHandlerStates("up", event);
333
+ updateCursor();
334
+ updateListeners();
335
+ }
336
+ function recalculateIntersectingHandles({
337
+ x,
338
+ y
339
+ }) {
340
+ intersectingHandles.splice(0);
341
+ registeredResizeHandlers.forEach(data => {
342
+ const {
343
+ element,
344
+ hitAreaMargins
345
+ } = data;
346
+ const {
347
+ bottom,
348
+ left,
349
+ right,
350
+ top
351
+ } = element.getBoundingClientRect();
352
+ const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
353
+ const intersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
354
+ if (intersects) {
355
+ intersectingHandles.push(data);
356
+ }
357
+ });
358
+ }
359
+ function reportConstraintsViolation(resizeHandleId, flag) {
360
+ panelConstraintFlags.set(resizeHandleId, flag);
361
+ }
362
+ function updateCursor() {
363
+ let intersectsHorizontal = false;
364
+ let intersectsVertical = false;
365
+ intersectingHandles.forEach(data => {
366
+ const {
367
+ direction
368
+ } = data;
369
+ if (direction === "horizontal") {
370
+ intersectsHorizontal = true;
371
+ } else {
372
+ intersectsVertical = true;
373
+ }
374
+ });
375
+ let constraintFlags = 0;
376
+ panelConstraintFlags.forEach(flag => {
377
+ constraintFlags |= flag;
378
+ });
379
+ if (intersectsHorizontal && intersectsVertical) {
380
+ setGlobalCursorStyle("intersection", constraintFlags);
381
+ } else if (intersectsHorizontal) {
382
+ setGlobalCursorStyle("horizontal", constraintFlags);
383
+ } else if (intersectsVertical) {
384
+ setGlobalCursorStyle("vertical", constraintFlags);
385
+ } else {
386
+ resetGlobalCursorStyle();
387
+ }
388
+ }
389
+ function updateListeners() {
390
+ ownerDocumentCounts.forEach((_, ownerDocument) => {
391
+ const {
392
+ body
393
+ } = ownerDocument;
394
+ body.removeEventListener("contextmenu", handlePointerUp);
395
+ body.removeEventListener("mousedown", handlePointerDown);
396
+ body.removeEventListener("mouseleave", handlePointerMove);
397
+ body.removeEventListener("mousemove", handlePointerMove);
398
+ body.removeEventListener("touchmove", handlePointerMove);
399
+ body.removeEventListener("touchstart", handlePointerDown);
400
+ });
401
+ window.removeEventListener("mouseup", handlePointerUp);
402
+ window.removeEventListener("touchcancel", handlePointerUp);
403
+ window.removeEventListener("touchend", handlePointerUp);
404
+ if (registerResizeHandle.length > 0) {
405
+ if (isPointerDown) {
406
+ if (intersectingHandles.length > 0) {
407
+ ownerDocumentCounts.forEach((count, ownerDocument) => {
408
+ const {
409
+ body
410
+ } = ownerDocument;
411
+ if (count > 0) {
412
+ body.addEventListener("contextmenu", handlePointerUp);
413
+ body.addEventListener("mouseleave", handlePointerMove);
414
+ body.addEventListener("mousemove", handlePointerMove);
415
+ body.addEventListener("touchmove", handlePointerMove, {
416
+ passive: false
417
+ });
418
+ }
419
+ });
420
+ }
421
+ window.addEventListener("mouseup", handlePointerUp);
422
+ window.addEventListener("touchcancel", handlePointerUp);
423
+ window.addEventListener("touchend", handlePointerUp);
424
+ } else {
425
+ ownerDocumentCounts.forEach((count, ownerDocument) => {
426
+ const {
427
+ body
428
+ } = ownerDocument;
429
+ if (count > 0) {
430
+ body.addEventListener("mousedown", handlePointerDown);
431
+ body.addEventListener("mousemove", handlePointerMove);
432
+ body.addEventListener("touchmove", handlePointerMove, {
433
+ passive: false
434
+ });
435
+ body.addEventListener("touchstart", handlePointerDown);
436
+ }
437
+ });
438
+ }
439
+ }
440
+ }
441
+ function updateResizeHandlerStates(action, event) {
442
+ registeredResizeHandlers.forEach(data => {
443
+ const {
444
+ setResizeHandlerState
445
+ } = data;
446
+ if (intersectingHandles.includes(data)) {
447
+ if (isPointerDown) {
448
+ setResizeHandlerState(action, "drag", event);
449
+ } else {
450
+ setResizeHandlerState(action, "hover", event);
451
+ }
452
+ } else {
453
+ setResizeHandlerState(action, "inactive", event);
454
+ }
455
+ });
456
+ }
457
+
142
458
  function assert(expectedCondition, message = "Assertion failed!") {
143
459
  if (!expectedCondition) {
144
460
  console.error(message);
@@ -571,27 +887,13 @@ function areEqual(arrayA, arrayB) {
571
887
  return true;
572
888
  }
573
889
 
574
- function isKeyDown(event) {
575
- return event.type === "keydown";
576
- }
577
- function isMouseEvent(event) {
578
- return event.type.startsWith("mouse");
579
- }
580
- function isTouchEvent(event) {
581
- return event.type.startsWith("touch");
582
- }
583
-
584
890
  function getResizeEventCursorPosition(direction, event) {
585
891
  const isHorizontal = direction === "horizontal";
586
- if (isMouseEvent(event)) {
587
- return isHorizontal ? event.clientX : event.clientY;
588
- } else if (isTouchEvent(event)) {
589
- const firstTouch = event.touches[0];
590
- assert(firstTouch);
591
- return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
592
- } else {
593
- throw Error(`Unsupported event type "${event.type}"`);
594
- }
892
+ const {
893
+ x,
894
+ y
895
+ } = getResizeEventCoordinates(event);
896
+ return isHorizontal ? x : y;
595
897
  }
596
898
 
597
899
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement) {
@@ -740,44 +1042,6 @@ function computePanelFlexBoxStyle({
740
1042
  };
741
1043
  }
742
1044
 
743
- let currentState = null;
744
- let element = null;
745
- function getCursorStyle(state) {
746
- switch (state) {
747
- case "horizontal":
748
- return "ew-resize";
749
- case "horizontal-max":
750
- return "w-resize";
751
- case "horizontal-min":
752
- return "e-resize";
753
- case "vertical":
754
- return "ns-resize";
755
- case "vertical-max":
756
- return "n-resize";
757
- case "vertical-min":
758
- return "s-resize";
759
- }
760
- }
761
- function resetGlobalCursorStyle() {
762
- if (element !== null) {
763
- document.head.removeChild(element);
764
- currentState = null;
765
- element = null;
766
- }
767
- }
768
- function setGlobalCursorStyle(state) {
769
- if (currentState === state) {
770
- return;
771
- }
772
- currentState = state;
773
- const style = getCursorStyle(state);
774
- if (element === null) {
775
- element = document.createElement("style");
776
- document.head.appendChild(element);
777
- }
778
- element.innerHTML = `*{cursor: ${style}!important;}`;
779
- }
780
-
781
1045
  function debounce(callback, durationMs = 10) {
782
1046
  let timeoutId = null;
783
1047
  let callable = (...args) => {
@@ -1261,18 +1525,15 @@ function PanelGroupWithForwardedRef({
1261
1525
  if (prevDeltaRef.current != delta) {
1262
1526
  prevDeltaRef.current = delta;
1263
1527
  if (!layoutChanged) {
1264
- // If the pointer has moved too far to resize the panel any further,
1265
- // update the cursor style for a visual clue.
1528
+ // If the pointer has moved too far to resize the panel any further, note this so we can update the cursor.
1266
1529
  // This mimics VS Code behavior.
1267
-
1268
1530
  if (isHorizontal) {
1269
- setGlobalCursorStyle(delta < 0 ? "horizontal-min" : "horizontal-max");
1531
+ reportConstraintsViolation(dragHandleId, delta < 0 ? EXCEEDED_HORIZONTAL_MIN : EXCEEDED_HORIZONTAL_MAX);
1270
1532
  } else {
1271
- setGlobalCursorStyle(delta < 0 ? "vertical-min" : "vertical-max");
1533
+ reportConstraintsViolation(dragHandleId, delta < 0 ? EXCEEDED_VERTICAL_MIN : EXCEEDED_VERTICAL_MAX);
1272
1534
  }
1273
1535
  } else {
1274
- // Reset the cursor style to the the normal resize cursor.
1275
- setGlobalCursorStyle(isHorizontal ? "horizontal" : "vertical");
1536
+ reportConstraintsViolation(dragHandleId, 0);
1276
1537
  }
1277
1538
  }
1278
1539
  }
@@ -1327,15 +1588,11 @@ function PanelGroupWithForwardedRef({
1327
1588
  } = eagerValuesRef.current;
1328
1589
  const {
1329
1590
  collapsedSize: prevCollapsedSize = 0,
1330
- collapsible: prevCollapsible,
1331
- defaultSize: prevDefaultSize,
1332
- maxSize: prevMaxSize = 100,
1333
- minSize: prevMinSize = 0
1591
+ collapsible: prevCollapsible
1334
1592
  } = prevConstraints;
1335
1593
  const {
1336
1594
  collapsedSize: nextCollapsedSize = 0,
1337
1595
  collapsible: nextCollapsible,
1338
- defaultSize: nextDefaultSize,
1339
1596
  maxSize: nextMaxSize = 100,
1340
1597
  minSize: nextMinSize = 0
1341
1598
  } = panelData.constraints;
@@ -1343,8 +1600,10 @@ function PanelGroupWithForwardedRef({
1343
1600
  panelSize: prevPanelSize
1344
1601
  } = panelDataHelper(panelDataArray, panelData, layout);
1345
1602
  assert(prevPanelSize != null);
1346
- if (prevCollapsible && nextCollapsible && prevCollapsedSize !== nextCollapsedSize && prevPanelSize === prevCollapsedSize) {
1347
- resizePanel(panelData, nextCollapsedSize);
1603
+ if (prevCollapsible && nextCollapsible && prevPanelSize === prevCollapsedSize) {
1604
+ if (prevCollapsedSize !== nextCollapsedSize) {
1605
+ resizePanel(panelData, nextCollapsedSize);
1606
+ }
1348
1607
  } else if (prevPanelSize < nextMinSize) {
1349
1608
  resizePanel(panelData, nextMinSize);
1350
1609
  } else if (prevPanelSize > nextMaxSize) {
@@ -1372,7 +1631,6 @@ function PanelGroupWithForwardedRef({
1372
1631
  });
1373
1632
  }, []);
1374
1633
  const stopDragging = useCallback(() => {
1375
- resetGlobalCursorStyle();
1376
1634
  setDragState(null);
1377
1635
  }, []);
1378
1636
  const unregisterPanel = useCallback(panelData => {
@@ -1513,6 +1771,7 @@ function PanelResizeHandle({
1513
1771
  children = null,
1514
1772
  className: classNameFromProps = "",
1515
1773
  disabled = false,
1774
+ hitAreaMargins,
1516
1775
  id: idFromProps,
1517
1776
  onDragging,
1518
1777
  style: styleFromProps = {},
@@ -1535,67 +1794,60 @@ function PanelResizeHandle({
1535
1794
  }
1536
1795
  const {
1537
1796
  direction,
1538
- dragState,
1539
1797
  groupId,
1540
- registerResizeHandle,
1798
+ registerResizeHandle: registerResizeHandleWithParentGroup,
1541
1799
  startDragging,
1542
1800
  stopDragging,
1543
1801
  panelGroupElement
1544
1802
  } = panelGroupContext;
1545
1803
  const resizeHandleId = useUniqueId(idFromProps);
1546
- const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
1804
+ const [state, setState] = useState("inactive");
1547
1805
  const [isFocused, setIsFocused] = useState(false);
1548
1806
  const [resizeHandler, setResizeHandler] = useState(null);
1549
- const stopDraggingAndBlur = useCallback(() => {
1550
- // Clicking on the drag handle shouldn't leave it focused;
1551
- // That would cause the PanelGroup to think it was still active.
1552
- const element = elementRef.current;
1553
- assert(element);
1554
- element.blur();
1555
- stopDragging();
1556
- const {
1557
- onDragging
1558
- } = callbacksRef.current;
1559
- if (onDragging) {
1560
- onDragging(false);
1561
- }
1562
- }, [stopDragging]);
1563
1807
  useEffect(() => {
1564
1808
  if (disabled) {
1565
1809
  setResizeHandler(null);
1566
1810
  } else {
1567
- const resizeHandler = registerResizeHandle(resizeHandleId);
1811
+ const resizeHandler = registerResizeHandleWithParentGroup(resizeHandleId);
1568
1812
  setResizeHandler(() => resizeHandler);
1569
1813
  }
1570
- }, [disabled, resizeHandleId, registerResizeHandle]);
1814
+ }, [disabled, resizeHandleId, registerResizeHandleWithParentGroup]);
1571
1815
  useEffect(() => {
1572
- if (disabled || resizeHandler == null || !isDragging) {
1816
+ var _hitAreaMargins$coars, _hitAreaMargins$fine;
1817
+ if (disabled || resizeHandler == null) {
1573
1818
  return;
1574
1819
  }
1575
- const onMove = event => {
1576
- resizeHandler(event);
1577
- };
1578
- const onMouseLeave = event => {
1579
- resizeHandler(event);
1580
- };
1581
1820
  const element = elementRef.current;
1582
1821
  assert(element);
1583
- const targetDocument = element.ownerDocument;
1584
- targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
1585
- targetDocument.body.addEventListener("mousemove", onMove);
1586
- targetDocument.body.addEventListener("touchmove", onMove);
1587
- targetDocument.body.addEventListener("mouseleave", onMouseLeave);
1588
- window.addEventListener("mouseup", stopDraggingAndBlur);
1589
- window.addEventListener("touchend", stopDraggingAndBlur);
1590
- return () => {
1591
- targetDocument.body.removeEventListener("contextmenu", stopDraggingAndBlur);
1592
- targetDocument.body.removeEventListener("mousemove", onMove);
1593
- targetDocument.body.removeEventListener("touchmove", onMove);
1594
- targetDocument.body.removeEventListener("mouseleave", onMouseLeave);
1595
- window.removeEventListener("mouseup", stopDraggingAndBlur);
1596
- window.removeEventListener("touchend", stopDraggingAndBlur);
1822
+ const setResizeHandlerState = (action, state, event) => {
1823
+ setState(state);
1824
+ switch (action) {
1825
+ case "down":
1826
+ {
1827
+ startDragging(resizeHandleId, event);
1828
+ break;
1829
+ }
1830
+ case "up":
1831
+ {
1832
+ stopDragging();
1833
+ break;
1834
+ }
1835
+ }
1836
+ switch (state) {
1837
+ case "drag":
1838
+ {
1839
+ resizeHandler(event);
1840
+ break;
1841
+ }
1842
+ }
1597
1843
  };
1598
- }, [direction, disabled, isDragging, resizeHandler, stopDraggingAndBlur]);
1844
+ return registerResizeHandle(resizeHandleId, element, direction, {
1845
+ // Coarse inputs (e.g. finger/touch)
1846
+ coarse: (_hitAreaMargins$coars = hitAreaMargins === null || hitAreaMargins === void 0 ? void 0 : hitAreaMargins.coarse) !== null && _hitAreaMargins$coars !== void 0 ? _hitAreaMargins$coars : 15,
1847
+ // Fine inputs (e.g. mouse)
1848
+ fine: (_hitAreaMargins$fine = hitAreaMargins === null || hitAreaMargins === void 0 ? void 0 : hitAreaMargins.fine) !== null && _hitAreaMargins$fine !== void 0 ? _hitAreaMargins$fine : 5
1849
+ }, setResizeHandlerState);
1850
+ }, [direction, disabled, hitAreaMargins, registerResizeHandleWithParentGroup, resizeHandleId, resizeHandler, startDragging, stopDragging]);
1599
1851
  useWindowSplitterResizeHandlerBehavior({
1600
1852
  disabled,
1601
1853
  handleId: resizeHandleId,
@@ -1603,7 +1855,6 @@ function PanelResizeHandle({
1603
1855
  panelGroupElement
1604
1856
  });
1605
1857
  const style = {
1606
- cursor: getCursorStyle(direction),
1607
1858
  touchAction: "none",
1608
1859
  userSelect: "none"
1609
1860
  };
@@ -1613,31 +1864,6 @@ function PanelResizeHandle({
1613
1864
  className: classNameFromProps,
1614
1865
  onBlur: () => setIsFocused(false),
1615
1866
  onFocus: () => setIsFocused(true),
1616
- onMouseDown: event => {
1617
- startDragging(resizeHandleId, event.nativeEvent);
1618
- const callbacks = callbacksRef.current;
1619
- assert(callbacks);
1620
- const {
1621
- onDragging
1622
- } = callbacks;
1623
- if (onDragging) {
1624
- onDragging(true);
1625
- }
1626
- },
1627
- onMouseUp: stopDraggingAndBlur,
1628
- onTouchCancel: stopDraggingAndBlur,
1629
- onTouchEnd: stopDraggingAndBlur,
1630
- onTouchStart: event => {
1631
- startDragging(resizeHandleId, event.nativeEvent);
1632
- const callbacks = callbacksRef.current;
1633
- assert(callbacks);
1634
- const {
1635
- onDragging
1636
- } = callbacks;
1637
- if (onDragging) {
1638
- onDragging(true);
1639
- }
1640
- },
1641
1867
  ref: elementRef,
1642
1868
  role: "separator",
1643
1869
  style: {
@@ -1649,7 +1875,8 @@ function PanelResizeHandle({
1649
1875
  "data-panel-group-direction": direction,
1650
1876
  "data-panel-group-id": groupId,
1651
1877
  "data-resize-handle": "",
1652
- "data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
1878
+ "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
1879
+ "data-resize-handle-state": state,
1653
1880
  "data-panel-resize-handle-enabled": !disabled,
1654
1881
  "data-panel-resize-handle-id": resizeHandleId
1655
1882
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-resizable-panels",
3
- "version": "1.0.9",
3
+ "version": "2.0.0",
4
4
  "description": "React components for resizable panel groups/layouts",
5
5
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
6
6
  "license": "MIT",
@@ -319,6 +319,58 @@ describe("PanelGroup", () => {
319
319
  expect(rightElement.getAttribute("data-panel-size")).toBe("5.0");
320
320
  });
321
321
 
322
+ it("it should not expand a collapsed panel if other constraints change", () => {
323
+ act(() => {
324
+ root.render(
325
+ <PanelGroup direction="horizontal">
326
+ <Panel
327
+ id="left"
328
+ collapsedSize={10}
329
+ collapsible
330
+ defaultSize={10}
331
+ minSize={25}
332
+ />
333
+ <PanelResizeHandle />
334
+ <Panel id="middle" />
335
+ <PanelResizeHandle />
336
+ <Panel
337
+ id="right"
338
+ collapsedSize={10}
339
+ collapsible
340
+ defaultSize={10}
341
+ minSize={25}
342
+ />
343
+ </PanelGroup>
344
+ );
345
+ });
346
+
347
+ let leftElement = getPanelElement("left", container);
348
+ let middleElement = getPanelElement("middle", container);
349
+ let rightElement = getPanelElement("right", container);
350
+ assert(leftElement);
351
+ assert(middleElement);
352
+ assert(rightElement);
353
+ expect(leftElement.getAttribute("data-panel-size")).toBe("10.0");
354
+ expect(middleElement.getAttribute("data-panel-size")).toBe("80.0");
355
+ expect(rightElement.getAttribute("data-panel-size")).toBe("10.0");
356
+
357
+ act(() => {
358
+ root.render(
359
+ <PanelGroup direction="horizontal">
360
+ <Panel id="left" collapsedSize={10} collapsible minSize={20} />
361
+ <PanelResizeHandle />
362
+ <Panel id="middle" />
363
+ <PanelResizeHandle />
364
+ <Panel id="right" collapsedSize={10} collapsible minSize={20} />
365
+ </PanelGroup>
366
+ );
367
+ });
368
+
369
+ expect(leftElement.getAttribute("data-panel-size")).toBe("10.0");
370
+ expect(middleElement.getAttribute("data-panel-size")).toBe("80.0");
371
+ expect(rightElement.getAttribute("data-panel-size")).toBe("10.0");
372
+ });
373
+
322
374
  it("should resize a panel if the minSize prop changes", () => {
323
375
  act(() => {
324
376
  root.render(