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()];
@@ -148,11 +164,11 @@ function PanelWithForwardedRef({
148
164
  ...styleFromProps
149
165
  },
150
166
  // CSS selectors
151
- "data-panel": "",
152
- "data-panel-collapsible": collapsible || undefined,
153
- "data-panel-group-id": groupId,
154
- "data-panel-id": panelId,
155
- "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)
156
172
  });
157
173
  }
158
174
  const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
@@ -172,6 +188,7 @@ function setNonce(value) {
172
188
 
173
189
  let currentCursorStyle = null;
174
190
  let enabled = true;
191
+ let prevRuleIndex = -1;
175
192
  let styleElement = null;
176
193
  function disableGlobalCursorStyles() {
177
194
  enabled = false;
@@ -221,9 +238,11 @@ function resetGlobalCursorStyle() {
221
238
  document.head.removeChild(styleElement);
222
239
  currentCursorStyle = null;
223
240
  styleElement = null;
241
+ prevRuleIndex = -1;
224
242
  }
225
243
  }
226
244
  function setGlobalCursorStyle(state, constraintFlags) {
245
+ var _styleElement$sheet$i, _styleElement$sheet2;
227
246
  if (!enabled) {
228
247
  return;
229
248
  }
@@ -240,7 +259,11 @@ function setGlobalCursorStyle(state, constraintFlags) {
240
259
  }
241
260
  document.head.appendChild(styleElement);
242
261
  }
243
- 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;
244
267
  }
245
268
 
246
269
  function isKeyDown(event) {
@@ -471,7 +494,9 @@ function handlePointerDown(event) {
471
494
  if (intersectingHandles.length > 0) {
472
495
  updateResizeHandlerStates("down", event);
473
496
  event.preventDefault();
474
- event.stopPropagation();
497
+ if (!isWithinResizeHandle(target)) {
498
+ event.stopImmediatePropagation();
499
+ }
475
500
  }
476
501
  }
477
502
  function handlePointerMove(event) {
@@ -520,6 +545,9 @@ function handlePointerUp(event) {
520
545
  isPointerDown = false;
521
546
  if (intersectingHandles.length > 0) {
522
547
  event.preventDefault();
548
+ if (!isWithinResizeHandle(target)) {
549
+ event.stopImmediatePropagation();
550
+ }
523
551
  }
524
552
  updateResizeHandlerStates("up", event);
525
553
  recalculateIntersectingHandles({
@@ -530,6 +558,16 @@ function handlePointerUp(event) {
530
558
  updateCursor();
531
559
  updateListeners();
532
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
+ }
533
571
  function recalculateIntersectingHandles({
534
572
  target,
535
573
  x,
@@ -621,49 +659,42 @@ function updateCursor() {
621
659
  resetGlobalCursorStyle();
622
660
  }
623
661
  }
662
+ let listenersAbortController = new AbortController();
624
663
  function updateListeners() {
625
- ownerDocumentCounts.forEach((_, ownerDocument) => {
626
- const {
627
- body
628
- } = ownerDocument;
629
- body.removeEventListener("contextmenu", handlePointerUp);
630
- body.removeEventListener("pointerdown", handlePointerDown, {
631
- capture: true
632
- });
633
- body.removeEventListener("pointerleave", handlePointerMove);
634
- body.removeEventListener("pointermove", handlePointerMove);
635
- });
636
- window.removeEventListener("pointerup", handlePointerUp);
637
- window.removeEventListener("pointercancel", handlePointerUp);
638
- if (registeredResizeHandlers.size > 0) {
639
- if (isPointerDown) {
640
- if (intersectingHandles.length > 0) {
641
- ownerDocumentCounts.forEach((count, ownerDocument) => {
642
- const {
643
- body
644
- } = ownerDocument;
645
- if (count > 0) {
646
- body.addEventListener("contextmenu", handlePointerUp);
647
- body.addEventListener("pointerleave", handlePointerMove);
648
- body.addEventListener("pointermove", handlePointerMove);
649
- }
650
- });
651
- }
652
- window.addEventListener("pointerup", handlePointerUp);
653
- window.addEventListener("pointercancel", handlePointerUp);
654
- } 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) {
655
675
  ownerDocumentCounts.forEach((count, ownerDocument) => {
656
676
  const {
657
677
  body
658
678
  } = ownerDocument;
659
679
  if (count > 0) {
660
- body.addEventListener("pointerdown", handlePointerDown, {
661
- capture: true
662
- });
663
- body.addEventListener("pointermove", handlePointerMove);
680
+ body.addEventListener("contextmenu", handlePointerUp, options);
681
+ body.addEventListener("pointerleave", handlePointerMove, options);
682
+ body.addEventListener("pointermove", handlePointerMove, options);
664
683
  }
665
684
  });
666
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
+ });
667
698
  }
668
699
  }
669
700
  function updateResizeHandlerStates(action, event) {
@@ -688,8 +719,6 @@ function assert(expectedCondition, message) {
688
719
  }
689
720
  }
690
721
 
691
- const PRECISION = 10;
692
-
693
722
  function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
694
723
  if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
695
724
  return 0;
@@ -1033,12 +1062,12 @@ function calculateAriaValues({
1033
1062
  }
1034
1063
 
1035
1064
  function getResizeHandleElementsForGroup(groupId, scope = document) {
1036
- 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}"]`));
1037
1066
  }
1038
1067
 
1039
1068
  function getResizeHandleElementIndex(groupId, id, scope = document) {
1040
1069
  const handles = getResizeHandleElementsForGroup(groupId, scope);
1041
- 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);
1042
1071
  return index !== null && index !== void 0 ? index : null;
1043
1072
  }
1044
1073
 
@@ -1063,7 +1092,7 @@ function getPanelGroupElement(id, rootElement = document) {
1063
1092
  }
1064
1093
 
1065
1094
  function getResizeHandleElement(id, scope = document) {
1066
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
1095
+ const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1067
1096
  if (element) {
1068
1097
  return element;
1069
1098
  }
@@ -1152,7 +1181,7 @@ function useWindowSplitterPanelGroupBehavior({
1152
1181
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1153
1182
  assert(handles, `No resize handles found for group id "${groupId}"`);
1154
1183
  const cleanupFunctions = handles.map(handle => {
1155
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1184
+ const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1156
1185
  assert(handleId, `Resize handle element has no handle id attribute`);
1157
1186
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1158
1187
  if (idBefore == null || idAfter == null) {
@@ -1230,7 +1259,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
1230
1259
  const isHorizontal = direction === "horizontal";
1231
1260
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1232
1261
  assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1233
- const groupId = handleElement.getAttribute("data-panel-group-id");
1262
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1234
1263
  assert(groupId, `Resize handle element has no group id attribute`);
1235
1264
  let {
1236
1265
  initialCursorPosition
@@ -2236,9 +2265,9 @@ function PanelGroupWithForwardedRef({
2236
2265
  ...styleFromProps
2237
2266
  },
2238
2267
  // CSS selectors
2239
- "data-panel-group": "",
2240
- "data-panel-group-direction": direction,
2241
- "data-panel-group-id": groupId
2268
+ [DATA_ATTRIBUTES.group]: "",
2269
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2270
+ [DATA_ATTRIBUTES.groupId]: groupId
2242
2271
  }));
2243
2272
  }
2244
2273
  const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
@@ -2297,7 +2326,7 @@ function useWindowSplitterResizeHandlerBehavior({
2297
2326
  case "F6":
2298
2327
  {
2299
2328
  event.preventDefault();
2300
- const groupId = handleElement.getAttribute("data-panel-group-id");
2329
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2301
2330
  assert(groupId, `No group element found for id "${groupId}"`);
2302
2331
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2303
2332
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
@@ -2392,54 +2421,54 @@ function PanelResizeHandle({
2392
2421
  assert(element, "Element ref not attached");
2393
2422
  let didMove = false;
2394
2423
  const setResizeHandlerState = (action, isActive, event) => {
2395
- if (isActive) {
2396
- switch (action) {
2397
- case "down":
2398
- {
2399
- setState("drag");
2400
- didMove = false;
2401
- assert(event, 'Expected event to be defined for "down" action');
2402
- startDragging(resizeHandleId, event);
2403
- const {
2404
- onDragging,
2405
- onPointerDown
2406
- } = callbacksRef.current;
2407
- onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2408
- onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2409
- break;
2410
- }
2411
- case "move":
2412
- {
2413
- const {
2414
- state
2415
- } = committedValuesRef.current;
2416
- didMove = true;
2417
- if (state !== "drag") {
2418
- setState("hover");
2419
- }
2420
- assert(event, 'Expected event to be defined for "move" action');
2421
- resizeHandler(event);
2422
- break;
2423
- }
2424
- case "up":
2425
- {
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") {
2426
2450
  setState("hover");
2427
- stopDragging();
2428
- const {
2429
- onClick,
2430
- onDragging,
2431
- onPointerUp
2432
- } = callbacksRef.current;
2433
- onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2434
- onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2435
- if (!didMove) {
2436
- onClick === null || onClick === void 0 ? void 0 : onClick();
2437
- }
2438
- break;
2439
2451
  }
2440
- }
2441
- } else {
2442
- 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
+ }
2443
2472
  }
2444
2473
  };
2445
2474
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2478,13 +2507,13 @@ function PanelResizeHandle({
2478
2507
  },
2479
2508
  tabIndex,
2480
2509
  // CSS selectors
2481
- "data-panel-group-direction": direction,
2482
- "data-panel-group-id": groupId,
2483
- "data-resize-handle": "",
2484
- "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2485
- "data-resize-handle-state": state,
2486
- "data-panel-resize-handle-enabled": !disabled,
2487
- "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
2488
2517
  });
2489
2518
  }
2490
2519
  PanelResizeHandle.displayName = "PanelResizeHandle";
@@ -2518,4 +2547,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2518
2547
  };
2519
2548
  }
2520
2549
 
2521
- 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 };