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,37 +1,32 @@
1
1
  import * as React from 'react';
2
+ import { createContext, useLayoutEffect, useRef, forwardRef, createElement, useContext, useImperativeHandle, useState, useCallback, useEffect, useMemo } from 'react';
2
3
 
3
4
  const isBrowser = typeof window !== "undefined";
4
5
 
5
- // This module exists to work around Webpack issue https://github.com/webpack/webpack/issues/14814
6
-
7
- // eslint-disable-next-line no-restricted-imports
8
-
9
- const {
10
- createElement,
11
- createContext,
12
- createRef,
13
- forwardRef,
14
- useCallback,
15
- useContext,
16
- useEffect,
17
- useImperativeHandle,
18
- useLayoutEffect,
19
- useMemo,
20
- useRef,
21
- useState
22
- } = React;
23
-
24
- // `Math.random()` and `.slice(0, 5)` prevents bundlers from trying to `import { useId } from 'react'`
25
- const useId = React[`useId${Math.random()}`.slice(0, 5)];
26
- const useLayoutEffect_do_not_use_directly = useLayoutEffect;
27
-
28
6
  // The "contextmenu" event is not supported as a PointerEvent in all browsers yet, so MouseEvent still need to be handled
29
7
 
30
8
  const PanelGroupContext = createContext(null);
31
9
  PanelGroupContext.displayName = "PanelGroupContext";
32
10
 
33
- const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect_do_not_use_directly : () => {};
11
+ const DATA_ATTRIBUTES = {
12
+ group: "data-panel-group",
13
+ groupDirection: "data-panel-group-direction",
14
+ groupId: "data-panel-group-id",
15
+ panel: "data-panel",
16
+ panelCollapsible: "data-panel-collapsible",
17
+ panelId: "data-panel-id",
18
+ panelSize: "data-panel-size",
19
+ resizeHandle: "data-resize-handle",
20
+ resizeHandleActive: "data-resize-handle-active",
21
+ resizeHandleEnabled: "data-panel-resize-handle-enabled",
22
+ resizeHandleId: "data-panel-resize-handle-id",
23
+ resizeHandleState: "data-resize-handle-state"
24
+ };
25
+ const PRECISION = 10;
26
+
27
+ const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : () => {};
34
28
 
29
+ const useId = React["useId".toString()];
35
30
  const wrappedUseId = typeof useId === "function" ? useId : () => null;
36
31
  let counter = 0;
37
32
  function useUniqueId(idFromParams = null) {
@@ -170,17 +165,17 @@ function PanelWithForwardedRef({
170
165
  ...rest,
171
166
  children,
172
167
  className: classNameFromProps,
173
- id: idFromProps,
168
+ id: panelId,
174
169
  style: {
175
170
  ...style,
176
171
  ...styleFromProps
177
172
  },
178
173
  // CSS selectors
179
- "data-panel": "",
180
- "data-panel-collapsible": collapsible || undefined,
181
- "data-panel-group-id": groupId,
182
- "data-panel-id": panelId,
183
- "data-panel-size": parseFloat("" + style.flexGrow).toFixed(1)
174
+ [DATA_ATTRIBUTES.groupId]: groupId,
175
+ [DATA_ATTRIBUTES.panel]: "",
176
+ [DATA_ATTRIBUTES.panelCollapsible]: collapsible || undefined,
177
+ [DATA_ATTRIBUTES.panelId]: panelId,
178
+ [DATA_ATTRIBUTES.panelSize]: parseFloat("" + style.flexGrow).toFixed(1)
184
179
  });
185
180
  }
186
181
  const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
@@ -200,6 +195,7 @@ function setNonce(value) {
200
195
 
201
196
  let currentCursorStyle = null;
202
197
  let enabled = true;
198
+ let prevRuleIndex = -1;
203
199
  let styleElement = null;
204
200
  function disableGlobalCursorStyles() {
205
201
  enabled = false;
@@ -249,9 +245,11 @@ function resetGlobalCursorStyle() {
249
245
  document.head.removeChild(styleElement);
250
246
  currentCursorStyle = null;
251
247
  styleElement = null;
248
+ prevRuleIndex = -1;
252
249
  }
253
250
  }
254
251
  function setGlobalCursorStyle(state, constraintFlags) {
252
+ var _styleElement$sheet$i, _styleElement$sheet2;
255
253
  if (!enabled) {
256
254
  return;
257
255
  }
@@ -268,7 +266,11 @@ function setGlobalCursorStyle(state, constraintFlags) {
268
266
  }
269
267
  document.head.appendChild(styleElement);
270
268
  }
271
- styleElement.innerHTML = `*{cursor: ${style}!important;}`;
269
+ if (prevRuleIndex >= 0) {
270
+ var _styleElement$sheet;
271
+ (_styleElement$sheet = styleElement.sheet) === null || _styleElement$sheet === void 0 ? void 0 : _styleElement$sheet.removeRule(prevRuleIndex);
272
+ }
273
+ 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;
272
274
  }
273
275
 
274
276
  function isKeyDown(event) {
@@ -499,7 +501,9 @@ function handlePointerDown(event) {
499
501
  if (intersectingHandles.length > 0) {
500
502
  updateResizeHandlerStates("down", event);
501
503
  event.preventDefault();
502
- event.stopPropagation();
504
+ if (!isWithinResizeHandle(target)) {
505
+ event.stopImmediatePropagation();
506
+ }
503
507
  }
504
508
  }
505
509
  function handlePointerMove(event) {
@@ -548,6 +552,9 @@ function handlePointerUp(event) {
548
552
  isPointerDown = false;
549
553
  if (intersectingHandles.length > 0) {
550
554
  event.preventDefault();
555
+ if (!isWithinResizeHandle(target)) {
556
+ event.stopImmediatePropagation();
557
+ }
551
558
  }
552
559
  updateResizeHandlerStates("up", event);
553
560
  recalculateIntersectingHandles({
@@ -558,6 +565,16 @@ function handlePointerUp(event) {
558
565
  updateCursor();
559
566
  updateListeners();
560
567
  }
568
+ function isWithinResizeHandle(element) {
569
+ let currentElement = element;
570
+ while (currentElement) {
571
+ if (currentElement.hasAttribute(DATA_ATTRIBUTES.resizeHandle)) {
572
+ return true;
573
+ }
574
+ currentElement = currentElement.parentElement;
575
+ }
576
+ return false;
577
+ }
561
578
  function recalculateIntersectingHandles({
562
579
  target,
563
580
  x,
@@ -649,47 +666,42 @@ function updateCursor() {
649
666
  resetGlobalCursorStyle();
650
667
  }
651
668
  }
669
+ let listenersAbortController = new AbortController();
652
670
  function updateListeners() {
653
- ownerDocumentCounts.forEach((_, ownerDocument) => {
654
- const {
655
- body
656
- } = ownerDocument;
657
- body.removeEventListener("contextmenu", handlePointerUp);
658
- body.removeEventListener("pointerdown", handlePointerDown);
659
- body.removeEventListener("pointerleave", handlePointerMove);
660
- body.removeEventListener("pointermove", handlePointerMove);
661
- });
662
- window.removeEventListener("pointerup", handlePointerUp);
663
- window.removeEventListener("pointercancel", handlePointerUp);
664
- if (registeredResizeHandlers.size > 0) {
665
- if (isPointerDown) {
666
- if (intersectingHandles.length > 0) {
667
- ownerDocumentCounts.forEach((count, ownerDocument) => {
668
- const {
669
- body
670
- } = ownerDocument;
671
- if (count > 0) {
672
- body.addEventListener("contextmenu", handlePointerUp);
673
- body.addEventListener("pointerleave", handlePointerMove);
674
- body.addEventListener("pointermove", handlePointerMove);
675
- }
676
- });
677
- }
678
- window.addEventListener("pointerup", handlePointerUp);
679
- window.addEventListener("pointercancel", handlePointerUp);
680
- } else {
671
+ listenersAbortController.abort();
672
+ listenersAbortController = new AbortController();
673
+ const options = {
674
+ capture: true,
675
+ signal: listenersAbortController.signal
676
+ };
677
+ if (!registeredResizeHandlers.size) {
678
+ return;
679
+ }
680
+ if (isPointerDown) {
681
+ if (intersectingHandles.length > 0) {
681
682
  ownerDocumentCounts.forEach((count, ownerDocument) => {
682
683
  const {
683
684
  body
684
685
  } = ownerDocument;
685
686
  if (count > 0) {
686
- body.addEventListener("pointerdown", handlePointerDown, {
687
- capture: true
688
- });
689
- body.addEventListener("pointermove", handlePointerMove);
687
+ body.addEventListener("contextmenu", handlePointerUp, options);
688
+ body.addEventListener("pointerleave", handlePointerMove, options);
689
+ body.addEventListener("pointermove", handlePointerMove, options);
690
690
  }
691
691
  });
692
692
  }
693
+ window.addEventListener("pointerup", handlePointerUp, options);
694
+ window.addEventListener("pointercancel", handlePointerUp, options);
695
+ } else {
696
+ ownerDocumentCounts.forEach((count, ownerDocument) => {
697
+ const {
698
+ body
699
+ } = ownerDocument;
700
+ if (count > 0) {
701
+ body.addEventListener("pointerdown", handlePointerDown, options);
702
+ body.addEventListener("pointermove", handlePointerMove, options);
703
+ }
704
+ });
693
705
  }
694
706
  }
695
707
  function updateResizeHandlerStates(action, event) {
@@ -714,8 +726,6 @@ function assert(expectedCondition, message) {
714
726
  }
715
727
  }
716
728
 
717
- const PRECISION = 10;
718
-
719
729
  function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
720
730
  if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
721
731
  return 0;
@@ -1059,12 +1069,12 @@ function calculateAriaValues({
1059
1069
  }
1060
1070
 
1061
1071
  function getResizeHandleElementsForGroup(groupId, scope = document) {
1062
- return Array.from(scope.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
1072
+ return Array.from(scope.querySelectorAll(`[${DATA_ATTRIBUTES.resizeHandleId}][data-panel-group-id="${groupId}"]`));
1063
1073
  }
1064
1074
 
1065
1075
  function getResizeHandleElementIndex(groupId, id, scope = document) {
1066
1076
  const handles = getResizeHandleElementsForGroup(groupId, scope);
1067
- const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
1077
+ const index = handles.findIndex(handle => handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId) === id);
1068
1078
  return index !== null && index !== void 0 ? index : null;
1069
1079
  }
1070
1080
 
@@ -1089,7 +1099,7 @@ function getPanelGroupElement(id, rootElement = document) {
1089
1099
  }
1090
1100
 
1091
1101
  function getResizeHandleElement(id, scope = document) {
1092
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
1102
+ const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1093
1103
  if (element) {
1094
1104
  return element;
1095
1105
  }
@@ -1178,7 +1188,7 @@ function useWindowSplitterPanelGroupBehavior({
1178
1188
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1179
1189
  assert(handles, `No resize handles found for group id "${groupId}"`);
1180
1190
  const cleanupFunctions = handles.map(handle => {
1181
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1191
+ const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1182
1192
  assert(handleId, `Resize handle element has no handle id attribute`);
1183
1193
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1184
1194
  if (idBefore == null || idAfter == null) {
@@ -1256,7 +1266,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
1256
1266
  const isHorizontal = direction === "horizontal";
1257
1267
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1258
1268
  assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1259
- const groupId = handleElement.getAttribute("data-panel-group-id");
1269
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1260
1270
  assert(groupId, `Resize handle element has no group id attribute`);
1261
1271
  let {
1262
1272
  initialCursorPosition
@@ -2262,9 +2272,9 @@ function PanelGroupWithForwardedRef({
2262
2272
  ...styleFromProps
2263
2273
  },
2264
2274
  // CSS selectors
2265
- "data-panel-group": "",
2266
- "data-panel-group-direction": direction,
2267
- "data-panel-group-id": groupId
2275
+ [DATA_ATTRIBUTES.group]: "",
2276
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2277
+ [DATA_ATTRIBUTES.groupId]: groupId
2268
2278
  }));
2269
2279
  }
2270
2280
  const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
@@ -2323,7 +2333,7 @@ function useWindowSplitterResizeHandlerBehavior({
2323
2333
  case "F6":
2324
2334
  {
2325
2335
  event.preventDefault();
2326
- const groupId = handleElement.getAttribute("data-panel-group-id");
2336
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2327
2337
  assert(groupId, `No group element found for id "${groupId}"`);
2328
2338
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2329
2339
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
@@ -2349,8 +2359,11 @@ function PanelResizeHandle({
2349
2359
  hitAreaMargins,
2350
2360
  id: idFromProps,
2351
2361
  onBlur,
2362
+ onClick,
2352
2363
  onDragging,
2353
2364
  onFocus,
2365
+ onPointerDown,
2366
+ onPointerUp,
2354
2367
  style: styleFromProps = {},
2355
2368
  tabIndex = 0,
2356
2369
  tagName: Type = "div",
@@ -2361,10 +2374,16 @@ function PanelResizeHandle({
2361
2374
 
2362
2375
  // Use a ref to guard against users passing inline props
2363
2376
  const callbacksRef = useRef({
2364
- onDragging
2377
+ onClick,
2378
+ onDragging,
2379
+ onPointerDown,
2380
+ onPointerUp
2365
2381
  });
2366
2382
  useEffect(() => {
2383
+ callbacksRef.current.onClick = onClick;
2367
2384
  callbacksRef.current.onDragging = onDragging;
2385
+ callbacksRef.current.onPointerDown = onPointerDown;
2386
+ callbacksRef.current.onPointerUp = onPointerUp;
2368
2387
  });
2369
2388
  const panelGroupContext = useContext(PanelGroupContext);
2370
2389
  if (panelGroupContext === null) {
@@ -2407,49 +2426,56 @@ function PanelResizeHandle({
2407
2426
  }
2408
2427
  const element = elementRef.current;
2409
2428
  assert(element, "Element ref not attached");
2429
+ let didMove = false;
2410
2430
  const setResizeHandlerState = (action, isActive, event) => {
2411
- if (isActive) {
2412
- switch (action) {
2413
- case "down":
2414
- {
2415
- setState("drag");
2416
- assert(event, 'Expected event to be defined for "down" action');
2417
- startDragging(resizeHandleId, event);
2418
- const {
2419
- onDragging
2420
- } = callbacksRef.current;
2421
- if (onDragging) {
2422
- onDragging(true);
2423
- }
2424
- break;
2425
- }
2426
- case "move":
2427
- {
2428
- const {
2429
- state
2430
- } = committedValuesRef.current;
2431
- if (state !== "drag") {
2432
- setState("hover");
2433
- }
2434
- assert(event, 'Expected event to be defined for "move" action');
2435
- resizeHandler(event);
2436
- break;
2437
- }
2438
- case "up":
2439
- {
2431
+ if (!isActive) {
2432
+ setState("inactive");
2433
+ return;
2434
+ }
2435
+ switch (action) {
2436
+ case "down":
2437
+ {
2438
+ setState("drag");
2439
+ didMove = false;
2440
+ assert(event, 'Expected event to be defined for "down" action');
2441
+ startDragging(resizeHandleId, event);
2442
+ const {
2443
+ onDragging,
2444
+ onPointerDown
2445
+ } = callbacksRef.current;
2446
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2447
+ onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2448
+ break;
2449
+ }
2450
+ case "move":
2451
+ {
2452
+ const {
2453
+ state
2454
+ } = committedValuesRef.current;
2455
+ didMove = true;
2456
+ if (state !== "drag") {
2440
2457
  setState("hover");
2441
- stopDragging();
2442
- const {
2443
- onDragging
2444
- } = callbacksRef.current;
2445
- if (onDragging) {
2446
- onDragging(false);
2447
- }
2448
- break;
2449
2458
  }
2450
- }
2451
- } else {
2452
- setState("inactive");
2459
+ assert(event, 'Expected event to be defined for "move" action');
2460
+ resizeHandler(event);
2461
+ break;
2462
+ }
2463
+ case "up":
2464
+ {
2465
+ setState("hover");
2466
+ stopDragging();
2467
+ const {
2468
+ onClick,
2469
+ onDragging,
2470
+ onPointerUp
2471
+ } = callbacksRef.current;
2472
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2473
+ onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2474
+ if (!didMove) {
2475
+ onClick === null || onClick === void 0 ? void 0 : onClick();
2476
+ }
2477
+ break;
2478
+ }
2453
2479
  }
2454
2480
  };
2455
2481
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2488,13 +2514,13 @@ function PanelResizeHandle({
2488
2514
  },
2489
2515
  tabIndex,
2490
2516
  // CSS selectors
2491
- "data-panel-group-direction": direction,
2492
- "data-panel-group-id": groupId,
2493
- "data-resize-handle": "",
2494
- "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2495
- "data-resize-handle-state": state,
2496
- "data-panel-resize-handle-enabled": !disabled,
2497
- "data-panel-resize-handle-id": resizeHandleId
2517
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2518
+ [DATA_ATTRIBUTES.groupId]: groupId,
2519
+ [DATA_ATTRIBUTES.resizeHandle]: "",
2520
+ [DATA_ATTRIBUTES.resizeHandleActive]: state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2521
+ [DATA_ATTRIBUTES.resizeHandleEnabled]: !disabled,
2522
+ [DATA_ATTRIBUTES.resizeHandleId]: resizeHandleId,
2523
+ [DATA_ATTRIBUTES.resizeHandleState]: state
2498
2524
  });
2499
2525
  }
2500
2526
  PanelResizeHandle.displayName = "PanelResizeHandle";
@@ -2528,4 +2554,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2528
2554
  };
2529
2555
  }
2530
2556
 
2531
- export { Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };
2557
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };