react-resizable-panels 2.1.8 → 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.
@@ -6,6 +6,22 @@ import { createContext, useLayoutEffect, useRef, forwardRef, createElement, useC
6
6
  const PanelGroupContext = createContext(null);
7
7
  PanelGroupContext.displayName = "PanelGroupContext";
8
8
 
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
+
9
25
  const useIsomorphicLayoutEffect = useLayoutEffect ;
10
26
 
11
27
  const useId = React["useId".toString()];
@@ -142,11 +158,11 @@ function PanelWithForwardedRef({
142
158
  ...styleFromProps
143
159
  },
144
160
  // CSS selectors
145
- "data-panel": "",
146
- "data-panel-collapsible": collapsible || undefined,
147
- "data-panel-group-id": groupId,
148
- "data-panel-id": panelId,
149
- "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)
150
166
  });
151
167
  }
152
168
  const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
@@ -166,6 +182,7 @@ function setNonce(value) {
166
182
 
167
183
  let currentCursorStyle = null;
168
184
  let enabled = true;
185
+ let prevRuleIndex = -1;
169
186
  let styleElement = null;
170
187
  function disableGlobalCursorStyles() {
171
188
  enabled = false;
@@ -215,9 +232,11 @@ function resetGlobalCursorStyle() {
215
232
  document.head.removeChild(styleElement);
216
233
  currentCursorStyle = null;
217
234
  styleElement = null;
235
+ prevRuleIndex = -1;
218
236
  }
219
237
  }
220
238
  function setGlobalCursorStyle(state, constraintFlags) {
239
+ var _styleElement$sheet$i, _styleElement$sheet2;
221
240
  if (!enabled) {
222
241
  return;
223
242
  }
@@ -234,7 +253,11 @@ function setGlobalCursorStyle(state, constraintFlags) {
234
253
  }
235
254
  document.head.appendChild(styleElement);
236
255
  }
237
- 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;
238
261
  }
239
262
 
