react-resizable-panels 3.0.3 → 3.0.5

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.
package/README.md CHANGED
@@ -80,7 +80,6 @@ import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
80
80
  | `getSize(): number` | Gets the current size of the panel as a percentage (`1 - 100`). |
81
81
  | `isCollapsed(): boolean` | Returns `true` if the panel is currently _collapsed_ (`size === 0`). |
82
82
  | `isExpanded(): boolean` | Returns `true` if the panel is currently _not collapsed_ (`!isCollapsed()`). |
83
- | `getSize(): number` | Returns the most recently committed size of the panel as a percentage (`1 - 100`). |
84
83
  | `resize(size: number)` | Resize panel to the specified _percentage_ (`1 - 100`). |
85
84
 
86
85
  ### `PanelResizeHandle`
@@ -124,7 +123,7 @@ The `Panel` API doesn't _require_ `id` and `order` props because they aren't nec
124
123
  </PanelGroup>
125
124
  ```
126
125
 
127
- ### Can a attach a ref to the DOM elements?
126
+ ### Can I attach a ref to the DOM elements?
128
127
 
129
128
  No. I think exposing two refs (one for the component's imperative API and one for a DOM element) would be awkward. This library does export several utility methods for accessing the underlying DOM elements though. For example:
130
129
 
@@ -247,3 +246,15 @@ import { disableGlobalCursorStyles } from "react-resizable-panels";
247
246
 
248
247
  disableGlobalCursorStyles();
249
248
  ```
249
+
250
+ #### How can I override the global cursor styles?
251
+
252
+ ```js
253
+ import { customizeGlobalCursorStyles, type CustomCursorStyleConfig } from "react-resizable-panels";
254
+
255
+ function customCursor({ isPointerDown }: CustomCursorStyleConfig) {
256
+ return isPointerDown ? "grabbing" : "grab";
257
+ }
258
+
259
+ customizeGlobalCursorStyles(customCursor);
260
+ ```
@@ -5,7 +5,7 @@ import { DATA_ATTRIBUTES } from "./constants.js";
5
5
  import { usePanelGroupContext } from "./hooks/usePanelGroupContext.js";
6
6
  import { assert } from "./utils/assert.js";
7
7
  import { setNonce } from "./utils/csp.js";
8
- import { disableGlobalCursorStyles, enableGlobalCursorStyles } from "./utils/cursor.js";
8
+ import { customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles } from "./utils/cursor.js";
9
9
  import { getPanelElement } from "./utils/dom/getPanelElement.js";
10
10
  import { getPanelElementsForGroup } from "./utils/dom/getPanelElementsForGroup.js";
11
11
  import { getPanelGroupElement } from "./utils/dom/getPanelGroupElement.js";
