react-resizable-panels 2.1.7 → 2.1.9

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 (27) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -0
  3. package/dist/declarations/src/Panel.d.ts +1 -1
  4. package/dist/declarations/src/PanelGroup.d.ts +1 -1
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +6 -3
  6. package/dist/declarations/src/constants.d.ts +15 -0
  7. package/dist/declarations/src/index.d.ts +3 -2
  8. package/dist/react-resizable-panels.browser.cjs.js +202 -176
  9. package/dist/react-resizable-panels.browser.cjs.mjs +1 -0
  10. package/dist/react-resizable-panels.browser.development.cjs.js +202 -176
  11. package/dist/react-resizable-panels.browser.development.cjs.mjs +1 -0
  12. package/dist/react-resizable-panels.browser.development.esm.js +150 -124
  13. package/dist/react-resizable-panels.browser.esm.js +150 -124
  14. package/dist/react-resizable-panels.cjs.js +202 -176
  15. package/dist/react-resizable-panels.cjs.mjs +1 -0
  16. package/dist/react-resizable-panels.development.cjs.js +202 -176
  17. package/dist/react-resizable-panels.development.cjs.mjs +1 -0
  18. package/dist/react-resizable-panels.development.esm.js +150 -124
  19. package/dist/react-resizable-panels.development.node.cjs.js +201 -174
  20. package/dist/react-resizable-panels.development.node.cjs.mjs +1 -0
  21. package/dist/react-resizable-panels.development.node.esm.js +149 -122
  22. package/dist/react-resizable-panels.esm.js +150 -124
  23. package/dist/react-resizable-panels.node.cjs.js +201 -174
  24. package/dist/react-resizable-panels.node.cjs.mjs +1 -0
  25. package/dist/react-resizable-panels.node.esm.js +149 -122
  26. package/package.json +12 -13
  27. package/dist/declarations/src/vendor/react.d.ts +0 -7
