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,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) {
@@ -157,17 +152,17 @@ function PanelWithForwardedRef({
157
152
  ...rest,
158
153
  children,
159
154
  className: classNameFromProps,
160
- id: idFromProps,
155
+ id: panelId,
161
156
  style: {
162
157
  ...style,
163
158
  ...styleFromProps
164
159
  },
165
160
  // CSS selectors
166
- "data-panel": "",
167
- "data-panel-collapsible": collapsible || undefined,
168
- "data-panel-group-id": groupId,
169
- "data-panel-id": panelId,
170
- "data-panel-size": parseFloat("" + style.flexGrow).toFixed(1)
161
+ [DATA_ATTRIBUTES.groupId]: groupId,
162
+ [DATA_ATTRIBUTES.panel]: "",
163
+ [DATA_ATTRIBUTES.panelCollapsible]: collapsible || undefined,
164
+ [DATA_ATTRIBUTES.panelId]: panelId,
165
+ [DATA_ATTRIBUTES.panelSize]: parseFloat("" + style.flexGrow).toFixed(1)
171
166
  });
172
167
  }
173
168
  const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
@@ -187,6 +182,7 @@ function setNonce(value) {
187
182
 
188
183
  let currentCursorStyle = null;
189
184
  let enabled = true;
185
+ let prevRuleIndex = -1;
190
186
  let styleElement = null;
191
187
  function disableGlobalCursorStyles() {
192
188
  enabled = false;
@@ -236,9 +232,11 @@ function resetGlobalCursorStyle() {
236
232
  document.head.removeChild(styleElement);
237
233
  currentCursorStyle = null;
238
234
  styleElement = null;
235
+ prevRuleIndex = -1;
239
236
  }
240
237
  }
241
238
  function setGlobalCursorStyle(state, constraintFlags) {
239
+ var _styleElement$sheet$i, _styleElement$sheet2;
242
240
  if (!enabled) {
243
241
  return;
244
242
  }
@@ -255,7 +253,11 @@ function setGlobalCursorStyle(state, constraintFlags) {
255
253
  }
256
254
  document.head.appendChild(styleElement);
257
255
  }
258
- styleElement.innerHTML = `*{cursor: ${style}!important;}`;
256
+ if (prevRuleIndex >= 0) {
257
+ var _styleElement$sheet;
258
+ (_styleElement$sheet = styleElement.sheet) === null || _styleElement$sheet === void 0 ? void 0 : _styleElement$sheet.removeRule(prevRuleIndex);
259
+ }
260
+ 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;
259
261
  }
260
262
 