240
263
  function isKeyDown(event) {
@@ -465,7 +488,9 @@ function handlePointerDown(event) {
465
488
  if (intersectingHandles.length > 0) {
466
489
  updateResizeHandlerStates("down", event);
467
490
  event.preventDefault();
468
- event.stopPropagation();
491
+ if (!isWithinResizeHandle(target)) {
492
+ event.stopImmediatePropagation();
493
+ }
469
494
  }
470
495
  }
471
496
  function handlePointerMove(event) {
@@ -514,6 +539,9 @@ function handlePointerUp(event) {
514
539
  isPointerDown = false;
515
540
  if (intersectingHandles.length > 0) {
516
541
  event.preventDefault();
542
+ if (!isWithinResizeHandle(target)) {
543
+ event.stopImmediatePropagation();
544
+ }
517
545
  }
518
546
  updateResizeHandlerStates("up", event);
519
547
  recalculateIntersectingHandles({
@@ -524,6 +552,16 @@ function handlePointerUp(event) {
524
552
  updateCursor();
525
553
  updateListeners();
526
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
+ }
527
565
  function recalculateIntersectingHandles({
528
566
  target,
529
567
  x,
@@ -615,49 +653,42 @@ function updateCursor() {
615
653
  resetGlobalCursorStyle();
616
654
  }
617
655
  }
656
+ let listenersAbortController = new AbortController();
618
657
  function updateListeners() {
619
- ownerDocumentCounts.forEach((_, ownerDocument) => {
620
- const {
621
- body
622
- } = ownerDocument;
623
- body.removeEventListener("contextmenu", handlePointerUp);
624
- body.removeEventListener("pointerdown", handlePointerDown, {
625
- capture: true
626
- });
627
- body.removeEventListener("pointerleave", handlePointerMove);
628
- body.removeEventListener("pointermove", handlePointerMove);
629
- });
630
- window.removeEventListener("pointerup", handlePointerUp);
631
- window.removeEventListener("pointercancel", handlePointerUp);
632
- if (registeredResizeHandlers.size > 0) {
633
- if (isPointerDown) {
634
- if (intersectingHandles.length > 0) {
635
- ownerDocumentCounts.forEach((count, ownerDocument) => {
636
- const {
637
- body
638
- } = ownerDocument;
639
- if (count > 0) {
640
- body.addEventListener("contextmenu", handlePointerUp);
641
- body.addEventListener("pointerleave", handlePointerMove);
642
- body.addEventListener("pointermove", handlePointerMove);
643
- }
644
- });
645
- }
646
- window.addEventListener("pointerup", handlePointerUp);
647
- window.addEventListener("pointercancel", handlePointerUp);
648
- } 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) {
649
669
  ownerDocumentCounts.forEach((count, ownerDocument) => {
650
670
  const {
651
671
  body
652
672
  } = ownerDocument;
653
673
  if (count > 0) {
654
- body.addEventListener("pointerdown", handlePointerDown, {
655
- capture: true
656
- });
657
- body.addEventListener("pointermove", handlePointerMove);
674
+ body.addEventListener("contextmenu", handlePointerUp, options);
675
+ body.addEventListener("pointerleave", handlePointerMove, options);
676
+ body.addEventListener("pointermove", handlePointerMove, options);
658
677
  }
659
678
  });
660
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
+ });
661
692
  }
662
693
  }
663
694
  function updateResizeHandlerStates(action, event) {
@@ -682,8 +713,6 @@ function assert(expectedCondition, message) {
682
713
  }
683
714
  }
684
715
 
685
- const PRECISION = 10;
686
-
687
716
  function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
688
717
  if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
689
718
  return 0;
@@ -1027,12 +1056,12 @@ function calculateAriaValues({
1027
1056
  }
1028
1057
 
1029
1058
  function getResizeHandleElementsForGroup(groupId, scope = document) {
1030
- 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}"]`));
1031
1060
  }
1032
1061
 
1033
1062
  function getResizeHandleElementIndex(groupId, id, scope = document) {
1034
1063
  const handles = getResizeHandleElementsForGroup(groupId, scope);
1035
- 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);
1036
1065
  return index !== null && index !== void 0 ? index : null;
1037
1066
  }
1038
1067
 
@@ -1057,7 +1086,7 @@ function getPanelGroupElement(id, rootElement = document) {
1057
1086
  }
1058
1087
 
1059
1088
  function getResizeHandleElement(id, scope = document) {
1060
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
1089
+ const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1061
1090
  if (element) {
1062
1091
  return element;
1063
1092
  }
@@ -1136,7 +1165,7 @@ function useWindowSplitterPanelGroupBehavior({
1136
1165
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1137
1166
  assert(handles, `No resize handles found for group id "${groupId}"`);
1138
1167
  const cleanupFunctions = handles.map(handle => {
1139
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1168
+ const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1140
1169
  assert(handleId, `Resize handle element has no handle id attribute`);
1141
1170
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1142
1171
  if (idBefore == null || idAfter == null) {
@@ -1214,7 +1243,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
1214
1243
  const isHorizontal = direction === "horizontal";
1215
1244
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1216
1245
  assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1217
- const groupId = handleElement.getAttribute("data-panel-group-id");
1246
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1218
1247
  assert(groupId, `Resize handle element has no group id attribute`);
1219
1248
  let {
1220
1249
  initialCursorPosition
@@ -2130,9 +2159,9 @@ function PanelGroupWithForwardedRef({
2130
2159
  ...styleFromProps
2131
2160
  },
2132
2161
  // CSS selectors
2133
- "data-panel-group": "",
2134
- "data-panel-group-direction": direction,
2135
- "data-panel-group-id": groupId
2162
+ [DATA_ATTRIBUTES.group]: "",
2163
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2164
+ [DATA_ATTRIBUTES.groupId]: groupId
2136
2165
  }));
2137
2166
  }
2138
2167
  const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
@@ -2191,7 +2220,7 @@ function useWindowSplitterResizeHandlerBehavior({
2191
2220
  case "F6":
2192
2221
  {
2193
2222
  event.preventDefault();
2194
- const groupId = handleElement.getAttribute("data-panel-group-id");
2223
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2195
2224
  assert(groupId, `No group element found for id "${groupId}"`);
2196
2225
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2197
2226
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
@@ -2286,54 +2315,54 @@ function PanelResizeHandle({
2286
2315
  assert(element, "Element ref not attached");
2287
2316
  let didMove = false;
2288
2317
  const setResizeHandlerState = (action, isActive, event) => {
2289
- if (isActive) {
2290
- switch (action) {
2291
- case "down":
2292
- {
2293
- setState("drag");
2294
- didMove = false;
2295
- assert(event, 'Expected event to be defined for "down" action');
2296
- startDragging(resizeHandleId, event);
2297
- const {
2298
- onDragging,
2299
- onPointerDown
2300
- } = callbacksRef.current;
2301
- onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2302
- onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2303
- break;
2304
- }
2305
- case "move":
2306
- {
2307
- const {
2308
- state
2309
- } = committedValuesRef.current;
2310
- didMove = true;
2311
- if (state !== "drag") {
2312
- setState("hover");
2313
- }
2314
- assert(event, 'Expected event to be defined for "move" action');
2315
- resizeHandler(event);
2316
- break;
2317
- }
2318
- case "up":
2319
- {
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") {
2320
2344
  setState("hover");
2321
- stopDragging();
2322
- const {
2323
- onClick,
2324
- onDragging,
2325
- onPointerUp
2326
- } = callbacksRef.current;
2327
- onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2328
- onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2329
- if (!didMove) {
2330
- onClick === null || onClick === void 0 ? void 0 : onClick();
2331
- }
2332
- break;
2333
2345
  }
2334
- }
2335
- } else {
2336
- 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
+ }
2337
2366
  }
2338
2367
  };
2339
2368
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2372,13 +2401,13 @@ function PanelResizeHandle({
2372
2401
  },
2373
2402
  tabIndex,
2374
2403
  // CSS selectors
2375
- "data-panel-group-direction": direction,
2376
- "data-panel-group-id": groupId,
2377
- "data-resize-handle": "",
2378
- "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2379
- "data-resize-handle-state": state,
2380
- "data-panel-resize-handle-enabled": !disabled,
2381
- "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
2382
2411
  });
2383
2412
  }
2384
2413
  PanelResizeHandle.displayName = "PanelResizeHandle";
@@ -2412,4 +2441,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2412
2441
  };
2413
2442
  }
2414
2443
 
2415
- 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 };