@@ -19,4 +19,5 @@ import type { ImperativePanelHandle, PanelOnCollapse, PanelOnExpand, PanelOnResi
19
19
  import type { ImperativePanelGroupHandle, PanelGroupOnLayout, PanelGroupProps, PanelGroupStorage } from "./PanelGroup.js";
20
20
  import type { PanelResizeHandleOnDragging, PanelResizeHandleProps } from "./PanelResizeHandle.js";
21
21
  import type { PointerHitAreaMargins } from "./PanelResizeHandleRegistry.js";
22
- export { ImperativePanelGroupHandle, ImperativePanelHandle, PanelGroupOnLayout, PanelGroupProps, PanelGroupStorage, PanelOnCollapse, PanelOnExpand, PanelOnResize, PanelProps, PanelResizeHandleOnDragging, PanelResizeHandleProps, PointerHitAreaMargins, Panel, PanelGroup, PanelResizeHandle, usePanelGroupContext, assert, getIntersectingRectangle, intersects, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, enableGlobalCursorStyles, disableGlobalCursorStyles, setNonce, DATA_ATTRIBUTES, };
22
+ import type { CustomCursorStyleConfig } from "./utils/cursor.js";
23
+ export { ImperativePanelGroupHandle, ImperativePanelHandle, PanelGroupOnLayout, PanelGroupProps, PanelGroupStorage, PanelOnCollapse, PanelOnExpand, PanelOnResize, PanelProps, PanelResizeHandleOnDragging, PanelResizeHandleProps, PointerHitAreaMargins, Panel, PanelGroup, PanelResizeHandle, usePanelGroupContext, assert, getIntersectingRectangle, intersects, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, setNonce, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, CustomCursorStyleConfig, DATA_ATTRIBUTES, };
@@ -1,7 +1,18 @@
1
1
  type CursorState = "horizontal" | "intersection" | "vertical";
2
+ export type CustomCursorStyleConfig = {
3
+ exceedsHorizontalMaximum: boolean;
4
+ exceedsHorizontalMinimum: boolean;
5
+ exceedsVerticalMaximum: boolean;
6
+ exceedsVerticalMinimum: boolean;
7
+ intersectsHorizontalDragHandle: boolean;
8
+ intersectsVerticalDragHandle: boolean;
9
+ isPointerDown: boolean;
10
+ };
11
+ type GetCustomCursorStyleFunction = (config: CustomCursorStyleConfig) => string;
12
+ export declare function customizeGlobalCursorStyles(callback: GetCustomCursorStyleFunction | null): void;
2
13
  export declare function disableGlobalCursorStyles(): void;
3
14
  export declare function enableGlobalCursorStyles(): void;
4
- export declare function getCursorStyle(state: CursorState, constraintFlags: number): string;
15
+ export declare function getCursorStyle(state: CursorState, constraintFlags: number, isPointerDown: boolean): string;
5
16
  export declare function resetGlobalCursorStyle(): void;
6
- export declare function setGlobalCursorStyle(state: CursorState, constraintFlags: number): void;
17
+ export declare function setGlobalCursorStyle(state: CursorState, constraintFlags: number, isPointerDown: boolean): void;
7
18
  export {};
@@ -188,20 +188,35 @@ function setNonce(value) {
188
188
 
189
189
  let currentCursorStyle = null;
190
190
  let enabled = true;
191
+ let getCustomCursorStyleFunction = null;
191
192
  let prevRuleIndex = -1;
192
193
  let styleElement = null;
194
+ function customizeGlobalCursorStyles(callback) {
195
+ getCustomCursorStyleFunction = callback;
196
+ }
193
197
  function disableGlobalCursorStyles() {
194
198
  enabled = false;
195
199
  }
196
200
  function enableGlobalCursorStyles() {
197
201
  enabled = true;
198
202
  }
199
- function getCursorStyle(state, constraintFlags) {
203
+ function getCursorStyle(state, constraintFlags, isPointerDown) {
204
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
205
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
206
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
207
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
208
+ if (getCustomCursorStyleFunction) {
209
+ return getCustomCursorStyleFunction({
210
+ exceedsHorizontalMaximum: horizontalMax,
211
+ exceedsHorizontalMinimum: horizontalMin,
212
+ exceedsVerticalMaximum: verticalMax,
213
+ exceedsVerticalMinimum: verticalMin,
214
+ intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
215
+ intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
216
+ isPointerDown
217
+ });
218
+ }
200
219
  if (constraintFlags) {
201
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
202
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
203
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
204
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
205
220
  if (horizontalMin) {
206
221
  if (verticalMin) {
207
222
  return "se-resize";
@@ -241,12 +256,12 @@ function resetGlobalCursorStyle() {
241
256
  prevRuleIndex = -1;
242
257
  }
243
258
  }
244
- function setGlobalCursorStyle(state, constraintFlags) {
259
+ function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
245
260
  var _styleElement$sheet$i, _styleElement$sheet2;
246
261
  if (!enabled) {
247
262
  return;
248
263
  }
249
- const style = getCursorStyle(state, constraintFlags);
264
+ const style = getCursorStyle(state, constraintFlags, isPointerDown);
250
265
  if (currentCursorStyle === style) {
251
266
  return;
252
267
  }
@@ -493,6 +508,9 @@ function handlePointerDown(event) {
493
508
  updateListeners();
494
509
  if (intersectingHandles.length > 0) {
495
510
  updateResizeHandlerStates("down", event);
511
+
512
+ // Update cursor based on return value(s) from active handles
513
+ updateCursor();
496
514
  event.preventDefault();
497
515
  if (!isWithinResizeHandle(target)) {
498
516
  event.stopImmediatePropagation();
@@ -650,11 +668,11 @@ function updateCursor() {
650
668
  constraintFlags |= flag;
651
669
  });
652
670
  if (intersectsHorizontal && intersectsVertical) {
653
- setGlobalCursorStyle("intersection", constraintFlags);
671
+ setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
654
672
  } else if (intersectsHorizontal) {
655
- setGlobalCursorStyle("horizontal", constraintFlags);
673
+ setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
656
674
  } else if (intersectsVertical) {
657
- setGlobalCursorStyle("vertical", constraintFlags);
675
+ setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
658
676
  } else {
659
677
  resetGlobalCursorStyle();
660
678
  }
@@ -939,7 +957,7 @@ function adjustLayoutByDelta({
939
957
  if (!fuzzyNumbersEqual(prevSize, safeSize)) {
940
958
  deltaApplied += prevSize - safeSize;
941
959
  nextLayout[index] = safeSize;
942
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
960
+ if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
943
961
  numeric: true
944
962
  }) >= 0) {
945
963
  break;
@@ -1437,12 +1455,12 @@ function computePanelFlexBoxStyle({
1437
1455
  if (size == null) {
1438
1456
  // Initial render (before panels have registered themselves)
1439
1457
  // In order to support server rendering, fall back to default size if provided
1440
- flexGrow = defaultSize != undefined ? defaultSize.toPrecision(precision) : "1";
1458
+ flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1441
1459
  } else if (panelData.length === 1) {
1442
1460
  // Special case: Single panel group should always fill full width/height
1443
1461
  flexGrow = "1";
1444
1462
  } else {
1445
- flexGrow = size.toPrecision(precision);
1463
+ flexGrow = size.toFixed(precision);
1446
1464
  }
1447
1465
  return {
1448
1466
  flexBasis: 0,
@@ -2569,4 +2587,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2569
2587
  };
2570
2588
  }
2571
2589
 
2572
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
2590
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
@@ -182,20 +182,35 @@ function setNonce(value) {
182
182
 
183
183
  let currentCursorStyle = null;
184
184
  let enabled = true;
185
+ let getCustomCursorStyleFunction = null;
185
186
  let prevRuleIndex = -1;
186
187
  let styleElement = null;
188
+ function customizeGlobalCursorStyles(callback) {
189
+ getCustomCursorStyleFunction = callback;
190
+ }
187
191
  function disableGlobalCursorStyles() {
188
192
  enabled = false;
189
193
  }
190
194
  function enableGlobalCursorStyles() {
191
195
  enabled = true;
192
196
  }
193
- function getCursorStyle(state, constraintFlags) {
197
+ function getCursorStyle(state, constraintFlags, isPointerDown) {
198
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
199
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
200
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
201
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
202
+ if (getCustomCursorStyleFunction) {
203
+ return getCustomCursorStyleFunction({
204
+ exceedsHorizontalMaximum: horizontalMax,
205
+ exceedsHorizontalMinimum: horizontalMin,
206
+ exceedsVerticalMaximum: verticalMax,
207
+ exceedsVerticalMinimum: verticalMin,
208
+ intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
209
+ intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
210
+ isPointerDown
211
+ });
212
+ }
194
213
  if (constraintFlags) {
195
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
196
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
197
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
198
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
199
214
  if (horizontalMin) {
200
215
  if (verticalMin) {
201
216
  return "se-resize";
@@ -235,12 +250,12 @@ function resetGlobalCursorStyle() {
235
250
  prevRuleIndex = -1;
236
251
  }
237
252
  }
238
- function setGlobalCursorStyle(state, constraintFlags) {
253
+ function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
239
254
  var _styleElement$sheet$i, _styleElement$sheet2;
240
255
  if (!enabled) {
241
256
  return;
242
257
  }
243
- const style = getCursorStyle(state, constraintFlags);
258
+ const style = getCursorStyle(state, constraintFlags, isPointerDown);
244
259
  if (currentCursorStyle === style) {
245
260
  return;
246
261
  }
@@ -487,6 +502,9 @@ function handlePointerDown(event) {
487
502
  updateListeners();
488
503
  if (intersectingHandles.length > 0) {
489
504
  updateResizeHandlerStates("down", event);
505
+
506
+ // Update cursor based on return value(s) from active handles
507
+ updateCursor();
490
508
  event.preventDefault();
491
509
  if (!isWithinResizeHandle(target)) {
492
510
  event.stopImmediatePropagation();
@@ -644,11 +662,11 @@ function updateCursor() {
644
662
  constraintFlags |= flag;
645
663
  });
646
664
  if (intersectsHorizontal && intersectsVertical) {
647
- setGlobalCursorStyle("intersection", constraintFlags);
665
+ setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
648
666
  } else if (intersectsHorizontal) {
649
- setGlobalCursorStyle("horizontal", constraintFlags);
667
+ setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
650
668
  } else if (intersectsVertical) {
651
- setGlobalCursorStyle("vertical", constraintFlags);
669
+ setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
652
670
  } else {
653
671
  resetGlobalCursorStyle();
654
672
  }
@@ -933,7 +951,7 @@ function adjustLayoutByDelta({
933
951
  if (!fuzzyNumbersEqual(prevSize, safeSize)) {
934
952
  deltaApplied += prevSize - safeSize;
935
953
  nextLayout[index] = safeSize;
936
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
954
+ if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
937
955
  numeric: true
938
956
  }) >= 0) {
939
957
  break;
@@ -1421,12 +1439,12 @@ function computePanelFlexBoxStyle({
1421
1439
  if (size == null) {
1422
1440
  // Initial render (before panels have registered themselves)
1423
1441
  // In order to support server rendering, fall back to default size if provided
1424
- flexGrow = defaultSize != undefined ? defaultSize.toPrecision(precision) : "1";
1442
+ flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1425
1443
  } else if (panelData.length === 1) {
1426
1444
  // Special case: Single panel group should always fill full width/height
1427
1445
  flexGrow = "1";
1428
1446
  } else {
1429
- flexGrow = size.toPrecision(precision);
1447
+ flexGrow = size.toFixed(precision);
1430
1448
  }
1431
1449
  return {
1432
1450
  flexBasis: 0,
@@ -2463,4 +2481,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2463
2481
  };
2464
2482
  }
2465
2483
 
2466
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
2484
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
@@ -158,20 +158,35 @@ function setNonce(value) {
158
158
 
159
159
  let currentCursorStyle = null;
160
160
  let enabled = true;
161
+ let getCustomCursorStyleFunction = null;
161
162
  let prevRuleIndex = -1;
162
163
  let styleElement = null;
164
+ function customizeGlobalCursorStyles(callback) {
165
+ getCustomCursorStyleFunction = callback;
166
+ }
163
167
  function disableGlobalCursorStyles() {
164
168
  enabled = false;
165
169
  }
166
170
  function enableGlobalCursorStyles() {
167
171
  enabled = true;
168
172
  }
169
- function getCursorStyle(state, constraintFlags) {
173
+ function getCursorStyle(state, constraintFlags, isPointerDown) {
174
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
175
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
176
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
177
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
178
+ if (getCustomCursorStyleFunction) {
179
+ return getCustomCursorStyleFunction({
180
+ exceedsHorizontalMaximum: horizontalMax,
181
+ exceedsHorizontalMinimum: horizontalMin,
182
+ exceedsVerticalMaximum: verticalMax,
183
+ exceedsVerticalMinimum: verticalMin,
184
+ intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
185
+ intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
186
+ isPointerDown
187
+ });
188
+ }
170
189
  if (constraintFlags) {
171
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
172
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
173
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
174
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
175
190
  if (horizontalMin) {
176
191
  if (verticalMin) {
177
192
  return "se-resize";
@@ -211,12 +226,12 @@ function resetGlobalCursorStyle() {
211
226
  prevRuleIndex = -1;
212
227
  }
213
228
  }
214
- function setGlobalCursorStyle(state, constraintFlags) {
229
+ function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
215
230
  var _styleElement$sheet$i, _styleElement$sheet2;
216
231
  if (!enabled) {
217
232
  return;
218
233
  }
219
- const style = getCursorStyle(state, constraintFlags);
234
+ const style = getCursorStyle(state, constraintFlags, isPointerDown);
220
235
  if (currentCursorStyle === style) {
221
236
  return;
222
237
  }
@@ -463,6 +478,9 @@ function handlePointerDown(event) {
463
478
  updateListeners();
464
479
  if (intersectingHandles.length > 0) {
465
480
  updateResizeHandlerStates("down", event);
481
+
482
+ // Update cursor based on return value(s) from active handles
483
+ updateCursor();
466
484
  event.preventDefault();
467
485
  if (!isWithinResizeHandle(target)) {
468
486
  event.stopImmediatePropagation();
@@ -620,11 +638,11 @@ function updateCursor() {
620
638
  constraintFlags |= flag;
621
639
  });
622
640
  if (intersectsHorizontal && intersectsVertical) {
623
- setGlobalCursorStyle("intersection", constraintFlags);
641
+ setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
624
642
  } else if (intersectsHorizontal) {
625
- setGlobalCursorStyle("horizontal", constraintFlags);
643
+ setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
626
644
  } else if (intersectsVertical) {
627
- setGlobalCursorStyle("vertical", constraintFlags);
645
+ setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
628
646
  } else {
629
647
  resetGlobalCursorStyle();
630
648
  }
@@ -909,7 +927,7 @@ function adjustLayoutByDelta({
909
927
  if (!fuzzyNumbersEqual(prevSize, safeSize)) {
910
928
  deltaApplied += prevSize - safeSize;
911
929
  nextLayout[index] = safeSize;
912
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
930
+ if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
913
931
  numeric: true
914
932
  }) >= 0) {
915
933
  break;
@@ -1283,12 +1301,12 @@ function computePanelFlexBoxStyle({
1283
1301
  if (size == null) {
1284
1302
  // Initial render (before panels have registered themselves)
1285
1303
  // In order to support server rendering, fall back to default size if provided
1286
- flexGrow = defaultSize != undefined ? defaultSize.toPrecision(precision) : "1";
1304
+ flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1287
1305
  } else if (panelData.length === 1) {
1288
1306
  // Special case: Single panel group should always fill full width/height
1289
1307
  flexGrow = "1";
1290
1308
  } else {
1291
- flexGrow = size.toPrecision(precision);
1309
+ flexGrow = size.toFixed(precision);
1292
1310
  }
1293
1311
  return {
1294
1312
  flexBasis: 0,
@@ -2342,4 +2360,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2342
2360
  };
2343
2361
  }
2344
2362
 
2345
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
2363
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
@@ -195,20 +195,35 @@ function setNonce(value) {
195
195
 
196
196
  let currentCursorStyle = null;
197
197
  let enabled = true;
198
+ let getCustomCursorStyleFunction = null;
198
199
  let prevRuleIndex = -1;
199
200
  let styleElement = null;
201
+ function customizeGlobalCursorStyles(callback) {
202
+ getCustomCursorStyleFunction = callback;
203
+ }
200
204
  function disableGlobalCursorStyles() {
201
205
  enabled = false;
202
206
  }
203
207
  function enableGlobalCursorStyles() {
204
208
  enabled = true;
205
209
  }
206
- function getCursorStyle(state, constraintFlags) {
210
+ function getCursorStyle(state, constraintFlags, isPointerDown) {
211
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
212
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
213
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
214
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
215
+ if (getCustomCursorStyleFunction) {
216
+ return getCustomCursorStyleFunction({
217
+ exceedsHorizontalMaximum: horizontalMax,
218
+ exceedsHorizontalMinimum: horizontalMin,
219
+ exceedsVerticalMaximum: verticalMax,
220
+ exceedsVerticalMinimum: verticalMin,
221
+ intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
222
+ intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
223
+ isPointerDown
224
+ });
225
+ }
207
226
  if (constraintFlags) {
208
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
209
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
210
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
211
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
212
227
  if (horizontalMin) {
213
228
  if (verticalMin) {
214
229
  return "se-resize";
@@ -248,12 +263,12 @@ function resetGlobalCursorStyle() {
248
263
  prevRuleIndex = -1;
249
264
  }
250
265
  }
251
- function setGlobalCursorStyle(state, constraintFlags) {
266
+ function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
252
267
  var _styleElement$sheet$i, _styleElement$sheet2;
253
268
  if (!enabled) {
254
269
  return;
255
270
  }
256
- const style = getCursorStyle(state, constraintFlags);
271
+ const style = getCursorStyle(state, constraintFlags, isPointerDown);
257
272
  if (currentCursorStyle === style) {
258
273
  return;
259
274
  }
@@ -500,6 +515,9 @@ function handlePointerDown(event) {
500
515
  updateListeners();
501
516
  if (intersectingHandles.length > 0) {
502
517
  updateResizeHandlerStates("down", event);
518
+
519
+ // Update cursor based on return value(s) from active handles
520
+ updateCursor();
503
521
  event.preventDefault();
504
522
  if (!isWithinResizeHandle(target)) {
505
523
  event.stopImmediatePropagation();
@@ -657,11 +675,11 @@ function updateCursor() {
657
675
  constraintFlags |= flag;
658
676
  });
659
677
  if (intersectsHorizontal && intersectsVertical) {
660
- setGlobalCursorStyle("intersection", constraintFlags);
678
+ setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
661
679
  } else if (intersectsHorizontal) {
662
- setGlobalCursorStyle("horizontal", constraintFlags);
680
+ setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
663
681
  } else if (intersectsVertical) {
664
- setGlobalCursorStyle("vertical", constraintFlags);
682
+ setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
665
683
  } else {
666
684
  resetGlobalCursorStyle();
667
685
  }
@@ -946,7 +964,7 @@ function adjustLayoutByDelta({
946
964
  if (!fuzzyNumbersEqual(prevSize, safeSize)) {
947
965
  deltaApplied += prevSize - safeSize;
948
966
  nextLayout[index] = safeSize;
949
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
967
+ if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
950
968
  numeric: true
951
969
  }) >= 0) {
952
970
  break;
@@ -1444,12 +1462,12 @@ function computePanelFlexBoxStyle({
1444
1462
  if (size == null) {
1445
1463
  // Initial render (before panels have registered themselves)
1446
1464
  // In order to support server rendering, fall back to default size if provided
1447
- flexGrow = defaultSize != undefined ? defaultSize.toPrecision(precision) : "1";
1465
+ flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1448
1466
  } else if (panelData.length === 1) {
1449
1467
  // Special case: Single panel group should always fill full width/height
1450
1468
  flexGrow = "1";
1451
1469
  } else {
1452
- flexGrow = size.toPrecision(precision);
1470
+ flexGrow = size.toFixed(precision);
1453
1471
  }
1454
1472
  return {
1455
1473
  flexBasis: 0,
@@ -2576,4 +2594,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2576
2594
  };
2577
2595
  }
2578
2596
 
2579
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
2597
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
@@ -147,20 +147,35 @@ function setNonce(value) {
147
147
 
148
148
  let currentCursorStyle = null;
149
149
  let enabled = true;
150
+ let getCustomCursorStyleFunction = null;
150
151
  let prevRuleIndex = -1;
151
152
  let styleElement = null;
153
+ function customizeGlobalCursorStyles(callback) {
154
+ getCustomCursorStyleFunction = callback;
155
+ }
152
156
  function disableGlobalCursorStyles() {
153
157
  enabled = false;
154
158
  }
155
159
  function enableGlobalCursorStyles() {
156
160
  enabled = true;
157
161
  }
158
- function getCursorStyle(state, constraintFlags) {
162
+ function getCursorStyle(state, constraintFlags, isPointerDown) {
163
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
164
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
165
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
166
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
167
+ if (getCustomCursorStyleFunction) {
168
+ return getCustomCursorStyleFunction({
169
+ exceedsHorizontalMaximum: horizontalMax,
170
+ exceedsHorizontalMinimum: horizontalMin,
171
+ exceedsVerticalMaximum: verticalMax,
172
+ exceedsVerticalMinimum: verticalMin,
173
+ intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
174
+ intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
175
+ isPointerDown
176
+ });
177
+ }
159
178
  if (constraintFlags) {
160
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
161
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
162
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
163
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
164
179
  if (horizontalMin) {
165
180
  if (verticalMin) {
166
181
  return "se-resize";
@@ -200,12 +215,12 @@ function resetGlobalCursorStyle() {
200
215
  prevRuleIndex = -1;
201
216
  }
202
217
  }
203
- function setGlobalCursorStyle(state, constraintFlags) {
218
+ function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
204
219
  var _styleElement$sheet$i, _styleElement$sheet2;
205
220
  if (!enabled) {
206
221
  return;
207
222
  }
208
- const style = getCursorStyle(state, constraintFlags);
223
+ const style = getCursorStyle(state, constraintFlags, isPointerDown);
209
224
  if (currentCursorStyle === style) {
210
225
  return;
211
226
  }
@@ -452,6 +467,9 @@ function handlePointerDown(event) {
452
467
  updateListeners();
453
468
  if (intersectingHandles.length > 0) {
454
469
  updateResizeHandlerStates("down", event);
470
+
471
+ // Update cursor based on return value(s) from active handles
472
+ updateCursor();
455
473
  event.preventDefault();
456
474
  if (!isWithinResizeHandle(target)) {
457
475
  event.stopImmediatePropagation();
@@ -609,11 +627,11 @@ function updateCursor() {
609
627
  constraintFlags |= flag;
610
628
  });
611
629
  if (intersectsHorizontal && intersectsVertical) {
612
- setGlobalCursorStyle("intersection", constraintFlags);
630
+ setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
613
631
  } else if (intersectsHorizontal) {
614
- setGlobalCursorStyle("horizontal", constraintFlags);
632
+ setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
615
633
  } else if (intersectsVertical) {
616
- setGlobalCursorStyle("vertical", constraintFlags);
634
+ setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
617
635
  } else {
618
636
  resetGlobalCursorStyle();
619
637
  }
@@ -898,7 +916,7 @@ function adjustLayoutByDelta({
898
916
  if (!fuzzyNumbersEqual(prevSize, safeSize)) {
899
917
  deltaApplied += prevSize - safeSize;
900
918
  nextLayout[index] = safeSize;
901
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
919
+ if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
902
920
  numeric: true
903
921
  }) >= 0) {
904
922
  break;
@@ -1272,12 +1290,12 @@ function computePanelFlexBoxStyle({
1272
1290
  if (size == null) {
1273
1291
  // Initial render (before panels have registered themselves)
1274
1292
  // In order to support server rendering, fall back to default size if provided
1275
- flexGrow = defaultSize != undefined ? defaultSize.toPrecision(precision) : "1";
1293
+ flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1276
1294
  } else if (panelData.length === 1) {
1277
1295
  // Special case: Single panel group should always fill full width/height
1278
1296
  flexGrow = "1";
1279
1297
  } else {
1280
- flexGrow = size.toPrecision(precision);
1298
+ flexGrow = size.toFixed(precision);
1281
1299
  }
1282
1300
  return {
1283
1301
  flexBasis: 0,
@@ -2241,4 +2259,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2241
2259
  };
2242
2260
  }
2243
2261
 
2244
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
2262
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
@@ -184,20 +184,35 @@ function setNonce(value) {
184
184
 
185
185
  let currentCursorStyle = null;
186
186
  let enabled = true;
187
+ let getCustomCursorStyleFunction = null;
187
188
  let prevRuleIndex = -1;
188
189
  let styleElement = null;
190
+ function customizeGlobalCursorStyles(callback) {
191
+ getCustomCursorStyleFunction = callback;
192
+ }
189
193
  function disableGlobalCursorStyles() {
190
194
  enabled = false;
191
195
  }
192
196
  function enableGlobalCursorStyles() {
193
197
  enabled = true;
194
198
  }
195
- function getCursorStyle(state, constraintFlags) {
199
+ function getCursorStyle(state, constraintFlags, isPointerDown) {
200
+ const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
201
+ const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
202
+ const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
203
+ const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
204
+ if (getCustomCursorStyleFunction) {
205
+ return getCustomCursorStyleFunction({
206
+ exceedsHorizontalMaximum: horizontalMax,
207
+ exceedsHorizontalMinimum: horizontalMin,
208
+ exceedsVerticalMaximum: verticalMax,
209
+ exceedsVerticalMinimum: verticalMin,
210
+ intersectsHorizontalDragHandle: state === "horizontal" || state === "intersection",
211
+ intersectsVerticalDragHandle: state === "vertical" || state === "intersection",
212
+ isPointerDown
213
+ });
214
+ }
196
215
  if (constraintFlags) {
197
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
198
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
199
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
200
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
201
216
  if (horizontalMin) {
202
217
  if (verticalMin) {
203
218
  return "se-resize";
@@ -237,12 +252,12 @@ function resetGlobalCursorStyle() {
237
252
  prevRuleIndex = -1;
238
253
  }
239
254
  }
240
- function setGlobalCursorStyle(state, constraintFlags) {
255
+ function setGlobalCursorStyle(state, constraintFlags, isPointerDown) {
241
256
  var _styleElement$sheet$i, _styleElement$sheet2;
242
257
  if (!enabled) {
243
258
  return;
244
259
  }
245
- const style = getCursorStyle(state, constraintFlags);
260
+ const style = getCursorStyle(state, constraintFlags, isPointerDown);
246
261
  if (currentCursorStyle === style) {
247
262
  return;
248
263
  }
@@ -489,6 +504,9 @@ function handlePointerDown(event) {
489
504
  updateListeners();
490
505
  if (intersectingHandles.length > 0) {
491
506
  updateResizeHandlerStates("down", event);
507
+
508
+ // Update cursor based on return value(s) from active handles
509
+ updateCursor();
492
510
  event.preventDefault();
493
511
  if (!isWithinResizeHandle(target)) {
494
512
  event.stopImmediatePropagation();
@@ -646,11 +664,11 @@ function updateCursor() {
646
664
  constraintFlags |= flag;
647
665
  });
648
666
  if (intersectsHorizontal && intersectsVertical) {
649
- setGlobalCursorStyle("intersection", constraintFlags);
667
+ setGlobalCursorStyle("intersection", constraintFlags, isPointerDown);
650
668
  } else if (intersectsHorizontal) {
651
- setGlobalCursorStyle("horizontal", constraintFlags);
669
+ setGlobalCursorStyle("horizontal", constraintFlags, isPointerDown);
652
670
  } else if (intersectsVertical) {
653
- setGlobalCursorStyle("vertical", constraintFlags);
671
+ setGlobalCursorStyle("vertical", constraintFlags, isPointerDown);
654
672
  } else {
655
673
  resetGlobalCursorStyle();
656
674
  }
@@ -935,7 +953,7 @@ function adjustLayoutByDelta({
935
953
  if (!fuzzyNumbersEqual(prevSize, safeSize)) {
936
954
  deltaApplied += prevSize - safeSize;
937
955
  nextLayout[index] = safeSize;
938
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
956
+ if (deltaApplied.toFixed(3).localeCompare(Math.abs(delta).toFixed(3), undefined, {
939
957
  numeric: true
940
958
  }) >= 0) {
941
959
  break;
@@ -1423,12 +1441,12 @@ function computePanelFlexBoxStyle({
1423
1441
  if (size == null) {
1424
1442
  // Initial render (before panels have registered themselves)
1425
1443
  // In order to support server rendering, fall back to default size if provided
1426
- flexGrow = defaultSize != undefined ? defaultSize.toPrecision(precision) : "1";
1444
+ flexGrow = defaultSize != undefined ? defaultSize.toFixed(precision) : "1";
1427
1445
  } else if (panelData.length === 1) {
1428
1446
  // Special case: Single panel group should always fill full width/height
1429
1447
  flexGrow = "1";
1430
1448
  } else {
1431
- flexGrow = size.toPrecision(precision);
1449
+ flexGrow = size.toFixed(precision);
1432
1450
  }
1433
1451
  return {
1434
1452
  flexBasis: 0,
@@ -2465,4 +2483,4 @@ function getIntersectingRectangle(rectOne, rectTwo, strict) {
2465
2483
  };
2466
2484
  }
2467
2485
 
2468
- export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
2486
+ export { DATA_ATTRIBUTES, Panel, PanelGroup, PanelResizeHandle, assert, customizeGlobalCursorStyles, disableGlobalCursorStyles, enableGlobalCursorStyles, getIntersectingRectangle, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, intersects, setNonce, usePanelGroupContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-resizable-panels",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
4
4
  "type": "module",
5
5
  "description": "React components for resizable panel groups/layouts",
6
6
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
@@ -51,6 +51,15 @@
51
51
  }
52
52
  },
53
53
  "types": "dist/react-resizable-panels.d.ts",
54
+ "scripts": {
55
+ "clear": "pnpm run clear:builds & pnpm run clear:node_modules",
56
+ "clear:builds": "rm -rf ./packages/*/dist",
57
+ "clear:node_modules": "rm -rf ./node_modules",
58
+ "lint": "eslint \"src/**/*.{ts,tsx}\"",
59
+ "test:browser": "vitest",
60
+ "test:node": "vitest -c vitest.node.config.ts",
61
+ "watch": "parcel watch --port=2345"
62
+ },
54
63
  "devDependencies": {
55
64
  "@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
56
65
  "@babel/plugin-proposal-optional-chaining": "7.21.0",
@@ -68,14 +77,5 @@
68
77
  },
69
78
  "browserslist": [
70
79
  "Chrome 79"
71
- ],
72
- "scripts": {
73
- "clear": "pnpm run clear:builds & pnpm run clear:node_modules",
74
- "clear:builds": "rm -rf ./packages/*/dist",
75
- "clear:node_modules": "rm -rf ./node_modules",
76
- "lint": "eslint \"src/**/*.{ts,tsx}\"",
77
- "test:browser": "vitest",
78
- "test:node": "vitest -c vitest.node.config.ts",
79
- "watch": "parcel watch --port=2345"
80
- }
81
- }
80
+ ]
81
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 Brian Vaughn
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.