261
263
  function isKeyDown(event) {
@@ -486,7 +488,9 @@ function handlePointerDown(event) {
486
488
  if (intersectingHandles.length > 0) {
487
489
  updateResizeHandlerStates("down", event);
488
490
  event.preventDefault();
489
- event.stopPropagation();
491
+ if (!isWithinResizeHandle(target)) {
492
+ event.stopImmediatePropagation();
493
+ }
490
494
  }
491
495
  }
492
496
  function handlePointerMove(event) {
@@ -535,6 +539,9 @@ function handlePointerUp(event) {
535
539
  isPointerDown = false;
536
540
  if (intersectingHandles.length > 0) {
537
541
  event.preventDefault();
542
+ if (!isWithinResizeHandle(target)) {
543
+ event.stopImmediatePropagation();
544
+ }
538
545
  }
539
546
  updateResizeHandlerStates("up", event);
540
547
  recalculateIntersectingHandles({
@@ -545,6 +552,16 @@ function handlePointerUp(event) {
545
552
  updateCursor();
546
553
  updateListeners();
547
554
  }
555
+ function isWithinResizeHandle(element) {
556
+ let currentElement = element;
557
+ while (currentElement) {
558
+ if (currentElement.hasAttribute(DATA_ATTRIBUTES.resizeHandle)) {
559
+ return true;
560
+ }
561
+ currentElement = currentElement.parentElement;
562
+ }
563
+ return false;
564
+ }
548
565
  function recalculateIntersectingHandles({
549
566
  target,
550
567
  x,
@@ -636,47 +653,42 @@ function updateCursor() {
636
653
  resetGlobalCursorStyle();
637
654
  }
638
655
  }
656
+ let listenersAbortController = new AbortController();
639
657
  function updateListeners() {
640
- ownerDocumentCounts.forEach((_, ownerDocument) => {
641
- const {
642
- body
643
- } = ownerDocument;
644
- body.removeEventListener("contextmenu", handlePointerUp);
645
- body.removeEventListener("pointerdown", handlePointerDown);
646
- body.removeEventListener("pointerleave", handlePointerMove);
647
- body.removeEventListener("pointermove", handlePointerMove);
648
- });
649
- window.removeEventListener("pointerup", handlePointerUp);
650
- window.removeEventListener("pointercancel", handlePointerUp);
651
- if (registeredResizeHandlers.size > 0) {
652
- if (isPointerDown) {
653
- if (intersectingHandles.length > 0) {
654
- ownerDocumentCounts.forEach((count, ownerDocument) => {
655
- const {
656
- body
657
- } = ownerDocument;
658
- if (count > 0) {
659
- body.addEventListener("contextmenu", handlePointerUp);
660
- body.addEventListener("pointerleave", handlePointerMove);
661
- body.addEventListener("pointermove", handlePointerMove);
662
- }
663
- });
664
- }
665
- window.addEventListener("pointerup", handlePointerUp);
666
- window.addEventListener("pointercancel", handlePointerUp);
667
- } else {
658
+ listenersAbortController.abort();
659
+ listenersAbortController = new AbortController();
660
+ const options = {
661
+ capture: true,
662
+ signal: listenersAbortController.signal
663
+ };
664
+ if (!registeredResizeHandlers.size) {
665
+ return;
666
+ }
667
+ if (isPointerDown) {
668
+ if (intersectingHandles.length > 0) {
668
669
  ownerDocumentCounts.forEach((count, ownerDocument) => {
669
670
  const {
670
671
  body
671
672
  } = ownerDocument;
672
673
  if (count > 0) {
673
- body.addEventListener("pointerdown", handlePointerDown, {
674
- capture: true
675
- });
676
- body.addEventListener("pointermove", handlePointerMove);
674
+ body.addEventListener("contextmenu", handlePointerUp, options);
675
+ body.addEventListener("pointerleave", handlePointerMove, options);
676
+ body.addEventListener("pointermove", handlePointerMove, options);
677
677
  }
678
678
  });
679
679
  }
680
+ window.addEventListener("pointerup", handlePointerUp, options);
681
+ window.addEventListener("pointercancel", handlePointerUp, options);
682
+ } else {
683
+ ownerDocumentCounts.forEach((count, ownerDocument) => {
684
+ const {
685
+ body
686
+ } = ownerDocument;
687
+ if (count > 0) {
688
+ body.addEventListener("pointerdown", handlePointerDown, options);
689
+ body.addEventListener("pointermove", handlePointerMove, options);
690
+ }
691
+ });
680
692
  }
681
693
  }
682
694
  function updateResizeHandlerStates(action, event) {
@@ -701,8 +713,6 @@ function assert(expectedCondition, message) {
701
713
  }
702
714
  }
703
715
 
704
- const PRECISION = 10;
705
-
706
716
  function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
707
717
  if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
708
718
  return 0;
@@ -1046,12 +1056,12 @@ function calculateAriaValues({
1046
1056
  }
1047
1057
 
1048
1058
  function getResizeHandleElementsForGroup(groupId, scope = document) {
1049
- return Array.from(scope.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
1059
+ return Array.from(scope.querySelectorAll(`[${DATA_ATTRIBUTES.resizeHandleId}][data-panel-group-id="${groupId}"]`));
1050
1060
  }
1051
1061
 
1052
1062
  function getResizeHandleElementIndex(groupId, id, scope = document) {
1053
1063
  const handles = getResizeHandleElementsForGroup(groupId, scope);
1054
- const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
1064
+ const index = handles.findIndex(handle => handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId) === id);
1055
1065
  return index !== null && index !== void 0 ? index : null;
1056
1066
  }
1057
1067
 
@@ -1076,7 +1086,7 @@ function getPanelGroupElement(id, rootElement = document) {
1076
1086
  }
1077
1087
 
1078
1088
  function getResizeHandleElement(id, scope = document) {
1079
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
1089
+ const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1080
1090
  if (element) {
1081
1091
  return element;
1082
1092
  }
@@ -1155,7 +1165,7 @@ function useWindowSplitterPanelGroupBehavior({
1155
1165
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1156
1166
  assert(handles, `No resize handles found for group id "${groupId}"`);
1157
1167
  const cleanupFunctions = handles.map(handle => {
1158
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1168
+ const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1159
1169
  assert(handleId, `Resize handle element has no handle id attribute`);
1160
1170
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1161
1171
  if (idBefore == null || idAfter == null) {
@@ -1233,7 +1243,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
1233
1243
  const isHorizontal = direction === "horizontal";
1234
1244
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1235
1245
  assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1236
- const groupId = handleElement.getAttribute("data-panel-group-id");
1246
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1237
1247
  assert(groupId, `Resize handle element has no group id attribute`);
1238
1248
  let {
1239
1249
  initialCursorPosition
@@ -2149,9 +2159,9 @@ function PanelGroupWithForwardedRef({
2149
2159
  ...styleFromProps
2150
2160
  },
2151
2161
  // CSS selectors
2152
- "data-panel-group": "",
2153
- "data-panel-group-direction": direction,
2154
- "data-panel-group-id": groupId
2162
+ [DATA_ATTRIBUTES.group]: "",
2163
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2164
+ [DATA_ATTRIBUTES.groupId]: groupId
2155
2165
  }));
2156
2166
  }
2157
2167
  const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
@@ -2210,7 +2220,7 @@ function useWindowSplitterResizeHandlerBehavior({
2210
2220
  case "F6":
2211
2221
  {
2212
2222
  event.preventDefault();
2213
- const groupId = handleElement.getAttribute("data-panel-group-id");
2223
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2214
2224
  assert(groupId, `No group element found for id "${groupId}"`);
2215
2225
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2216
2226
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
@@ -2236,8 +2246,11 @@ function PanelResizeHandle({
2236
2246
  hitAreaMargins,
2237
2247
  id: idFromProps,
2238
2248
  onBlur,
2249
+ onClick,
2239
2250
  onDragging,
2240
2251
  onFocus,
2252
+ onPointerDown,
2253
+ onPointerUp,
2241
2254
  style: styleFromProps = {},
2242
2255
  tabIndex = 0,
2243
2256
  tagName: Type = "div",
@@ -2248,10 +2261,16 @@ function PanelResizeHandle({
2248
2261
 
2249
2262
  // Use a ref to guard against users passing inline props
2250
2263
  const callbacksRef = useRef({
2251
- onDragging
2264
+ onClick,
2265
+ onDragging,
2266
+ onPointerDown,
2267
+ onPointerUp
2252
2268
  });
2253
2269
  useEffect(() => {
2270
+ callbacksRef.current.onClick = onClick;
2254
2271
  callbacksRef.current.onDragging = onDragging;
2272
+ callbacksRef.current.onPointerDown = onPointerDown;
2273
+ callbacksRef.current.onPointerUp = onPointerUp;
2255
2274
  });
2256
2275
  const panelGroupContext = useContext(PanelGroupContext);
2257
2276
  if (panelGroupContext === null) {
@@ -2294,49 +2313,56 @@ function PanelResizeHandle({
2294
2313
  }
2295
2314
  const element = elementRef.current;
2296
2315
  assert(element, "Element ref not attached");
2316
+ let didMove = false;
2297
2317
  const setResizeHandlerState = (action, isActive, event) => {
2298
- if (isActive) {
2299
- switch (action) {
2300
- case "down":
2301
- {
2302
- setState("drag");
2303
- assert(event, 'Expected event to be defined for "down" action');
2304
- startDragging(resizeHandleId, event);
2305
- const {
2306
- onDragging
2307
- } = callbacksRef.current;
2308
- if (onDragging) {
2309
- onDragging(true);
2310
- }
2311
- break;
2312
- }
2313
- case "move":
2314
- {
2315
- const {
2316
- state
2317
- } = committedValuesRef.current;
2318
- if (state !== "drag") {
2319
- setState("hover");
2320
- }
2321
- assert(event, 'Expected event to be defined for "move" action');
2322
- resizeHandler(event);
2323
- break;
2324
- }
2325
- case "up":
2326
- {
2318
+ if (!isActive) {
2319
+ setState("inactive");
2320
+ return;
2321
+ }
2322
+ switch (action) {
2323
+ case "down":
2324
+ {
2325
+ setState("drag");
2326
+ didMove = false;
2327
+ assert(event, 'Expected event to be defined for "down" action');
2328
+ startDragging(resizeHandleId, event);
2329
+ const {
2330
+ onDragging,
2331
+ onPointerDown
2332
+ } = callbacksRef.current;
2333
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2334
+ onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2335
+ break;
2336
+ }
2337
+ case "move":
2338
+ {
2339
+ const {
2340
+ state
2341
+ } = committedValuesRef.current;
2342
+ didMove = true;
2343
+ if (state !== "drag") {
2327
2344
  setState("hover");
2328
- stopDragging();
2329
- const {
2330
- onDragging
2331
- } = callbacksRef.current;
2332
- if (onDragging) {
2333
- onDragging(false);
2334
- }
2335
- break;
2336
2345
  }
2337
- }
2338
- } else {
2339
- setState("inactive");
2346
+ assert(event, 'Expected event to be defined for "move" action');
2347
+ resizeHandler(event);
2348
+ break;
2349
+ }
2350
+ case "up":
2351
+ {
2352
+ setState("hover");
2353
+ stopDragging();
2354
+ const {
2355
+ onClick,
2356
+ onDragging,
2357
+ onPointerUp
2358
+ } = callbacksRef.current;
2359
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2360
+ onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2361
+ if (!didMove) {
2362
+ onClick === null || onClick === void 0 ? void 0 : onClick();
2363
+ }
2364
+ break;
2365
+ }
2340
2366
  }
2341
2367
  };
2342
2368
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2375,13 +2401,13 @@ function PanelResizeHandle({
2375
2401
  },
2376
2402
  tabIndex,
2377
2403
  // CSS selectors
2378
- "data-panel-group-direction": direction,
2379
- "data-panel-group-id": groupId,
2380
- "data-resize-handle": "",
2381
- "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2382
- "data-resize-handle-state": state,
2383
- "data-panel-resize-handle-enabled": !disabled,
2384
- "data-panel-resize-handle-id": resizeHandleId
2404
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2405
+ [DATA_ATTRIBUTES.groupId]: groupId,
2406
+ [DATA_ATTRIBUTES.resizeHandle]: "",
2407
+ [DATA_ATTRIBUTES.resizeHandleActive]: state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2408
+ [DATA_ATTRIBUTES.resizeHandleEnabled]: !disabled,
2409
+ [DATA_ATTRIBUTES.resizeHandleId]: resizeHandleId,
2410
+ [DATA_ATTRIBUTES.resizeHandleState]: state
2385
2411
  });
2386
2412
  }
2387
2413
  PanelResizeHandle.displayName = "PanelResizeHandle";
@@ -2415,4 +2441,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2415
2441
  };
2416
2442
  }
2417
2443
 
2418
- export { Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };
2444
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };