react-resizable-panels 2.0.8 → 2.0.10

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 (34) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/declarations/src/utils/assert.d.ts +1 -1
  3. package/dist/react-resizable-panels.browser.cjs.js +158 -53
  4. package/dist/react-resizable-panels.browser.development.cjs.js +160 -55
  5. package/dist/react-resizable-panels.browser.development.esm.js +159 -54
  6. package/dist/react-resizable-panels.browser.esm.js +157 -52
  7. package/dist/react-resizable-panels.cjs.js +158 -53
  8. package/dist/react-resizable-panels.development.cjs.js +160 -55
  9. package/dist/react-resizable-panels.development.esm.js +159 -54
  10. package/dist/react-resizable-panels.development.node.cjs.js +156 -51
  11. package/dist/react-resizable-panels.development.node.esm.js +155 -50
  12. package/dist/react-resizable-panels.esm.js +157 -52
  13. package/dist/react-resizable-panels.node.cjs.js +154 -49
  14. package/dist/react-resizable-panels.node.esm.js +153 -48
  15. package/package.json +1 -4
  16. package/src/Panel.test.tsx +23 -23
  17. package/src/PanelGroup.test.tsx +32 -3
  18. package/src/PanelGroup.ts +25 -7
  19. package/src/PanelResizeHandle.test.tsx +3 -3
  20. package/src/PanelResizeHandle.ts +1 -1
  21. package/src/PanelResizeHandleRegistry.ts +2 -2
  22. package/src/hooks/useWindowSplitterBehavior.ts +5 -2
  23. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +5 -5
  24. package/src/utils/adjustLayoutByDelta.ts +47 -20
  25. package/src/utils/assert.ts +1 -1
  26. package/src/utils/calculateAriaValues.ts +1 -1
  27. package/src/utils/calculateDragOffsetPercentage.ts +6 -3
  28. package/src/utils/calculateUnsafeDefaultLayout.ts +2 -2
  29. package/src/utils/callPanelCallbacks.ts +1 -1
  30. package/src/utils/resizePanel.ts +4 -1
  31. package/src/utils/test-utils.ts +1 -1
  32. package/src/utils/validatePanelConstraints.ts +4 -1
  33. package/src/utils/validatePanelGroupLayout.ts +3 -3
  34. package/src/vendor/stacking-order.ts +133 -0
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import { compare } from 'stacking-order';
3
2
 
4
3
  // This module exists to work around Webpack issue https://github.com/webpack/webpack/issues/14814
5
4
 
@@ -255,6 +254,114 @@ function intersects(rectOne, rectTwo, strict) {
255
254
  }
256
255
  }
257
256
 
257
+ // Forked from NPM stacking-order@2.0.0
258
+
259
+ /**
260
+ * Determine which of two nodes appears in front of the other —
261
+ * if `a` is in front, returns 1, otherwise returns -1
262
+ * @param {HTMLElement} a
263
+ * @param {HTMLElement} b
264
+ */
265
+ function compare(a, b) {
266
+ if (a === b) throw new Error("Cannot compare node with itself");
267
+ const ancestors = {
268
+ a: get_ancestors(a),
269
+ b: get_ancestors(b)
270
+ };
271
+ let common_ancestor;
272
+
273
+ // remove shared ancestors
274
+ while (ancestors.a.at(-1) === ancestors.b.at(-1)) {
275
+ a = ancestors.a.pop();
276
+ b = ancestors.b.pop();
277
+ common_ancestor = a;
278
+ }
279
+ assert(common_ancestor, "Stacking order can only be calculated for elements with a common ancestor");
280
+ const z_indexes = {
281
+ a: get_z_index(find_stacking_context(ancestors.a)),
282
+ b: get_z_index(find_stacking_context(ancestors.b))
283
+ };
284
+ if (z_indexes.a === z_indexes.b) {
285
+ const children = common_ancestor.childNodes;
286
+ const furthest_ancestors = {
287
+ a: ancestors.a.at(-1),
288
+ b: ancestors.b.at(-1)
289
+ };
290
+ let i = children.length;
291
+ while (i--) {
292
+ const child = children[i];
293
+ if (child === furthest_ancestors.a) return 1;
294
+ if (child === furthest_ancestors.b) return -1;
295
+ }
296
+ }
297
+ return Math.sign(z_indexes.a - z_indexes.b);
298
+ }
299
+ const props = /\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\b/;
300
+
301
+ /** @param {HTMLElement} node */
302
+ function is_flex_item(node) {
303
+ const display = getComputedStyle(get_parent(node)).display;
304
+ return display === "flex" || display === "inline-flex";
305
+ }
306
+
307
+ /** @param {HTMLElement} node */
308
+ function creates_stacking_context(node) {
309
+ const style = getComputedStyle(node);
310
+
311
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
312
+ if (style.position === "fixed") return true;
313
+ // Forked to fix upstream bug https://github.com/Rich-Harris/stacking-order/issues/3
314
+ // if (
315
+ // (style.zIndex !== "auto" && style.position !== "static") ||
316
+ // is_flex_item(node)
317
+ // )
318
+ if (style.zIndex !== "auto" && (style.position !== "static" || is_flex_item(node))) return true;
319
+ if (+style.opacity < 1) return true;
320
+ if ("transform" in style && style.transform !== "none") return true;
321
+ if ("webkitTransform" in style && style.webkitTransform !== "none") return true;
322
+ if ("mixBlendMode" in style && style.mixBlendMode !== "normal") return true;
323
+ if ("filter" in style && style.filter !== "none") return true;
324
+ if ("webkitFilter" in style && style.webkitFilter !== "none") return true;
325
+ if ("isolation" in style && style.isolation === "isolate") return true;
326
+ if (props.test(style.willChange)) return true;
327
+ // @ts-expect-error
328
+ if (style.webkitOverflowScrolling === "touch") return true;
329
+ return false;
330
+ }
331
+
332
+ /** @param {HTMLElement[]} nodes */
333
+ function find_stacking_context(nodes) {
334
+ let i = nodes.length;
335
+ while (i--) {
336
+ const node = nodes[i];
337
+ assert(node, "Missing node");
338
+ if (creates_stacking_context(node)) return node;
339
+ }
340
+ return null;
341
+ }
342
+
343
+ /** @param {HTMLElement} node */
344
+ function get_z_index(node) {
345
+ return node && Number(getComputedStyle(node).zIndex) || 0;
346
+ }
347
+
348
+ /** @param {HTMLElement} node */
349
+ function get_ancestors(node) {
350
+ const ancestors = [];
351
+ while (node) {
352
+ ancestors.push(node);
353
+ node = get_parent(node);
354
+ }
355
+ return ancestors; // [ node, ... <body>, <html>, document ]
356
+ }
357
+
358
+ /** @param {HTMLElement} node */
359
+ function get_parent(node) {
360
+ var _node$parentNode;
361
+ // @ts-ignore
362
+ return ((_node$parentNode = node.parentNode) === null || _node$parentNode === void 0 ? void 0 : _node$parentNode.host) || node.parentNode;
363
+ }
364
+
258
365
  const EXCEEDED_HORIZONTAL_MIN = 0b0001;
259
366
  const EXCEEDED_HORIZONTAL_MAX = 0b0010;
260
367
  const EXCEEDED_VERTICAL_MIN = 0b0100;
@@ -467,7 +574,7 @@ function updateListeners() {
467
574
  window.removeEventListener("mouseup", handlePointerUp);
468
575
  window.removeEventListener("touchcancel", handlePointerUp);
469
576
  window.removeEventListener("touchend", handlePointerUp);
470
- if (registerResizeHandle.length > 0) {
577
+ if (registeredResizeHandlers.size > 0) {
471
578
  if (isPointerDown) {
472
579
  if (intersectingHandles.length > 0) {
473
580
  ownerDocumentCounts.forEach((count, ownerDocument) => {
@@ -514,7 +621,7 @@ function updateResizeHandlerStates(action, event) {
514
621
  });
515
622
  }
516
623
 
517
- function assert(expectedCondition, message = "Assertion failed!") {
624
+ function assert(expectedCondition, message) {
518
625
  if (!expectedCondition) {
519
626
  console.error(message);
520
627
  throw Error(message);
@@ -545,7 +652,7 @@ function resizePanel({
545
652
  size
546
653
  }) {
547
654
  const panelConstraints = panelConstraintsArray[panelIndex];
548
- assert(panelConstraints != null);
655
+ assert(panelConstraints != null, `Panel constraints not found for index ${panelIndex}`);
549
656
  let {
550
657
  collapsedSize = 0,
551
658
  collapsible,
@@ -583,8 +690,8 @@ function adjustLayoutByDelta({
583
690
  }
584
691
  const nextLayout = [...prevLayout];
585
692
  const [firstPivotIndex, secondPivotIndex] = pivotIndices;
586
- assert(firstPivotIndex != null);
587
- assert(secondPivotIndex != null);
693
+ assert(firstPivotIndex != null, "Invalid first pivot index");
694
+ assert(secondPivotIndex != null, "Invalid second pivot index");
588
695
  let deltaApplied = 0;
589
696
 
590
697
  //const DEBUG = [];
@@ -610,19 +717,18 @@ function adjustLayoutByDelta({
610
717
  // Check if we should expand a collapsed panel
611
718
  const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
612
719
  const panelConstraints = panelConstraintsArray[index];
613
- assert(panelConstraints);
720
+ assert(panelConstraints, `Panel constraints not found for index ${index}`);
721
+ const {
722
+ collapsedSize = 0,
723
+ collapsible,
724
+ minSize = 0
725
+ } = panelConstraints;
614
726
 
615
727
  //DEBUG.push(`edge case check 1: ${index}`);
616
728
  //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
617
- if (panelConstraints.collapsible) {
729
+ if (collapsible) {
618
730
  const prevSize = prevLayout[index];
619
- assert(prevSize != null);
620
- const panelConstraints = panelConstraintsArray[index];
621
- assert(panelConstraints);
622
- const {
623
- collapsedSize = 0,
624
- minSize = 0
625
- } = panelConstraints;
731
+ assert(prevSize != null, `Previous layout not found for panel index ${index}`);
626
732
  if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
627
733
  const localDelta = minSize - prevSize;
628
734
  //DEBUG.push(` -> expand delta: ${localDelta}`);
@@ -639,22 +745,18 @@ function adjustLayoutByDelta({
639
745
  // Check if we should collapse a panel at its minimum size
640
746
  const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
641
747
  const panelConstraints = panelConstraintsArray[index];
642
- assert(panelConstraints);
748
+ assert(panelConstraints, `No panel constraints found for index ${index}`);
643
749
  const {
644
- collapsible
750
+ collapsedSize = 0,
751
+ collapsible,
752
+ minSize = 0
645
753
  } = panelConstraints;
646
754
 
647
755
  //DEBUG.push(`edge case check 2: ${index}`);
648
756
  //DEBUG.push(` -> collapsible? ${collapsible}`);
649
757
  if (collapsible) {
650
758
  const prevSize = prevLayout[index];
651
- assert(prevSize != null);
652
- const panelConstraints = panelConstraintsArray[index];
653
- assert(panelConstraints);
654
- const {
655
- collapsedSize = 0,
656
- minSize = 0
657
- } = panelConstraints;
759
+ assert(prevSize != null, `Previous layout not found for panel index ${index}`);
658
760
  if (fuzzyNumbersEqual(prevSize, minSize)) {
659
761
  const localDelta = prevSize - collapsedSize;
660
762
  //DEBUG.push(` -> expand delta: ${localDelta}`);
@@ -684,7 +786,7 @@ function adjustLayoutByDelta({
684
786
  //DEBUG.push("pre calc...");
685
787
  while (true) {
686
788
  const prevSize = prevLayout[index];
687
- assert(prevSize != null);
789
+ assert(prevSize != null, `Previous layout not found for panel index ${index}`);
688
790
  const maxSafeSize = resizePanel({
689
791
  panelConstraints: panelConstraintsArray,
690
792
  panelIndex: index,
@@ -715,7 +817,7 @@ function adjustLayoutByDelta({
715
817
  while (index >= 0 && index < panelConstraintsArray.length) {
716
818
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
717
819
  const prevSize = prevLayout[index];
718
- assert(prevSize != null);
820
+ assert(prevSize != null, `Previous layout not found for panel index ${index}`);
719
821
  const unsafeSize = prevSize - deltaRemaining;
720
822
  const safeSize = resizePanel({
721
823
  panelConstraints: panelConstraintsArray,
@@ -752,7 +854,7 @@ function adjustLayoutByDelta({
752
854
  // Now distribute the applied delta to the panels in the other direction
753
855
  const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
754
856
  const prevSize = prevLayout[pivotIndex];
755
- assert(prevSize != null);
857
+ assert(prevSize != null, `Previous layout not found for panel index ${pivotIndex}`);
756
858
  const unsafeSize = prevSize + deltaApplied;
757
859
  const safeSize = resizePanel({
758
860
  panelConstraints: panelConstraintsArray,
@@ -770,7 +872,7 @@ function adjustLayoutByDelta({
770
872
  let index = pivotIndex;
771
873
  while (index >= 0 && index < panelConstraintsArray.length) {
772
874
  const prevSize = nextLayout[index];
773
- assert(prevSize != null);
875
+ assert(prevSize != null, `Previous layout not found for panel index ${index}`);
774
876
  const unsafeSize = prevSize + deltaRemaining;
775
877
  const safeSize = resizePanel({
776
878
  panelConstraints: panelConstraintsArray,
@@ -873,17 +975,17 @@ function useWindowSplitterPanelGroupBehavior({
873
975
  return;
874
976
  }
875
977
  const eagerValues = eagerValuesRef.current;
876
- assert(eagerValues);
978
+ assert(eagerValues, `Eager values not found`);
877
979
  const {
878
980
  panelDataArray
879
981
  } = eagerValues;
880
982
  const groupElement = getPanelGroupElement(groupId, panelGroupElement);
881
983
  assert(groupElement != null, `No group found for id "${groupId}"`);
882
984
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
883
- assert(handles);
985
+ assert(handles, `No resize handles found for group id "${groupId}"`);
884
986
  const cleanupFunctions = handles.map(handle => {
885
987
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
886
- assert(handleId);
988
+ assert(handleId, `Resize handle element has no handle id attribute`);
887
989
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
888
990
  if (idBefore == null || idAfter == null) {
889
991
  return () => {};
@@ -899,7 +1001,7 @@ function useWindowSplitterPanelGroupBehavior({
899
1001
  const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
900
1002
  if (index >= 0) {
901
1003
  const panelData = panelDataArray[index];
902
- assert(panelData);
1004
+ assert(panelData, `No panel data found for index ${index}`);
903
1005
  const size = layout[index];
904
1006
  const {
905
1007
  collapsedSize = 0,
@@ -958,15 +1060,15 @@ function getResizeEventCursorPosition(direction, event) {
958
1060
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement) {
959
1061
  const isHorizontal = direction === "horizontal";
960
1062
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
961
- assert(handleElement);
1063
+ assert(handleElement, `No resize handle element found for id "${dragHandleId}"`);
962
1064
  const groupId = handleElement.getAttribute("data-panel-group-id");
963
- assert(groupId);
1065
+ assert(groupId, `Resize handle element has no group id attribute`);
964
1066
  let {
965
1067
  initialCursorPosition
966
1068
  } = initialDragState;
967
1069
  const cursorPosition = getResizeEventCursorPosition(direction, event);
968
1070
  const groupElement = getPanelGroupElement(groupId, panelGroupElement);
969
- assert(groupElement);
1071
+ assert(groupElement, `No group element found for id "${groupId}"`);
970
1072
  const groupRect = groupElement.getBoundingClientRect();
971
1073
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
972
1074
  const offsetPixels = cursorPosition - initialCursorPosition;
@@ -1020,7 +1122,7 @@ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragSta
1020
1122
  function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
1021
1123
  layout.forEach((size, index) => {
1022
1124
  const panelData = panelsArray[index];
1023
- assert(panelData);
1125
+ assert(panelData, `Panel data not found for index ${index}`);
1024
1126
  const {
1025
1127
  callbacks,
1026
1128
  constraints,
@@ -1198,7 +1300,7 @@ function validatePanelConstraints({
1198
1300
  {
1199
1301
  const warnings = [];
1200
1302
  const panelConstraints = panelConstraintsArray[panelIndex];
1201
- assert(panelConstraints);
1303
+ assert(panelConstraints, `No panel constraints found for index ${panelIndex}`);
1202
1304
  const {
1203
1305
  collapsedSize = 0,
1204
1306
  collapsible = false,
@@ -1252,7 +1354,7 @@ function validatePanelGroupLayout({
1252
1354
  }
1253
1355
  for (let index = 0; index < panelConstraints.length; index++) {
1254
1356
  const unsafeSize = nextLayout[index];
1255
- assert(unsafeSize != null);
1357
+ assert(unsafeSize != null, `No layout data found for index ${index}`);
1256
1358
  const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
1257
1359
  nextLayout[index] = safeSize;
1258
1360
  }
@@ -1262,7 +1364,7 @@ function validatePanelGroupLayout({
1262
1364
  // First pass: Validate the proposed layout given each panel's constraints
1263
1365
  for (let index = 0; index < panelConstraints.length; index++) {
1264
1366
  const unsafeSize = nextLayout[index];
1265
- assert(unsafeSize != null);
1367
+ assert(unsafeSize != null, `No layout data found for index ${index}`);
1266
1368
  const safeSize = resizePanel({
1267
1369
  panelConstraints,
1268
1370
  panelIndex: index,
@@ -1279,7 +1381,7 @@ function validatePanelGroupLayout({
1279
1381
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1280
1382
  for (let index = 0; index < panelConstraints.length; index++) {
1281
1383
  const prevSize = nextLayout[index];
1282
- assert(prevSize != null);
1384
+ assert(prevSize != null, `No layout data found for index ${index}`);
1283
1385
  const unsafeSize = prevSize + remainingSize;
1284
1386
  const safeSize = resizePanel({
1285
1387
  panelConstraints,
@@ -1448,7 +1550,7 @@ function PanelGroupWithForwardedRef({
1448
1550
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1449
1551
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1450
1552
  const panelData = panelDataArray[panelIndex];
1451
- assert(panelData);
1553
+ assert(panelData, `Panel data not found for index ${panelIndex}`);
1452
1554
  const isValid = validatePanelConstraints({
1453
1555
  panelConstraints,
1454
1556
  panelId: panelData.id,
@@ -1479,7 +1581,7 @@ function PanelGroupWithForwardedRef({
1479
1581
  panelSize,
1480
1582
  pivotIndices
1481
1583
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1482
- assert(panelSize != null);
1584
+ assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1483
1585
  if (panelSize !== collapsedSize) {
1484
1586
  // Store size before collapse;
1485
1587
  // This is the size that gets restored if the expand() API is used.
@@ -1556,7 +1658,7 @@ function PanelGroupWithForwardedRef({
1556
1658
  const {
1557
1659
  panelSize
1558
1660
  } = panelDataHelper(panelDataArray, panelData, layout);
1559
- assert(panelSize != null);
1661
+ assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1560
1662
  return panelSize;
1561
1663
  }, []);
1562
1664
 
@@ -1600,7 +1702,7 @@ function PanelGroupWithForwardedRef({
1600
1702
  collapsible,
1601
1703
  panelSize
1602
1704
  } = panelDataHelper(panelDataArray, panelData, layout);
1603
- assert(panelSize != null);
1705
+ assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1604
1706
  return !collapsible || panelSize > collapsedSize;
1605
1707
  }, []);
1606
1708
  const registerPanel = useCallback(panelData => {
@@ -1711,7 +1813,7 @@ function PanelGroupWithForwardedRef({
1711
1813
  panelSize,
1712
1814
  pivotIndices
1713
1815
  } = panelDataHelper(panelDataArray, panelData, prevLayout);
1714
- assert(panelSize != null);
1816
+ assert(panelSize != null, `Panel size not found for panel "${panelData.id}"`);
1715
1817
  const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1716
1818
  const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1717
1819
  const nextLayout = adjustLayoutByDelta({
@@ -1748,7 +1850,10 @@ function PanelGroupWithForwardedRef({
1748
1850
  const {
1749
1851
  panelSize: prevPanelSize
1750
1852
  } = panelDataHelper(panelDataArray, panelData, layout);
1751
- assert(prevPanelSize != null);
1853
+ if (prevPanelSize == null) {
1854
+ // It's possible that the panels in this group have changed since the last render
1855
+ return;
1856
+ }
1752
1857
  if (prevCollapsible && nextCollapsible && prevPanelSize === prevCollapsedSize) {
1753
1858
  if (prevCollapsedSize !== nextCollapsedSize) {
1754
1859
  resizePanel(panelData, nextCollapsedSize);
@@ -1770,7 +1875,7 @@ function PanelGroupWithForwardedRef({
1770
1875
  return;
1771
1876
  }
1772
1877
  const handleElement = getResizeHandleElement(dragHandleId, panelGroupElementRef.current);
1773
- assert(handleElement);
1878
+ assert(handleElement, `Drag handle element not found for id "${dragHandleId}"`);
1774
1879
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1775
1880
  setDragState({
1776
1881
  dragHandleId,
@@ -1899,10 +2004,10 @@ function useWindowSplitterResizeHandlerBehavior({
1899
2004
  {
1900
2005
  event.preventDefault();
1901
2006
  const groupId = handleElement.getAttribute("data-panel-group-id");
1902
- assert(groupId);
2007
+ assert(groupId, `No group element found for id "${groupId}"`);
1903
2008
  const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1904
2009
  const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
1905
- assert(index !== null);
2010
+ assert(index !== null, `No resize element found for id "${handleId}"`);
1906
2011
  const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
1907
2012
  const nextHandle = handles[nextIndex];
1908
2013
  nextHandle.focus();
@@ -1971,7 +2076,7 @@ function PanelResizeHandle({
1971
2076
  return;
1972
2077
  }
1973
2078
  const element = elementRef.current;
1974
- assert(element);
2079
+ assert(element, "Element ref not attached");
1975
2080
  const setResizeHandlerState = (action, isActive, event) => {
1976
2081
  if (isActive) {
1977
2082
  switch (action) {