@@ -1,4 +1,5 @@
1
1
  export {
2
+ DATA_ATTRIBUTES,
2
3
  Panel,
3
4
  PanelGroup,
4
5
  PanelResizeHandle,
@@ -1,35 +1,30 @@
1
1
  import * as React from 'react';
2
-
3
- // This module exists to work around Webpack issue https://github.com/webpack/webpack/issues/14814
4
-
5
- // eslint-disable-next-line no-restricted-imports
6
-
7
- const {
8
- createElement,
9
- createContext,
10
- createRef,
11
- forwardRef,
12
- useCallback,
13
- useContext,
14
- useEffect,
15
- useImperativeHandle,
16
- useLayoutEffect,
17
- useMemo,
18
- useRef,
19
- useState
20
- } = React;
21
-
22
- // `Math.random()` and `.slice(0, 5)` prevents bundlers from trying to `import { useId } from 'react'`
23
- const useId = React[`useId${Math.random()}`.slice(0, 5)];
24
- const useLayoutEffect_do_not_use_directly = useLayoutEffect;
2
+ import { createContext, useLayoutEffect, useRef, forwardRef, createElement, useContext, useImperativeHandle, useState, useCallback, useEffect, useMemo } from 'react';
25
3
 
26
4
  // The "contextmenu" event is not supported as a PointerEvent in all browsers yet, so MouseEvent still need to be handled
27
5
 
28
6
  const PanelGroupContext = createContext(null);
29
7
  PanelGroupContext.displayName = "PanelGroupContext";
30
8
 
31
- const useIsomorphicLayoutEffect = useLayoutEffect_do_not_use_directly ;
9
+ const DATA_ATTRIBUTES = {
10
+ group: "data-panel-group",
11
+ groupDirection: "data-panel-group-direction",
12
+ groupId: "data-panel-group-id",
13
+ panel: "data-panel",
14
+ panelCollapsible: "data-panel-collapsible",
15
+ panelId: "data-panel-id",
16
+ panelSize: "data-panel-size",
17
+ resizeHandle: "data-resize-handle",
18
+ resizeHandleActive: "data-resize-handle-active",
19
+ resizeHandleEnabled: "data-panel-resize-handle-enabled",
20
+ resizeHandleId: "data-panel-resize-handle-id",
21
+ resizeHandleState: "data-resize-handle-state"
22
+ };
23
+ const PRECISION = 10;
24
+
25
+ const useIsomorphicLayoutEffect = useLayoutEffect ;
32
26
 
27
+ const useId = React["useId".toString()];
33
28
  const wrappedUseId = typeof useId === "function" ? useId : () => null;
34
29
  let counter = 0;
35
30
  function useUniqueId(idFromParams = null) {
@@ -163,17 +158,17 @@ function PanelWithForwardedRef({
163
158
  ...rest,
164
159
  children,
165
160
  className: classNameFromProps,
166
- id: idFromProps,
161
+ id: panelId,
167
162
  style: {
168
163
  ...style,
169
164
  ...styleFromProps
170
165
  },
171
166
  // CSS selectors
172
- "data-panel": "",
173
- "data-panel-collapsible": collapsible || undefined,
174
- "data-panel-group-id": groupId,
175
- "data-panel-id": panelId,
176
- "data-panel-size": parseFloat("" + style.flexGrow).toFixed(1)
167
+ [DATA_ATTRIBUTES.groupId]: groupId,
168
+ [DATA_ATTRIBUTES.panel]: "",
169
+ [DATA_ATTRIBUTES.panelCollapsible]: collapsible || undefined,
170
+ [DATA_ATTRIBUTES.panelId]: panelId,
171
+ [DATA_ATTRIBUTES.panelSize]: parseFloat("" + style.flexGrow).toFixed(1)
177
172
  });
178
173
  }
179
174
  const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
@@ -193,6 +188,7 @@ function setNonce(value) {
193
188
 
194
189
  let currentCursorStyle = null;
195
190
  let enabled = true;
191
+ let prevRuleIndex = -1;
196
192
  let styleElement = null;
197
193
  function disableGlobalCursorStyles() {
198
194
  enabled = false;
@@ -242,9 +238,11 @@ function resetGlobalCursorStyle() {
242
238
  document.head.removeChild(styleElement);
243
239
  currentCursorStyle = null;
244
240
  styleElement = null;
241
+ prevRuleIndex = -1;
245
242
  }
246
243
  }
247
244
  function setGlobalCursorStyle(state, constraintFlags) {
245
+ var _styleElement$sheet$i, _styleElement$sheet2;
248
246
  if (!enabled) {
249
247
  return;
250
248
  }
@@ -261,7 +259,11 @@ function setGlobalCursorStyle(state, constraintFlags) {
261
259
  }
262
260
  document.head.appendChild(styleElement);
263
261
  }
264
- styleElement.innerHTML = `*{cursor: ${style}!important;}`;
262
+ if (prevRuleIndex >= 0) {
263
+ var _styleElement$sheet;
264
+ (_styleElement$sheet = styleElement.sheet) === null || _styleElement$sheet === void 0 ? void 0 : _styleElement$sheet.removeRule(prevRuleIndex);
265
+ }
266
+ prevRuleIndex = (_styleElement$sheet$i = (_styleElement$sheet2 = styleElement.sheet) === null || _styleElement$sheet2 === void 0 ? void 0 : _styleElement$sheet2.insertRule(`*{cursor: ${style} !important;}`)) !== null && _styleElement$sheet$i !== void 0 ? _styleElement$sheet$i : -1;
265
267
  }
266
268
 
267
269
  function isKeyDown(event) {
@@ -492,7 +494,9 @@ function handlePointerDown(event) {
492
494
  if (intersectingHandles.length > 0) {
493
495
  updateResizeHandlerStates("down", event);
494
496
  event.preventDefault();
495
- event.stopPropagation();
497
+ if (!isWithinResizeHandle(target)) {
498
+ event.stopImmediatePropagation();
499
+ }
496
500
  }
497
501
  }
498
502
  function handlePointerMove(event) {
@@ -541,6 +545,9 @@ function handlePointerUp(event) {
541
545
  isPointerDown = false;
542
546
  if (intersectingHandles.length > 0) {
543
547
  event.preventDefault();
548
+ if (!isWithinResizeHandle(target)) {
549
+ event.stopImmediatePropagation();
550
+ }
544
551
  }
545
552
  updateResizeHandlerStates("up", event);
546
553
  recalculateIntersectingHandles({
@@ -551,6 +558,16 @@ function handlePointerUp(event) {
551
558
  updateCursor();
552
559
  updateListeners();
553
560
  }
561
+ function isWithinResizeHandle(element) {
562
+ let currentElement = element;
563
+ while (currentElement) {
564
+ if (currentElement.hasAttribute(DATA_ATTRIBUTES.resizeHandle)) {
565
+ return true;
566
+ }
567
+ currentElement = currentElement.parentElement;
568
+ }
569
+ return false;
570
+ }
554
571
  function recalculateIntersectingHandles({
555
572
  target,
556
573
  x,
@@ -642,47 +659,42 @@ function updateCursor() {
642
659
  resetGlobalCursorStyle();
643
660
  }
644
661
  }
662
+ let listenersAbortController = new AbortController();
645
663
  function updateListeners() {
646
- ownerDocumentCounts.forEach((_, ownerDocument) => {
647
- const {
648
- body
649
- } = ownerDocument;
650
- body.removeEventListener("contextmenu", handlePointerUp);
651
- body.removeEventListener("pointerdown", handlePointerDown);
652
- body.removeEventListener("pointerleave", handlePointerMove);
653
- body.removeEventListener("pointermove", handlePointerMove);
654
- });
655
- window.removeEventListener("pointerup", handlePointerUp);
656
- window.removeEventListener("pointercancel", handlePointerUp);
657
- if (registeredResizeHandlers.size > 0) {
658
- if (isPointerDown) {
659
- if (intersectingHandles.length > 0) {
660
- ownerDocumentCounts.forEach((count, ownerDocument) => {
661
- const {
662
- body
663
- } = ownerDocument;
664
- if (count > 0) {
665
- body.addEventListener("contextmenu", handlePointerUp);
666
- body.addEventListener("pointerleave", handlePointerMove);
667
- body.addEventListener("pointermove", handlePointerMove);
668
- }
669
- });
670
- }
671
- window.addEventListener("pointerup", handlePointerUp);
672
- window.addEventListener("pointercancel", handlePointerUp);
673
- } else {
664
+ listenersAbortController.abort();
665
+ listenersAbortController = new AbortController();
666
+ const options = {
667
+ capture: true,
668
+ signal: listenersAbortController.signal
669
+ };
670
+ if (!registeredResizeHandlers.size) {
671
+ return;
672
+ }
673
+ if (isPointerDown) {
674
+ if (intersectingHandles.length > 0) {
674
675
  ownerDocumentCounts.forEach((count, ownerDocument) => {
675
676
  const {
676
677
  body
677
678
  } = ownerDocument;
678
679
  if (count > 0) {
679
- body.addEventListener("pointerdown", handlePointerDown, {
680
- capture: true
681
- });
682
- body.addEventListener("pointermove", handlePointerMove);
680
+ body.addEventListener("contextmenu", handlePointerUp, options);
681
+ body.addEventListener("pointerleave", handlePointerMove, options);
682
+ body.addEventListener("pointermove", handlePointerMove, options);
683
683
  }
684
684
  });
685
685
  }
686
+ window.addEventListener("pointerup", handlePointerUp, options);
687
+ window.addEventListener("pointercancel", handlePointerUp, options);
688
+ } else {
689
+ ownerDocumentCounts.forEach((count, ownerDocument) => {
690
+ const {
691
+ body
692
+ } = ownerDocument;
693
+ if (count > 0) {
694
+ body.addEventListener("pointerdown", handlePointerDown, options);
695
+ body.addEventListener("pointermove", handlePointerMove, options);
696
+ }
697
+ });
686
698
  }
687
699
  }
688
700
  function updateResizeHandlerStates(action, event) {
@@ -707,8 +719,6 @@ function assert(expectedCondition, message) {
707
719
  }
708
720
  }
709
721
 
710
- const PRECISION = 10;
711
-
712
722
  function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
713
723
  if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
714
724
  return 0;
@@ -1052,12 +1062,12 @@ function calculateAriaValues({
1052
1062
  }
1053
1063
 
1054
1064
  function getResizeHandleElementsForGroup(groupId, scope = document) {
1055
- return Array.from(scope.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
1065
+ return Array.from(scope.querySelectorAll(`[${DATA_ATTRIBUTES.resizeHandleId}][data-panel-group-id="${groupId}"]`));
1056
1066
  }
1057
1067
 
1058
1068
  function getResizeHandleElementIndex(groupId, id, scope = document) {
1059
1069
  const handles = getResizeHandleElementsForGroup(groupId, scope);
1060
- const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
1070
+ const index = handles.findIndex(handle => handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId) === id);
1061
1071
  return index !== null && index !== void 0 ? index : null;
1062
1072
  }
1063
1073
 
@@ -1082,7 +1092,7 @@ function getPanelGroupElement(id, rootElement = document) {
1082
1092
  }
1083
1093
 
1084
1094
  function getResizeHandleElement(id, scope = document) {
1085
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
1095
+ const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1086
1096
  if (element) {
1087
1097
  return element;
1088
1098
  }
@@ -1171,7 +1181,7 @@ function useWindowSplitterPanelGroupBehavior({
1171
1181
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1172
1182
  assert(handles, `No resize handles found for group id "${groupId}"`);
1173
1183
  const cleanupFunctions = handles.map(handle => {
1174
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1184
+ const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1175
1185
  assert(handleId, `Resize handle element has no handle id attribute`);
1176
1186
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1177
1187
  if (idBefore == null || idAfter == null) {
@@ -1249,7 +1259,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
1249
1259
  const isHorizontal = direction === "horizontal";
1250
1260
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1251
1261
  assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1252
- const groupId = handleElement.getAttribute("data-panel-group-id");
1262
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1253
1263
  assert(groupId, `Resize handle element has no group id attribute`);
1254
1264
  let {
1255
1265
  initialCursorPosition
@@ -2255,9 +2265,9 @@ function PanelGroupWithForwardedRef({
2255
2265
  ...styleFromProps
2256
2266
  },
2257
2267
  // CSS selectors
2258
- "data-panel-group": "",
2259
- "data-panel-group-direction": direction,
2260
- "data-panel-group-id": groupId
2268
+ [DATA_ATTRIBUTES.group]: "",
2269
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2270
+ [DATA_ATTRIBUTES.groupId]: groupId
2261
2271
  }));
2262
2272
  }
2263
2273
  const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
@@ -2316,7 +2326,7 @@ function useWindowSplitterResizeHandlerBehavior({
2316
2326
  case "F6":
2317
2327
  {
2318
2328
  event.preventDefault();
2319
- const groupId = handleElement.getAttribute("data-panel-group-id");
2329
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2320
2330
  assert(groupId, `No group element found for id "${groupId}"`);
2321
2331
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2322
2332
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
@@ -2342,8 +2352,11 @@ function PanelResizeHandle({
2342
2352
  hitAreaMargins,
2343
2353
  id: idFromProps,
2344
2354
  onBlur,
2355
+ onClick,
2345
2356
  onDragging,
2346
2357
  onFocus,
2358
+ onPointerDown,
2359
+ onPointerUp,
2347
2360
  style: styleFromProps = {},
2348
2361
  tabIndex = 0,
2349
2362
  tagName: Type = "div",
@@ -2354,10 +2367,16 @@ function PanelResizeHandle({
2354
2367
 
2355
2368
  // Use a ref to guard against users passing inline props
2356
2369
  const callbacksRef = useRef({
2357
- onDragging
2370
+ onClick,
2371
+ onDragging,
2372
+ onPointerDown,
2373
+ onPointerUp
2358
2374
  });
2359
2375
  useEffect(() => {
2376
+ callbacksRef.current.onClick = onClick;
2360
2377
  callbacksRef.current.onDragging = onDragging;
2378
+ callbacksRef.current.onPointerDown = onPointerDown;
2379
+ callbacksRef.current.onPointerUp = onPointerUp;
2361
2380
  });
2362
2381
  const panelGroupContext = useContext(PanelGroupContext);
2363
2382
  if (panelGroupContext === null) {
@@ -2400,49 +2419,56 @@ function PanelResizeHandle({
2400
2419
  }
2401
2420
  const element = elementRef.current;
2402
2421
  assert(element, "Element ref not attached");
2422
+ let didMove = false;
2403
2423
  const setResizeHandlerState = (action, isActive, event) => {
2404
- if (isActive) {
2405
- switch (action) {
2406
- case "down":
2407
- {
2408
- setState("drag");
2409
- assert(event, 'Expected event to be defined for "down" action');
2410
- startDragging(resizeHandleId, event);
2411
- const {
2412
- onDragging
2413
- } = callbacksRef.current;
2414
- if (onDragging) {
2415
- onDragging(true);
2416
- }
2417
- break;
2418
- }
2419
- case "move":
2420
- {
2421
- const {
2422
- state
2423
- } = committedValuesRef.current;
2424
- if (state !== "drag") {
2425
- setState("hover");
2426
- }
2427
- assert(event, 'Expected event to be defined for "move" action');
2428
- resizeHandler(event);
2429
- break;
2430
- }
2431
- case "up":
2432
- {
2424
+ if (!isActive) {
2425
+ setState("inactive");
2426
+ return;
2427
+ }
2428
+ switch (action) {
2429
+ case "down":
2430
+ {
2431
+ setState("drag");
2432
+ didMove = false;
2433
+ assert(event, 'Expected event to be defined for "down" action');
2434
+ startDragging(resizeHandleId, event);
2435
+ const {
2436
+ onDragging,
2437
+ onPointerDown
2438
+ } = callbacksRef.current;
2439
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2440
+ onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2441
+ break;
2442
+ }
2443
+ case "move":
2444
+ {
2445
+ const {
2446
+ state
2447
+ } = committedValuesRef.current;
2448
+ didMove = true;
2449
+ if (state !== "drag") {
2433
2450
  setState("hover");
2434
- stopDragging();
2435
- const {
2436
- onDragging
2437
- } = callbacksRef.current;
2438
- if (onDragging) {
2439
- onDragging(false);
2440
- }
2441
- break;
2442
2451
  }
2443
- }
2444
- } else {
2445
- setState("inactive");
2452
+ assert(event, 'Expected event to be defined for "move" action');
2453
+ resizeHandler(event);
2454
+ break;
2455
+ }
2456
+ case "up":
2457
+ {
2458
+ setState("hover");
2459
+ stopDragging();
2460
+ const {
2461
+ onClick,
2462
+ onDragging,
2463
+ onPointerUp
2464
+ } = callbacksRef.current;
2465
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2466
+ onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2467
+ if (!didMove) {
2468
+ onClick === null || onClick === void 0 ? void 0 : onClick();
2469
+ }
2470
+ break;
2471
+ }
2446
2472
  }
2447
2473
  };
2448
2474
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2481,13 +2507,13 @@ function PanelResizeHandle({
2481
2507
  },
2482
2508
  tabIndex,
2483
2509
  // CSS selectors
2484
- "data-panel-group-direction": direction,
2485
- "data-panel-group-id": groupId,
2486
- "data-resize-handle": "",
2487
- "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2488
- "data-resize-handle-state": state,
2489
- "data-panel-resize-handle-enabled": !disabled,
2490
- "data-panel-resize-handle-id": resizeHandleId
2510
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2511
+ [DATA_ATTRIBUTES.groupId]: groupId,
2512
+ [DATA_ATTRIBUTES.resizeHandle]: "",
2513
+ [DATA_ATTRIBUTES.resizeHandleActive]: state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2514
+ [DATA_ATTRIBUTES.resizeHandleEnabled]: !disabled,
2515
+ [DATA_ATTRIBUTES.resizeHandleId]: resizeHandleId,
2516
+ [DATA_ATTRIBUTES.resizeHandleState]: state
2491
2517
  });
2492
2518
  }
2493
2519
  PanelResizeHandle.displayName = "PanelResizeHandle";
@@ -2521,4 +2547,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2521
2547
  };
2522
2548
  }
2523
2549
 
2524
- export { Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };
2550
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };