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,32 +1,28 @@
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)];
2
+ import { createContext, useRef, forwardRef, createElement, useContext, useImperativeHandle, useState, useCallback, useEffect, useMemo } from 'react';
24
3
 
25
4
  // The "contextmenu" event is not supported as a PointerEvent in all browsers yet, so MouseEvent still need to be handled
26
5
 
27
6
  const PanelGroupContext = createContext(null);
28
7
  PanelGroupContext.displayName = "PanelGroupContext";
29
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
+
25
+ const useId = React["useId".toString()];
30
26
  const wrappedUseId = typeof useId === "function" ? useId : () => null;
31
27
  let counter = 0;
32
28
  function useUniqueId(idFromParams = null) {
@@ -132,17 +128,17 @@ function PanelWithForwardedRef({
132
128
  ...rest,
133
129
  children,
134
130
  className: classNameFromProps,
135
- id: idFromProps,
131
+ id: panelId,
136
132
  style: {
137
133
  ...style,
138
134
  ...styleFromProps
139
135
  },
140
136
  // CSS selectors
141
- "data-panel": "",
142
- "data-panel-collapsible": collapsible || undefined,
143
- "data-panel-group-id": groupId,
144
- "data-panel-id": panelId,
145
- "data-panel-size": parseFloat("" + style.flexGrow).toFixed(1)
137
+ [DATA_ATTRIBUTES.groupId]: groupId,
138
+ [DATA_ATTRIBUTES.panel]: "",
139
+ [DATA_ATTRIBUTES.panelCollapsible]: collapsible || undefined,
140
+ [DATA_ATTRIBUTES.panelId]: panelId,
141
+ [DATA_ATTRIBUTES.panelSize]: parseFloat("" + style.flexGrow).toFixed(1)
146
142
  });
147
143
  }
148
144
  const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
@@ -162,6 +158,7 @@ function setNonce(value) {
162
158
 
163
159
  let currentCursorStyle = null;
164
160
  let enabled = true;
161
+ let prevRuleIndex = -1;
165
162
  let styleElement = null;
166
163
  function disableGlobalCursorStyles() {
167
164
  enabled = false;
@@ -211,9 +208,11 @@ function resetGlobalCursorStyle() {
211
208
  document.head.removeChild(styleElement);
212
209
  currentCursorStyle = null;
213
210
  styleElement = null;
211
+ prevRuleIndex = -1;
214
212
  }
215
213
  }
216
214
  function setGlobalCursorStyle(state, constraintFlags) {
215
+ var _styleElement$sheet$i, _styleElement$sheet2;
217
216
  if (!enabled) {
218
217
  return;
219
218
  }
@@ -230,7 +229,11 @@ function setGlobalCursorStyle(state, constraintFlags) {
230
229
  }
231
230
  document.head.appendChild(styleElement);
232
231
  }
233
- styleElement.innerHTML = `*{cursor: ${style}!important;}`;
232
+ if (prevRuleIndex >= 0) {
233
+ var _styleElement$sheet;
234
+ (_styleElement$sheet = styleElement.sheet) === null || _styleElement$sheet === void 0 ? void 0 : _styleElement$sheet.removeRule(prevRuleIndex);
235
+ }
236
+ 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;
234
237
  }
235
238
 
236
239
  function isKeyDown(event) {
@@ -461,7 +464,9 @@ function handlePointerDown(event) {
461
464
  if (intersectingHandles.length > 0) {
462
465
  updateResizeHandlerStates("down", event);
463
466
  event.preventDefault();
464
- event.stopPropagation();
467
+ if (!isWithinResizeHandle(target)) {
468
+ event.stopImmediatePropagation();
469
+ }
465
470
  }
466
471
  }
467
472
  function handlePointerMove(event) {
@@ -510,6 +515,9 @@ function handlePointerUp(event) {
510
515
  isPointerDown = false;
511
516
  if (intersectingHandles.length > 0) {
512
517
  event.preventDefault();
518
+ if (!isWithinResizeHandle(target)) {
519
+ event.stopImmediatePropagation();
520
+ }
513
521
  }
514
522
  updateResizeHandlerStates("up", event);
515
523
  recalculateIntersectingHandles({
@@ -520,6 +528,16 @@ function handlePointerUp(event) {
520
528
  updateCursor();
521
529
  updateListeners();
522
530
  }
531
+ function isWithinResizeHandle(element) {
532
+ let currentElement = element;
533
+ while (currentElement) {
534
+ if (currentElement.hasAttribute(DATA_ATTRIBUTES.resizeHandle)) {
535
+ return true;
536
+ }
537
+ currentElement = currentElement.parentElement;
538
+ }
539
+ return false;
540
+ }
523
541
  function recalculateIntersectingHandles({
524
542
  target,
525
543
  x,
@@ -611,47 +629,42 @@ function updateCursor() {
611
629
  resetGlobalCursorStyle();
612
630
  }
613
631
  }
632
+ let listenersAbortController = new AbortController();
614
633
  function updateListeners() {
615
- ownerDocumentCounts.forEach((_, ownerDocument) => {
616
- const {
617
- body
618
- } = ownerDocument;
619
- body.removeEventListener("contextmenu", handlePointerUp);
620
- body.removeEventListener("pointerdown", handlePointerDown);
621
- body.removeEventListener("pointerleave", handlePointerMove);
622
- body.removeEventListener("pointermove", handlePointerMove);
623
- });
624
- window.removeEventListener("pointerup", handlePointerUp);
625
- window.removeEventListener("pointercancel", handlePointerUp);
626
- if (registeredResizeHandlers.size > 0) {
627
- if (isPointerDown) {
628
- if (intersectingHandles.length > 0) {
629
- ownerDocumentCounts.forEach((count, ownerDocument) => {
630
- const {
631
- body
632
- } = ownerDocument;
633
- if (count > 0) {
634
- body.addEventListener("contextmenu", handlePointerUp);
635
- body.addEventListener("pointerleave", handlePointerMove);
636
- body.addEventListener("pointermove", handlePointerMove);
637
- }
638
- });
639
- }
640
- window.addEventListener("pointerup", handlePointerUp);
641
- window.addEventListener("pointercancel", handlePointerUp);
642
- } else {
634
+ listenersAbortController.abort();
635
+ listenersAbortController = new AbortController();
636
+ const options = {
637
+ capture: true,
638
+ signal: listenersAbortController.signal
639
+ };
640
+ if (!registeredResizeHandlers.size) {
641
+ return;
642
+ }
643
+ if (isPointerDown) {
644
+ if (intersectingHandles.length > 0) {
643
645
  ownerDocumentCounts.forEach((count, ownerDocument) => {
644
646
  const {
645
647
  body
646
648
  } = ownerDocument;
647
649
  if (count > 0) {
648
- body.addEventListener("pointerdown", handlePointerDown, {
649
- capture: true
650
- });
651
- body.addEventListener("pointermove", handlePointerMove);
650
+ body.addEventListener("contextmenu", handlePointerUp, options);
651
+ body.addEventListener("pointerleave", handlePointerMove, options);
652
+ body.addEventListener("pointermove", handlePointerMove, options);
652
653
  }
653
654
  });
654
655
  }
656
+ window.addEventListener("pointerup", handlePointerUp, options);
657
+ window.addEventListener("pointercancel", handlePointerUp, options);
658
+ } else {
659
+ ownerDocumentCounts.forEach((count, ownerDocument) => {
660
+ const {
661
+ body
662
+ } = ownerDocument;
663
+ if (count > 0) {
664
+ body.addEventListener("pointerdown", handlePointerDown, options);
665
+ body.addEventListener("pointermove", handlePointerMove, options);
666
+ }
667
+ });
655
668
  }
656
669
  }
657
670
  function updateResizeHandlerStates(action, event) {
@@ -676,8 +689,6 @@ function assert(expectedCondition, message) {
676
689
  }
677
690
  }
678
691
 
679
- const PRECISION = 10;
680
-
681
692
  function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
682
693
  if (actual.toFixed(fractionDigits) === expected.toFixed(fractionDigits)) {
683
694
  return 0;
@@ -982,12 +993,12 @@ function adjustLayoutByDelta({
982
993
  }
983
994
 
984
995
  function getResizeHandleElementsForGroup(groupId, scope = document) {
985
- return Array.from(scope.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
996
+ return Array.from(scope.querySelectorAll(`[${DATA_ATTRIBUTES.resizeHandleId}][data-panel-group-id="${groupId}"]`));
986
997
  }
987
998
 
988
999
  function getResizeHandleElementIndex(groupId, id, scope = document) {
989
1000
  const handles = getResizeHandleElementsForGroup(groupId, scope);
990
- const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
1001
+ const index = handles.findIndex(handle => handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId) === id);
991
1002
  return index !== null && index !== void 0 ? index : null;
992
1003
  }
993
1004
 
@@ -1012,7 +1023,7 @@ function getPanelGroupElement(id, rootElement = document) {
1012
1023
  }
1013
1024
 
1014
1025
  function getResizeHandleElement(id, scope = document) {
1015
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
1026
+ const element = scope.querySelector(`[${DATA_ATTRIBUTES.resizeHandleId}="${id}"]`);
1016
1027
  if (element) {
1017
1028
  return element;
1018
1029
  }
@@ -1057,7 +1068,7 @@ function useWindowSplitterPanelGroupBehavior({
1057
1068
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1058
1069
  assert(handles, `No resize handles found for group id "${groupId}"`);
1059
1070
  const cleanupFunctions = handles.map(handle => {
1060
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1071
+ const handleId = handle.getAttribute(DATA_ATTRIBUTES.resizeHandleId);
1061
1072
  assert(handleId, `Resize handle element has no handle id attribute`);
1062
1073
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
1063
1074
  if (idBefore == null || idAfter == null) {
@@ -1135,7 +1146,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
1135
1146
  const isHorizontal = direction === "horizontal";
1136
1147
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
1137
1148
  assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
1138
- const groupId = handleElement.getAttribute("data-panel-group-id");
1149
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
1139
1150
  assert(groupId, `Resize handle element has no group id attribute`);
1140
1151
  let {
1141
1152
  initialCursorPosition
@@ -2030,9 +2041,9 @@ function PanelGroupWithForwardedRef({
2030
2041
  ...styleFromProps
2031
2042
  },
2032
2043
  // CSS selectors
2033
- "data-panel-group": "",
2034
- "data-panel-group-direction": direction,
2035
- "data-panel-group-id": groupId
2044
+ [DATA_ATTRIBUTES.group]: "",
2045
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2046
+ [DATA_ATTRIBUTES.groupId]: groupId
2036
2047
  }));
2037
2048
  }
2038
2049
  const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
@@ -2091,7 +2102,7 @@ function useWindowSplitterResizeHandlerBehavior({
2091
2102
  case "F6":
2092
2103
  {
2093
2104
  event.preventDefault();
2094
- const groupId = handleElement.getAttribute("data-panel-group-id");
2105
+ const groupId = handleElement.getAttribute(DATA_ATTRIBUTES.groupId);
2095
2106
  assert(groupId, `No group element found for id "${groupId}"`);
2096
2107
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
2097
2108
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
@@ -2117,8 +2128,11 @@ function PanelResizeHandle({
2117
2128
  hitAreaMargins,
2118
2129
  id: idFromProps,
2119
2130
  onBlur,
2131
+ onClick,
2120
2132
  onDragging,
2121
2133
  onFocus,
2134
+ onPointerDown,
2135
+ onPointerUp,
2122
2136
  style: styleFromProps = {},
2123
2137
  tabIndex = 0,
2124
2138
  tagName: Type = "div",
@@ -2129,10 +2143,16 @@ function PanelResizeHandle({
2129
2143
 
2130
2144
  // Use a ref to guard against users passing inline props
2131
2145
  const callbacksRef = useRef({
2132
- onDragging
2146
+ onClick,
2147
+ onDragging,
2148
+ onPointerDown,
2149
+ onPointerUp
2133
2150
  });
2134
2151
  useEffect(() => {
2152
+ callbacksRef.current.onClick = onClick;
2135
2153
  callbacksRef.current.onDragging = onDragging;
2154
+ callbacksRef.current.onPointerDown = onPointerDown;
2155
+ callbacksRef.current.onPointerUp = onPointerUp;
2136
2156
  });
2137
2157
  const panelGroupContext = useContext(PanelGroupContext);
2138
2158
  if (panelGroupContext === null) {
@@ -2172,49 +2192,56 @@ function PanelResizeHandle({
2172
2192
  }
2173
2193
  const element = elementRef.current;
2174
2194
  assert(element, "Element ref not attached");
2195
+ let didMove = false;
2175
2196
  const setResizeHandlerState = (action, isActive, event) => {
2176
- if (isActive) {
2177
- switch (action) {
2178
- case "down":
2179
- {
2180
- setState("drag");
2181
- assert(event, 'Expected event to be defined for "down" action');
2182
- startDragging(resizeHandleId, event);
2183
- const {
2184
- onDragging
2185
- } = callbacksRef.current;
2186
- if (onDragging) {
2187
- onDragging(true);
2188
- }
2189
- break;
2190
- }
2191
- case "move":
2192
- {
2193
- const {
2194
- state
2195
- } = committedValuesRef.current;
2196
- if (state !== "drag") {
2197
- setState("hover");
2198
- }
2199
- assert(event, 'Expected event to be defined for "move" action');
2200
- resizeHandler(event);
2201
- break;
2202
- }
2203
- case "up":
2204
- {
2197
+ if (!isActive) {
2198
+ setState("inactive");
2199
+ return;
2200
+ }
2201
+ switch (action) {
2202
+ case "down":
2203
+ {
2204
+ setState("drag");
2205
+ didMove = false;
2206
+ assert(event, 'Expected event to be defined for "down" action');
2207
+ startDragging(resizeHandleId, event);
2208
+ const {
2209
+ onDragging,
2210
+ onPointerDown
2211
+ } = callbacksRef.current;
2212
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(true);
2213
+ onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown();
2214
+ break;
2215
+ }
2216
+ case "move":
2217
+ {
2218
+ const {
2219
+ state
2220
+ } = committedValuesRef.current;
2221
+ didMove = true;
2222
+ if (state !== "drag") {
2205
2223
  setState("hover");
2206
- stopDragging();
2207
- const {
2208
- onDragging
2209
- } = callbacksRef.current;
2210
- if (onDragging) {
2211
- onDragging(false);
2212
- }
2213
- break;
2214
2224
  }
2215
- }
2216
- } else {
2217
- setState("inactive");
2225
+ assert(event, 'Expected event to be defined for "move" action');
2226
+ resizeHandler(event);
2227
+ break;
2228
+ }
2229
+ case "up":
2230
+ {
2231
+ setState("hover");
2232
+ stopDragging();
2233
+ const {
2234
+ onClick,
2235
+ onDragging,
2236
+ onPointerUp
2237
+ } = callbacksRef.current;
2238
+ onDragging === null || onDragging === void 0 ? void 0 : onDragging(false);
2239
+ onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp();
2240
+ if (!didMove) {
2241
+ onClick === null || onClick === void 0 ? void 0 : onClick();
2242
+ }
2243
+ break;
2244
+ }
2218
2245
  }
2219
2246
  };
2220
2247
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -2253,13 +2280,13 @@ function PanelResizeHandle({
2253
2280
  },
2254
2281
  tabIndex,
2255
2282
  // CSS selectors
2256
- "data-panel-group-direction": direction,
2257
- "data-panel-group-id": groupId,
2258
- "data-resize-handle": "",
2259
- "data-resize-handle-active": state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2260
- "data-resize-handle-state": state,
2261
- "data-panel-resize-handle-enabled": !disabled,
2262
- "data-panel-resize-handle-id": resizeHandleId
2283
+ [DATA_ATTRIBUTES.groupDirection]: direction,
2284
+ [DATA_ATTRIBUTES.groupId]: groupId,
2285
+ [DATA_ATTRIBUTES.resizeHandle]: "",
2286
+ [DATA_ATTRIBUTES.resizeHandleActive]: state === "drag" ? "pointer" : isFocused ? "keyboard" : undefined,
2287
+ [DATA_ATTRIBUTES.resizeHandleEnabled]: !disabled,
2288
+ [DATA_ATTRIBUTES.resizeHandleId]: resizeHandleId,
2289
+ [DATA_ATTRIBUTES.resizeHandleState]: state
2263
2290
  });
2264
2291
  }
2265
2292
  PanelResizeHandle.displayName = "PanelResizeHandle";
@@ -2293,4 +2320,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2293
2320
  };
2294
2321
  }
2295
2322
 
2296
- export { Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };
2323
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce };