react-sync-board 0.6.2 → 0.7.2

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/dist/esm/index.js CHANGED
@@ -4550,6 +4550,18 @@ var computeDistance = function computeDistance(_ref, _ref2) {
4550
4550
 
4551
4551
  var empty = function empty() {};
4552
4552
 
4553
+ var stopPropagation = function stopPropagation(fn) {
4554
+ return function (arg) {
4555
+ var event = arg.event;
4556
+
4557
+ if (!event.isPropagationStopped()) {
4558
+ return fn(arg);
4559
+ }
4560
+
4561
+ return null;
4562
+ };
4563
+ };
4564
+
4553
4565
  var protect = function protect(fn) {
4554
4566
  return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
4555
4567
  var _args = arguments;
@@ -4580,6 +4592,35 @@ var protect = function protect(fn) {
4580
4592
  }));
4581
4593
  };
4582
4594
 
4595
+ var PromiseQueue = /*#__PURE__*/function () {
4596
+ function PromiseQueue() {
4597
+ _classCallCheck(this, PromiseQueue);
4598
+
4599
+ _defineProperty(this, "lastPromise", Promise.resolve(true));
4600
+ }
4601
+
4602
+ _createClass(PromiseQueue, [{
4603
+ key: "add",
4604
+ value: function add(operation) {
4605
+ var _this = this;
4606
+
4607
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
4608
+ args[_key - 1] = arguments[_key];
4609
+ }
4610
+
4611
+ return new Promise(function (resolve, reject) {
4612
+ _this.lastPromise = _this.lastPromise.then(function () {
4613
+ return stopPropagation(protect(operation)).apply(void 0, args);
4614
+ }).then(resolve)["catch"](reject);
4615
+ });
4616
+ }
4617
+ }]);
4618
+
4619
+ return PromiseQueue;
4620
+ }();
4621
+
4622
+ var promiseQueue = new PromiseQueue();
4623
+
4583
4624
  var Gesture = function Gesture(_ref6) {
4584
4625
  var children = _ref6.children,
4585
4626
  _ref6$onDrag = _ref6.onDrag,
@@ -4596,57 +4637,25 @@ var Gesture = function Gesture(_ref6) {
4596
4637
  onLongTap = _ref6$onLongTap === void 0 ? empty : _ref6$onLongTap,
4597
4638
  _ref6$onDoubleTap = _ref6.onDoubleTap,
4598
4639
  onDoubleTap = _ref6$onDoubleTap === void 0 ? empty : _ref6$onDoubleTap,
4599
- onZoom = _ref6.onZoom;
4640
+ onZoom = _ref6.onZoom,
4641
+ _ref6$mainAction = _ref6.mainAction,
4642
+ mainAction = _ref6$mainAction === void 0 ? "drag" : _ref6$mainAction;
4600
4643
  var wrapperRef = React__default.useRef(null);
4601
4644
  var stateRef = React__default.useRef({
4602
4645
  moving: false,
4603
4646
  pointers: {},
4604
4647
  mainPointer: undefined
4605
4648
  });
4606
- var queueRef = React__default.useRef([]); // Queue event to avoid async mess
4607
-
4608
- var queue = React__default.useCallback(function (callback, args) {
4609
- queueRef.current.push( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
4610
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
4611
- while (1) {
4612
- switch (_context2.prev = _context2.next) {
4613
- case 0:
4614
- _context2.next = 2;
4615
- return protect(callback)(args);
4616
-
4617
- case 2:
4618
- queueRef.current.shift();
4619
-
4620
- if (!(queueRef.current.length !== 0)) {
4621
- _context2.next = 6;
4622
- break;
4623
- }
4624
-
4625
- _context2.next = 6;
4626
- return protect(queueRef.current[0])();
4627
-
4628
- case 6:
4629
- case "end":
4630
- return _context2.stop();
4631
- }
4632
- }
4633
- }, _callee2);
4634
- })));
4635
-
4636
- if (queueRef.current.length === 1) {
4637
- protect(queueRef.current[0])();
4638
- }
4639
- }, []);
4640
- var onWheel = React__default.useCallback(function (e) {
4641
- var deltaX = e.deltaX,
4642
- deltaY = e.deltaY,
4643
- clientX = e.clientX,
4644
- clientY = e.clientY,
4645
- deltaMode = e.deltaMode,
4646
- ctrlKey = e.ctrlKey,
4647
- altKey = e.altKey,
4648
- metaKey = e.metaKey,
4649
- target = e.target; // On a MacOs trackpad, the pinch gesture sets the ctrlKey to true.
4649
+ var onWheel = React__default.useCallback(function (event) {
4650
+ var deltaX = event.deltaX,
4651
+ deltaY = event.deltaY,
4652
+ clientX = event.clientX,
4653
+ clientY = event.clientY,
4654
+ deltaMode = event.deltaMode,
4655
+ ctrlKey = event.ctrlKey,
4656
+ altKey = event.altKey,
4657
+ metaKey = event.metaKey,
4658
+ target = event.target; // On a MacOs trackpad, the pinch gesture sets the ctrlKey to true.
4650
4659
  // In that situation, we want to use the custom scaling, not the browser default zoom.
4651
4660
  // Hence in this situation we avoid to return immediately.
4652
4661
 
@@ -4659,14 +4668,14 @@ var Gesture = function Gesture(_ref6) {
4659
4668
 
4660
4669
 
4661
4670
  if (isMacOS() && !ctrlKey) {
4662
- queue(onPan, {
4671
+ promiseQueue.add(onPan, {
4663
4672
  deltaX: -2 * deltaX,
4664
4673
  deltaY: -2 * deltaY,
4665
4674
  button: 1,
4666
4675
  ctrlKey: ctrlKey,
4667
4676
  metaKey: metaKey,
4668
4677
  target: target,
4669
- event: e
4678
+ event: event
4670
4679
  });
4671
4680
  } else {
4672
4681
  // Quit if onZoom is not set
@@ -4688,25 +4697,25 @@ var Gesture = function Gesture(_ref6) {
4688
4697
  scale *= 2;
4689
4698
  }
4690
4699
 
4691
- queue(onZoom, {
4700
+ promiseQueue.add(onZoom, {
4692
4701
  scale: scale,
4693
4702
  clientX: clientX,
4694
4703
  clientY: clientY,
4695
- event: e
4704
+ event: event
4696
4705
  });
4697
4706
  }
4698
- }, [onPan, onZoom, queue]);
4699
- var onPointerDown = React__default.useCallback(function (_ref8) {
4700
- var target = _ref8.target,
4701
- button = _ref8.button,
4702
- clientX = _ref8.clientX,
4703
- clientY = _ref8.clientY,
4704
- pointerId = _ref8.pointerId,
4705
- altKey = _ref8.altKey,
4706
- ctrlKey = _ref8.ctrlKey,
4707
- metaKey = _ref8.metaKey,
4708
- isPrimary = _ref8.isPrimary;
4709
- // Add pointer to map
4707
+ }, [onPan, onZoom]);
4708
+ var onPointerDown = React__default.useCallback(function (event) {
4709
+ var target = event.target,
4710
+ button = event.button,
4711
+ clientX = event.clientX,
4712
+ clientY = event.clientY,
4713
+ pointerId = event.pointerId,
4714
+ altKey = event.altKey,
4715
+ ctrlKey = event.ctrlKey,
4716
+ metaKey = event.metaKey,
4717
+ isPrimary = event.isPrimary; // Add pointer to map
4718
+
4710
4719
  stateRef.current.pointers[pointerId] = {
4711
4720
  clientX: clientX,
4712
4721
  clientY: clientY
@@ -4727,7 +4736,7 @@ var Gesture = function Gesture(_ref6) {
4727
4736
 
4728
4737
  var newClientX = (clientX2 + clientX) / 2;
4729
4738
  var newClientY = (clientY2 + clientY) / 2;
4730
- var distance = computeDistance([clientX2, clientY2], [clientX, clientY]); // We update previous position as the new position is the center beetween both finger
4739
+ var distance = computeDistance([clientX2, clientY2], [clientX, clientY]); // We update previous position as the new position is the center between both fingers
4731
4740
 
4732
4741
  Object.assign(stateRef.current, {
4733
4742
  pressed: true,
@@ -4763,29 +4772,31 @@ var Gesture = function Gesture(_ref6) {
4763
4772
  prevX: clientX,
4764
4773
  prevY: clientY,
4765
4774
  currentButton: button,
4775
+ pointerDownEvent: event,
4766
4776
  target: target,
4767
4777
  timeStart: Date.now(),
4768
- longTapTimeout: setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
4769
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
4778
+ longTapTimeout: setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
4779
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
4770
4780
  while (1) {
4771
- switch (_context3.prev = _context3.next) {
4781
+ switch (_context2.prev = _context2.next) {
4772
4782
  case 0:
4773
4783
  stateRef.current.noTap = true;
4774
- queue(onLongTap, {
4784
+ promiseQueue.add(onLongTap, {
4775
4785
  clientX: clientX,
4776
4786
  clientY: clientY,
4777
4787
  altKey: altKey,
4778
4788
  ctrlKey: ctrlKey,
4779
4789
  metaKey: metaKey,
4780
- target: target
4790
+ target: target,
4791
+ event: event
4781
4792
  });
4782
4793
 
4783
4794
  case 2:
4784
4795
  case "end":
4785
- return _context3.stop();
4796
+ return _context2.stop();
4786
4797
  }
4787
4798
  }
4788
- }, _callee3);
4799
+ }, _callee2);
4789
4800
  })), 750)
4790
4801
  });
4791
4802
 
@@ -4795,16 +4806,17 @@ var Gesture = function Gesture(_ref6) {
4795
4806
  // eslint-disable-next-line no-console
4796
4807
  console.log("Fail to capture pointer", e);
4797
4808
  }
4798
- }, [onLongTap, queue]);
4799
- var onPointerMove = React__default.useCallback(function (e) {
4809
+ }, [onLongTap]);
4810
+ var onPointerMove = React__default.useCallback(function (event) {
4800
4811
  if (stateRef.current.pressed) {
4801
- var pointerId = e.pointerId,
4802
- eventClientX = e.clientX,
4803
- eventClientY = e.clientY,
4804
- altKey = e.altKey,
4805
- ctrlKey = e.ctrlKey,
4806
- metaKey = e.metaKey,
4807
- pointerType = e.pointerType;
4812
+ var pointerId = event.pointerId,
4813
+ eventClientX = event.clientX,
4814
+ eventClientY = event.clientY,
4815
+ altKey = event.altKey,
4816
+ ctrlKey = event.ctrlKey,
4817
+ metaKey = event.metaKey,
4818
+ buttons = event.buttons,
4819
+ pointerType = event.pointerType;
4808
4820
 
4809
4821
  if (stateRef.current.mainPointer !== pointerId) {
4810
4822
  // Event from other pointer
@@ -4837,13 +4849,20 @@ var Gesture = function Gesture(_ref6) {
4837
4849
  clientY = eventClientY;
4838
4850
  } // We drag if
4839
4851
  // On non touch device
4840
- // - Button is 0
4841
- // - Alt key is no pressed
4852
+ // - Only button is pressed (1)
4853
+ // - any special key is no pressed
4842
4854
  // or on touch devices
4843
4855
  // - We use only one finger
4844
4856
 
4845
4857
 
4846
- var shouldDrag = pointerType !== "touch" ? stateRef.current.currentButton === 0 && !altKey : !twoFingers;
4858
+ var altAction = altKey || ctrlKey || metaKey || buttons !== 1;
4859
+
4860
+ if (mainAction !== "drag") {
4861
+ altAction = !altAction;
4862
+ }
4863
+
4864
+ var shouldDrag = pointerType !== "touch" ? !altAction : !twoFingers;
4865
+ var shouldPan = pointerType !== "touch" ? altAction : twoFingers;
4847
4866
 
4848
4867
  if (shouldDrag) {
4849
4868
  // Send drag start on first move
@@ -4852,7 +4871,7 @@ var Gesture = function Gesture(_ref6) {
4852
4871
  stateRef.current.gestureStart = true; // Clear tap timeout
4853
4872
 
4854
4873
  clearTimeout(stateRef.current.longTapTimeout);
4855
- queue(onDragStart, {
4874
+ promiseQueue.add(onDragStart, {
4856
4875
  deltaX: 0,
4857
4876
  deltaY: 0,
4858
4877
  startX: stateRef.current.startX,
@@ -4866,17 +4885,16 @@ var Gesture = function Gesture(_ref6) {
4866
4885
  ctrlKey: ctrlKey,
4867
4886
  metaKey: metaKey,
4868
4887
  target: stateRef.current.target,
4869
- event: e
4888
+ event: stateRef.current.pointerDownEvent
4870
4889
  });
4871
- } // Create closure
4872
-
4890
+ }
4873
4891
 
4874
4892
  var deltaX = clientX - stateRef.current.prevX;
4875
4893
  var deltaY = clientY - stateRef.current.prevY;
4876
4894
  var distanceX = clientX - stateRef.current.startX;
4877
4895
  var distanceY = clientY - stateRef.current.startY; // Drag event
4878
4896
 
4879
- queue(onDrag, {
4897
+ promiseQueue.add(onDrag, {
4880
4898
  deltaX: deltaX,
4881
4899
  deltaY: deltaY,
4882
4900
  startX: stateRef.current.startX,
@@ -4890,9 +4908,11 @@ var Gesture = function Gesture(_ref6) {
4890
4908
  ctrlKey: ctrlKey,
4891
4909
  metaKey: metaKey,
4892
4910
  target: stateRef.current.target,
4893
- event: e
4911
+ event: event
4894
4912
  });
4895
- } else {
4913
+ }
4914
+
4915
+ if (shouldPan) {
4896
4916
  if (!stateRef.current.gestureStart) {
4897
4917
  wrapperRef.current.style.cursor = "move";
4898
4918
  stateRef.current.gestureStart = true; // Clear tap timeout on first move
@@ -4907,7 +4927,7 @@ var Gesture = function Gesture(_ref6) {
4907
4927
 
4908
4928
  var target = stateRef.current.target; // Pan event
4909
4929
 
4910
- queue(onPan, {
4930
+ promiseQueue.add(onPan, {
4911
4931
  deltaX: _deltaX,
4912
4932
  deltaY: _deltaY,
4913
4933
  button: stateRef.current.currentButton,
@@ -4915,18 +4935,18 @@ var Gesture = function Gesture(_ref6) {
4915
4935
  ctrlKey: ctrlKey,
4916
4936
  metaKey: metaKey,
4917
4937
  target: target,
4918
- event: e
4938
+ event: event
4919
4939
  });
4920
4940
 
4921
4941
  if (twoFingers && distance !== stateRef.current.prevDistance && onZoom) {
4922
4942
  var scale = stateRef.current.prevDistance - distance;
4923
4943
 
4924
4944
  if (Math.abs(scale) > 0) {
4925
- queue(onZoom, {
4945
+ promiseQueue.add(onZoom, {
4926
4946
  scale: scale,
4927
4947
  clientX: clientX,
4928
4948
  clientY: clientY,
4929
- event: e
4949
+ event: event
4930
4950
  });
4931
4951
  stateRef.current.prevDistance = distance;
4932
4952
  }
@@ -4936,15 +4956,15 @@ var Gesture = function Gesture(_ref6) {
4936
4956
  stateRef.current.prevX = clientX;
4937
4957
  stateRef.current.prevY = clientY;
4938
4958
  }
4939
- }, [onDrag, onDragStart, onPan, onZoom, queue]);
4940
- var onPointerUp = React__default.useCallback(function (e) {
4941
- var clientX = e.clientX,
4942
- clientY = e.clientY,
4943
- altKey = e.altKey,
4944
- ctrlKey = e.ctrlKey,
4945
- metaKey = e.metaKey,
4946
- target = e.target,
4947
- pointerId = e.pointerId;
4959
+ }, [mainAction, onDrag, onDragStart, onPan, onZoom]);
4960
+ var onPointerUp = React__default.useCallback(function (event) {
4961
+ var clientX = event.clientX,
4962
+ clientY = event.clientY,
4963
+ altKey = event.altKey,
4964
+ ctrlKey = event.ctrlKey,
4965
+ metaKey = event.metaKey,
4966
+ target = event.target,
4967
+ pointerId = event.pointerId;
4948
4968
 
4949
4969
  if (!stateRef.current.pointers[pointerId]) {
4950
4970
  // Pointer already gone previously with another event
@@ -4983,7 +5003,7 @@ var Gesture = function Gesture(_ref6) {
4983
5003
  if (stateRef.current.moving) {
4984
5004
  // If we were moving, send drag end event
4985
5005
  stateRef.current.moving = false;
4986
- queue(onDragEnd, {
5006
+ promiseQueue.add(onDragEnd, {
4987
5007
  deltaX: clientX - stateRef.current.prevX,
4988
5008
  deltaY: clientY - stateRef.current.prevY,
4989
5009
  startX: stateRef.current.startX,
@@ -4996,7 +5016,7 @@ var Gesture = function Gesture(_ref6) {
4996
5016
  altKey: altKey,
4997
5017
  ctrlKey: ctrlKey,
4998
5018
  metaKey: metaKey,
4999
- event: e
5019
+ event: event
5000
5020
  });
5001
5021
  wrapperRef.current.style.cursor = "auto";
5002
5022
  } else {
@@ -5006,20 +5026,35 @@ var Gesture = function Gesture(_ref6) {
5006
5026
  stateRef.current.noTap = false;
5007
5027
  } // Send tap event only if time less than 300ms
5008
5028
  else if (stateRef.current.timeStart - now < 300) {
5009
- queue(onTap, {
5029
+ promiseQueue.add(onTap, {
5010
5030
  clientX: clientX,
5011
5031
  clientY: clientY,
5012
5032
  altKey: altKey,
5013
5033
  ctrlKey: ctrlKey,
5014
5034
  metaKey: metaKey,
5015
- target: target
5035
+ target: target,
5036
+ event: event
5016
5037
  });
5017
5038
  }
5018
5039
  }
5019
- }, [onDragEnd, onTap, queue]);
5040
+ }, [onDragEnd, onTap]);
5020
5041
  var onDoubleTapHandler = React__default.useCallback(function (event) {
5021
- queue(onDoubleTap, event);
5022
- }, [onDoubleTap, queue]);
5042
+ var clientX = event.clientX,
5043
+ clientY = event.clientY,
5044
+ altKey = event.altKey,
5045
+ ctrlKey = event.ctrlKey,
5046
+ metaKey = event.metaKey,
5047
+ target = event.target;
5048
+ promiseQueue.add(onDoubleTap, {
5049
+ clientX: clientX,
5050
+ clientY: clientY,
5051
+ altKey: altKey,
5052
+ ctrlKey: ctrlKey,
5053
+ metaKey: metaKey,
5054
+ target: target,
5055
+ event: event
5056
+ });
5057
+ }, [onDoubleTap]);
5023
5058
  return /*#__PURE__*/React__default.createElement("div", {
5024
5059
  onWheel: onWheel,
5025
5060
  onPointerDown: onPointerDown,
@@ -5911,24 +5946,20 @@ var Selector = function Selector(_ref) {
5911
5946
  }));
5912
5947
  }, [setSelected]);
5913
5948
  useThrottledEffect(updateSelected, [selector, updateSelected], 200);
5914
-
5915
- var onDragStart = /*#__PURE__*/function () {
5949
+ var onDragStart = React__default.useCallback( /*#__PURE__*/function () {
5916
5950
  var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(event) {
5917
- var button, altKey, ctrlKey, metaKey, foundElement, metaKeyPressed, goodButton;
5951
+ var foundElement;
5918
5952
  return regeneratorRuntime.wrap(function _callee2$(_context2) {
5919
5953
  while (1) {
5920
5954
  switch (_context2.prev = _context2.next) {
5921
5955
  case 0:
5922
- button = event.button, altKey = event.altKey, ctrlKey = event.ctrlKey, metaKey = event.metaKey;
5923
- _context2.next = 3;
5956
+ _context2.next = 2;
5924
5957
  return findElementUnderPointer(event);
5925
5958
 
5926
- case 3:
5959
+ case 2:
5927
5960
  foundElement = _context2.sent;
5928
- metaKeyPressed = altKey || ctrlKey || metaKey;
5929
- goodButton = moveFirst ? button === 1 || button === 0 && metaKeyPressed : button === 0 && !metaKeyPressed;
5930
5961
 
5931
- if (goodButton && (!foundElement || moveFirst)) {
5962
+ if (!foundElement) {
5932
5963
  stateRef.current.moving = true;
5933
5964
  setBoardState(function (prev) {
5934
5965
  return _objectSpread2(_objectSpread2({}, prev), {}, {
@@ -5938,7 +5969,7 @@ var Selector = function Selector(_ref) {
5938
5969
  wrapperRef.current.style.cursor = "crosshair";
5939
5970
  }
5940
5971
 
5941
- case 7:
5972
+ case 4:
5942
5973
  case "end":
5943
5974
  return _context2.stop();
5944
5975
  }
@@ -5946,11 +5977,10 @@ var Selector = function Selector(_ref) {
5946
5977
  }, _callee2);
5947
5978
  }));
5948
5979
 
5949
- return function onDragStart(_x) {
5980
+ return function (_x) {
5950
5981
  return _ref4.apply(this, arguments);
5951
5982
  };
5952
- }();
5953
-
5983
+ }(), [findElementUnderPointer, setBoardState]);
5954
5984
  var onDrag = useRecoilCallback(function (_ref5) {
5955
5985
  var snapshot = _ref5.snapshot;
5956
5986
  return /*#__PURE__*/function () {
@@ -6013,8 +6043,7 @@ var Selector = function Selector(_ref) {
6013
6043
  };
6014
6044
  }();
6015
6045
  }, []);
6016
-
6017
- var onDragEnd = function onDragEnd() {
6046
+ var onDragEnd = React__default.useCallback(function () {
6018
6047
  if (stateRef.current.moving) {
6019
6048
  setBoardState(function (prev) {
6020
6049
  return _objectSpread2(_objectSpread2({}, prev), {}, {
@@ -6027,8 +6056,7 @@ var Selector = function Selector(_ref) {
6027
6056
  });
6028
6057
  wrapperRef.current.style.cursor = "auto";
6029
6058
  }
6030
- };
6031
-
6059
+ }, [setBoardState]);
6032
6060
  var onLongTap = React__default.useCallback(function (_ref8) {
6033
6061
  var target = _ref8.target;
6034
6062
  var foundElement = insideClass(target, "item");
@@ -6109,7 +6137,8 @@ var Selector = function Selector(_ref) {
6109
6137
  onDrag: onDrag,
6110
6138
  onDragEnd: onDragEnd,
6111
6139
  onTap: onTap,
6112
- onLongTap: onLongTap
6140
+ onLongTap: onLongTap,
6141
+ mainAction: moveFirst ? "pan" : "drag"
6113
6142
  }, /*#__PURE__*/React__default.createElement("div", {
6114
6143
  ref: wrapperRef
6115
6144
  }, selector.moving && /*#__PURE__*/React__default.createElement("div", {
@@ -6202,23 +6231,24 @@ var ActionPane = function ActionPane(_ref) {
6202
6231
  var snapshot = _ref4.snapshot;
6203
6232
  return /*#__PURE__*/function () {
6204
6233
  var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_ref5) {
6205
- var deltaX, deltaY, _yield$snapshot$getPr, scale, moveX, moveY;
6234
+ var deltaX, deltaY, originalEvent, _yield$snapshot$getPr, scale, moveX, moveY;
6206
6235
 
6207
6236
  return regeneratorRuntime.wrap(function _callee2$(_context2) {
6208
6237
  while (1) {
6209
6238
  switch (_context2.prev = _context2.next) {
6210
6239
  case 0:
6211
- deltaX = _ref5.deltaX, deltaY = _ref5.deltaY;
6240
+ deltaX = _ref5.deltaX, deltaY = _ref5.deltaY, originalEvent = _ref5.event;
6212
6241
 
6213
6242
  if (!actionRef.current.moving) {
6214
- _context2.next = 10;
6243
+ _context2.next = 11;
6215
6244
  break;
6216
6245
  }
6217
6246
 
6218
- _context2.next = 4;
6247
+ originalEvent.stopPropagation();
6248
+ _context2.next = 5;
6219
6249
  return snapshot.getPromise(BoardTransformAtom);
6220
6250
 
6221
- case 4:
6251
+ case 5:
6222
6252
  _yield$snapshot$getPr = _context2.sent;
6223
6253
  scale = _yield$snapshot$getPr.scale;
6224
6254
  moveX = actionRef.current.remainX + deltaX / scale;
@@ -6233,7 +6263,7 @@ var ActionPane = function ActionPane(_ref) {
6233
6263
  }) : prev;
6234
6264
  });
6235
6265
 
6236
- case 10:
6266
+ case 11:
6237
6267
  case "end":
6238
6268
  return _context2.stop();
6239
6269
  }
@@ -6958,8 +6988,6 @@ var usePositionNavigator = function usePositionNavigator() {
6958
6988
  return null;
6959
6989
  };
6960
6990
 
6961
- var SCALE_TOLERANCE = 0.8;
6962
-
6963
6991
  var PanZoom = function PanZoom(_ref) {
6964
6992
  var children = _ref.children,
6965
6993
  _ref$moveFirst = _ref.moveFirst,
@@ -6969,7 +6997,8 @@ var PanZoom = function PanZoom(_ref) {
6969
6997
 
6970
6998
  var _useDim = useDim(),
6971
6999
  setDim = _useDim.setDim,
6972
- zoomTo = _useDim.zoomTo;
7000
+ zoomToCenter = _useDim.zoomToCenter,
7001
+ zoomToExtent = _useDim.zoomToExtent;
6973
7002
 
6974
7003
  var _useRecoilValue = useRecoilValue(ConfigurationAtom),
6975
7004
  itemExtentGlobal = _useRecoilValue.itemExtent;
@@ -6985,10 +7014,14 @@ var PanZoom = function PanZoom(_ref) {
6985
7014
  var getMouseInfo = useMousePosition(wrappedRef); // Hooks to save/restore position
6986
7015
 
6987
7016
  usePositionNavigator();
7017
+ /**
7018
+ * Center board on startup
7019
+ */
7020
+
6988
7021
  var centerBoard = useRecoilCallback(function (_ref2) {
6989
7022
  var snapshot = _ref2.snapshot;
6990
7023
  return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
6991
- var _yield$snapshot$getPr, _yield$snapshot$getPr2, left, top, width, height, boardWrapperRect, scaleX, scaleY, newScale, scaleWithTolerance, centerX, centerY;
7024
+ var _yield$snapshot$getPr, itemExtent;
6992
7025
 
6993
7026
  return regeneratorRuntime.wrap(function _callee$(_context) {
6994
7027
  while (1) {
@@ -6999,34 +7032,17 @@ var PanZoom = function PanZoom(_ref) {
6999
7032
 
7000
7033
  case 2:
7001
7034
  _yield$snapshot$getPr = _context.sent;
7002
- _yield$snapshot$getPr2 = _yield$snapshot$getPr.itemExtent;
7003
- left = _yield$snapshot$getPr2.left;
7004
- top = _yield$snapshot$getPr2.top;
7005
- width = _yield$snapshot$getPr2.width;
7006
- height = _yield$snapshot$getPr2.height;
7007
- boardWrapperRect = _yield$snapshot$getPr.boardWrapperRect;
7008
- scaleX = boardWrapperRect.width / width;
7009
- scaleY = boardWrapperRect.height / height;
7010
- newScale = Math.min(scaleX, scaleY);
7011
- scaleWithTolerance = newScale * SCALE_TOLERANCE;
7012
- centerX = boardWrapperRect.width / 2 - (left + width / 2) * scaleWithTolerance;
7013
- centerY = boardWrapperRect.height / 2 - (top + height / 2) * scaleWithTolerance;
7014
- setDim(function (prev) {
7015
- return _objectSpread2(_objectSpread2({}, prev), {}, {
7016
- translateX: centerX,
7017
- translateY: centerY,
7018
- scale: scaleWithTolerance
7019
- });
7020
- });
7035
+ itemExtent = _yield$snapshot$getPr.itemExtent;
7036
+ zoomToExtent(itemExtent);
7021
7037
 
7022
- case 16:
7038
+ case 5:
7023
7039
  case "end":
7024
7040
  return _context.stop();
7025
7041
  }
7026
7042
  }
7027
7043
  }, _callee);
7028
7044
  }));
7029
- }, [setDim]);
7045
+ }, [zoomToExtent]);
7030
7046
  React__default.useEffect(function () {
7031
7047
  if (!centered && itemExtentGlobal.left) {
7032
7048
  // Center board on first valid extent
@@ -7038,7 +7054,7 @@ var PanZoom = function PanZoom(_ref) {
7038
7054
  var clientX = _ref4.clientX,
7039
7055
  clientY = _ref4.clientY,
7040
7056
  scale = _ref4.scale;
7041
- zoomTo(1 - scale / 500, {
7057
+ zoomToCenter(1 - scale / 500, {
7042
7058
  x: clientX,
7043
7059
  y: clientY
7044
7060
  }); // Update the board zooming state
@@ -7056,7 +7072,7 @@ var PanZoom = function PanZoom(_ref) {
7056
7072
  zooming: true
7057
7073
  }) : prev;
7058
7074
  });
7059
- }, [setBoardState, zoomTo]);
7075
+ }, [setBoardState, zoomToCenter]);
7060
7076
  var onPan = React__default.useCallback( /*#__PURE__*/function () {
7061
7077
  var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_ref5) {
7062
7078
  var deltaX, deltaY;
@@ -7098,14 +7114,6 @@ var PanZoom = function PanZoom(_ref) {
7098
7114
  return _ref6.apply(this, arguments);
7099
7115
  };
7100
7116
  }(), [setBoardState, setDim]);
7101
- var onDrag = React__default.useCallback(function (state) {
7102
- var target = state.target;
7103
- var outsideItem = !insideClass(target, "item") || insideClass(target, "locked");
7104
-
7105
- if (moveFirst && outsideItem) {
7106
- onPan(state);
7107
- }
7108
- }, [moveFirst, onPan]);
7109
7117
  var onKeyDown = useRecoilCallback(function (_ref7) {
7110
7118
  var snapshot = _ref7.snapshot;
7111
7119
  return /*#__PURE__*/function () {
@@ -7190,14 +7198,14 @@ var PanZoom = function PanZoom(_ref) {
7190
7198
  translateX: prev.translateX + moveX
7191
7199
  });
7192
7200
  });
7193
- zoomTo(zoom);
7201
+ zoomToCenter(zoom);
7194
7202
  e.preventDefault();
7195
7203
 
7196
7204
  case 31:
7197
7205
  // Temporary zoom
7198
7206
  if (e.key === " " && !e.repeat) {
7199
7207
  if (getMouseInfo().hover) {
7200
- zoomTo(3, getMouseInfo());
7208
+ zoomToCenter(3, getMouseInfo());
7201
7209
  }
7202
7210
  }
7203
7211
 
@@ -7213,15 +7221,15 @@ var PanZoom = function PanZoom(_ref) {
7213
7221
  return _ref8.apply(this, arguments);
7214
7222
  };
7215
7223
  }();
7216
- }, [setDim, zoomTo, getMouseInfo]);
7224
+ }, [setDim, zoomToCenter, getMouseInfo]);
7217
7225
  var onKeyUp = React__default.useCallback(function (e) {
7218
7226
  // Ignore text in Input or Textarea
7219
7227
  if (["INPUT", "TEXTAREA"].includes(e.target.tagName)) return; // Zoom out on release
7220
7228
 
7221
7229
  if (e.key === " " && getMouseInfo().hover) {
7222
- zoomTo(1 / 3, getMouseInfo());
7230
+ zoomToCenter(1 / 3, getMouseInfo());
7223
7231
  }
7224
- }, [getMouseInfo, zoomTo]);
7232
+ }, [getMouseInfo, zoomToCenter]);
7225
7233
  React__default.useEffect(function () {
7226
7234
  document.addEventListener("keydown", onKeyDown);
7227
7235
  document.addEventListener("keyup", onKeyUp);
@@ -7233,7 +7241,7 @@ var PanZoom = function PanZoom(_ref) {
7233
7241
  return /*#__PURE__*/React__default.createElement(Gesture, {
7234
7242
  onPan: onPan,
7235
7243
  onZoom: onZoom,
7236
- onDrag: onDrag
7244
+ mainAction: moveFirst ? "pan" : "drag"
7237
7245
  }, /*#__PURE__*/React__default.createElement("div", {
7238
7246
  style: {
7239
7247
  display: "inline-block",
@@ -7401,7 +7409,9 @@ var Board = function Board(_ref) {
7401
7409
  moveFirst: moveFirst
7402
7410
  }, /*#__PURE__*/React__default.createElement(Selector, {
7403
7411
  moveFirst: moveFirst
7404
- }, /*#__PURE__*/React__default.createElement(ActionPane, null, /*#__PURE__*/React__default.createElement(CursorPane, null, /*#__PURE__*/React__default.createElement("div", {
7412
+ }, /*#__PURE__*/React__default.createElement(ActionPane, {
7413
+ moveFirst: moveFirst
7414
+ }, /*#__PURE__*/React__default.createElement(CursorPane, null, /*#__PURE__*/React__default.createElement("div", {
7405
7415
  onContextMenu: function onContextMenu(e) {
7406
7416
  e.preventDefault();
7407
7417
  },
@@ -7412,6 +7422,7 @@ var Board = function Board(_ref) {
7412
7422
 
7413
7423
  var TOLERANCE = 100;
7414
7424
  var MIN_SIZE = 1000;
7425
+ var SCALE_TOLERANCE = 0.8;
7415
7426
 
7416
7427
  var translateBoundaries = function translateBoundaries(_ref) {
7417
7428
  var x = _ref.x,
@@ -7529,7 +7540,7 @@ var useDim = function useDim() {
7529
7540
  };
7530
7541
  }();
7531
7542
  }, [setDim]);
7532
- var zoomTo = useRecoilCallback(function (_ref5) {
7543
+ var zoomToCenter = useRecoilCallback(function (_ref5) {
7533
7544
  var snapshot = _ref5.snapshot;
7534
7545
  return /*#__PURE__*/function () {
7535
7546
  var _ref6 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(factor, zoomCenter) {
@@ -7608,24 +7619,68 @@ var useDim = function useDim() {
7608
7619
  };
7609
7620
  }();
7610
7621
  }, [setDim]);
7611
- var updateScaleBoundaries = useRecoilCallback(function (_ref7) {
7622
+ var zoomToExtent = useRecoilCallback(function (_ref7) {
7612
7623
  var snapshot = _ref7.snapshot;
7613
- return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
7614
- var _yield$snapshot$getPr3, _yield$snapshot$getPr4, width, height, boardWrapperRect, scaleX, scaleY, newScale;
7624
+ return /*#__PURE__*/function () {
7625
+ var _ref9 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(_ref8) {
7626
+ var left, top, width, height, _yield$snapshot$getPr3, boardWrapperRect, scaleX, scaleY, newScale, scaleWithTolerance, centerX, centerY;
7615
7627
 
7616
- return regeneratorRuntime.wrap(function _callee3$(_context3) {
7628
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
7629
+ while (1) {
7630
+ switch (_context3.prev = _context3.next) {
7631
+ case 0:
7632
+ left = _ref8.left, top = _ref8.top, width = _ref8.width, height = _ref8.height;
7633
+ _context3.next = 3;
7634
+ return snapshot.getPromise(ConfigurationAtom);
7635
+
7636
+ case 3:
7637
+ _yield$snapshot$getPr3 = _context3.sent;
7638
+ boardWrapperRect = _yield$snapshot$getPr3.boardWrapperRect;
7639
+ scaleX = boardWrapperRect.width / width;
7640
+ scaleY = boardWrapperRect.height / height;
7641
+ newScale = Math.min(scaleX, scaleY);
7642
+ scaleWithTolerance = newScale * SCALE_TOLERANCE;
7643
+ centerX = boardWrapperRect.width / 2 - (left + width / 2) * scaleWithTolerance;
7644
+ centerY = boardWrapperRect.height / 2 - (top + height / 2) * scaleWithTolerance;
7645
+ setDim(function (prev) {
7646
+ return _objectSpread2(_objectSpread2({}, prev), {}, {
7647
+ translateX: centerX,
7648
+ translateY: centerY,
7649
+ scale: scaleWithTolerance
7650
+ });
7651
+ });
7652
+
7653
+ case 12:
7654
+ case "end":
7655
+ return _context3.stop();
7656
+ }
7657
+ }
7658
+ }, _callee3);
7659
+ }));
7660
+
7661
+ return function (_x4) {
7662
+ return _ref9.apply(this, arguments);
7663
+ };
7664
+ }();
7665
+ }, [setDim]);
7666
+ var updateScaleBoundaries = useRecoilCallback(function (_ref10) {
7667
+ var snapshot = _ref10.snapshot;
7668
+ return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
7669
+ var _yield$snapshot$getPr4, _yield$snapshot$getPr5, width, height, boardWrapperRect, scaleX, scaleY, newScale;
7670
+
7671
+ return regeneratorRuntime.wrap(function _callee4$(_context4) {
7617
7672
  while (1) {
7618
- switch (_context3.prev = _context3.next) {
7673
+ switch (_context4.prev = _context4.next) {
7619
7674
  case 0:
7620
- _context3.next = 2;
7675
+ _context4.next = 2;
7621
7676
  return snapshot.getPromise(ConfigurationAtom);
7622
7677
 
7623
7678
  case 2:
7624
- _yield$snapshot$getPr3 = _context3.sent;
7625
- _yield$snapshot$getPr4 = _yield$snapshot$getPr3.itemExtent;
7626
- width = _yield$snapshot$getPr4.width;
7627
- height = _yield$snapshot$getPr4.height;
7628
- boardWrapperRect = _yield$snapshot$getPr3.boardWrapperRect;
7679
+ _yield$snapshot$getPr4 = _context4.sent;
7680
+ _yield$snapshot$getPr5 = _yield$snapshot$getPr4.itemExtent;
7681
+ width = _yield$snapshot$getPr5.width;
7682
+ height = _yield$snapshot$getPr5.height;
7683
+ boardWrapperRect = _yield$snapshot$getPr4.boardWrapperRect;
7629
7684
  scaleX = boardWrapperRect.width / width;
7630
7685
  scaleY = boardWrapperRect.height / height;
7631
7686
  newScale = Math.min(scaleX, scaleY);
@@ -7633,86 +7688,86 @@ var useDim = function useDim() {
7633
7688
 
7634
7689
  case 11:
7635
7690
  case "end":
7636
- return _context3.stop();
7691
+ return _context4.stop();
7637
7692
  }
7638
7693
  }
7639
- }, _callee3);
7694
+ }, _callee4);
7640
7695
  }));
7641
7696
  }, []);
7642
- var getCenterCoordinates = useRecoilCallback(function (_ref9) {
7643
- var snapshot = _ref9.snapshot;
7644
- return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
7645
- var _yield$snapshot$getPr5, boardWrapperRect, boardSize, _yield$snapshot$getPr6, translateX, translateY, scale;
7697
+ var getCenterCoordinates = useRecoilCallback(function (_ref12) {
7698
+ var snapshot = _ref12.snapshot;
7699
+ return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
7700
+ var _yield$snapshot$getPr6, boardWrapperRect, boardSize, _yield$snapshot$getPr7, translateX, translateY, scale;
7646
7701
 
7647
- return regeneratorRuntime.wrap(function _callee4$(_context4) {
7702
+ return regeneratorRuntime.wrap(function _callee5$(_context5) {
7648
7703
  while (1) {
7649
- switch (_context4.prev = _context4.next) {
7704
+ switch (_context5.prev = _context5.next) {
7650
7705
  case 0:
7651
- _context4.next = 2;
7706
+ _context5.next = 2;
7652
7707
  return snapshot.getPromise(ConfigurationAtom);
7653
7708
 
7654
7709
  case 2:
7655
- _yield$snapshot$getPr5 = _context4.sent;
7656
- boardWrapperRect = _yield$snapshot$getPr5.boardWrapperRect;
7657
- boardSize = _yield$snapshot$getPr5.boardSize;
7658
- _context4.next = 7;
7710
+ _yield$snapshot$getPr6 = _context5.sent;
7711
+ boardWrapperRect = _yield$snapshot$getPr6.boardWrapperRect;
7712
+ boardSize = _yield$snapshot$getPr6.boardSize;
7713
+ _context5.next = 7;
7659
7714
  return snapshot.getPromise(BoardTransformAtom);
7660
7715
 
7661
7716
  case 7:
7662
- _yield$snapshot$getPr6 = _context4.sent;
7663
- translateX = _yield$snapshot$getPr6.translateX;
7664
- translateY = _yield$snapshot$getPr6.translateY;
7665
- scale = _yield$snapshot$getPr6.scale;
7666
- return _context4.abrupt("return", {
7717
+ _yield$snapshot$getPr7 = _context5.sent;
7718
+ translateX = _yield$snapshot$getPr7.translateX;
7719
+ translateY = _yield$snapshot$getPr7.translateY;
7720
+ scale = _yield$snapshot$getPr7.scale;
7721
+ return _context5.abrupt("return", {
7667
7722
  x: (boardWrapperRect.width / 2 - translateX) / scale - boardSize / 2,
7668
7723
  y: (boardWrapperRect.height / 2 - translateY) / scale - boardSize / 2
7669
7724
  });
7670
7725
 
7671
7726
  case 12:
7672
7727
  case "end":
7673
- return _context4.stop();
7728
+ return _context5.stop();
7674
7729
  }
7675
7730
  }
7676
- }, _callee4);
7731
+ }, _callee5);
7677
7732
  }));
7678
7733
  }, []);
7679
- var updateItemExtent = useRecoilCallback(function (_ref11) {
7680
- var snapshot = _ref11.snapshot,
7681
- set = _ref11.set;
7682
- return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
7683
- var itemIds, _yield$snapshot$getPr7, boardWrapperRect, boardWrapper, boardSize, _yield$snapshot$getPr8, scale, translateX, translateY, _ref13, left, top, width, height, relativeExtent, delta, _delta;
7734
+ var updateItemExtent = useRecoilCallback(function (_ref14) {
7735
+ var snapshot = _ref14.snapshot,
7736
+ set = _ref14.set;
7737
+ return /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
7738
+ var itemIds, _yield$snapshot$getPr8, boardWrapperRect, boardWrapper, boardSize, _yield$snapshot$getPr9, scale, translateX, translateY, _ref16, left, top, width, height, relativeExtent, delta, _delta;
7684
7739
 
7685
- return regeneratorRuntime.wrap(function _callee5$(_context5) {
7740
+ return regeneratorRuntime.wrap(function _callee6$(_context6) {
7686
7741
  while (1) {
7687
- switch (_context5.prev = _context5.next) {
7742
+ switch (_context6.prev = _context6.next) {
7688
7743
  case 0:
7689
- _context5.next = 2;
7744
+ _context6.next = 2;
7690
7745
  return snapshot.getPromise(ItemListAtom);
7691
7746
 
7692
7747
  case 2:
7693
- itemIds = _context5.sent;
7694
- _context5.next = 5;
7748
+ itemIds = _context6.sent;
7749
+ _context6.next = 5;
7695
7750
  return snapshot.getPromise(ConfigurationAtom);
7696
7751
 
7697
7752
  case 5:
7698
- _yield$snapshot$getPr7 = _context5.sent;
7699
- boardWrapperRect = _yield$snapshot$getPr7.boardWrapperRect;
7700
- boardWrapper = _yield$snapshot$getPr7.boardWrapper;
7701
- boardSize = _yield$snapshot$getPr7.boardSize;
7702
- _context5.next = 11;
7753
+ _yield$snapshot$getPr8 = _context6.sent;
7754
+ boardWrapperRect = _yield$snapshot$getPr8.boardWrapperRect;
7755
+ boardWrapper = _yield$snapshot$getPr8.boardWrapper;
7756
+ boardSize = _yield$snapshot$getPr8.boardSize;
7757
+ _context6.next = 11;
7703
7758
  return snapshot.getPromise(BoardTransformAtom);
7704
7759
 
7705
7760
  case 11:
7706
- _yield$snapshot$getPr8 = _context5.sent;
7707
- scale = _yield$snapshot$getPr8.scale;
7708
- translateX = _yield$snapshot$getPr8.translateX;
7709
- translateY = _yield$snapshot$getPr8.translateY;
7710
- _ref13 = getItemBoundingBox(itemIds, boardWrapper) || {
7761
+ _yield$snapshot$getPr9 = _context6.sent;
7762
+ scale = _yield$snapshot$getPr9.scale;
7763
+ translateX = _yield$snapshot$getPr9.translateX;
7764
+ translateY = _yield$snapshot$getPr9.translateY;
7765
+ _ref16 = getItemBoundingBox(itemIds, boardWrapper) || {
7711
7766
  left: boardSize / 2 * scale + boardWrapperRect.left + translateX,
7712
7767
  top: boardSize / 2 * scale + boardWrapperRect.top + translateY,
7713
7768
  width: 0,
7714
7769
  height: 0
7715
- }, left = _ref13.left, top = _ref13.top, width = _ref13.width, height = _ref13.height;
7770
+ }, left = _ref16.left, top = _ref16.top, width = _ref16.width, height = _ref16.height;
7716
7771
  relativeExtent = {
7717
7772
  left: (left - boardWrapperRect.left - translateX) / scale,
7718
7773
  top: (top - boardWrapperRect.top - translateY) / scale,
@@ -7744,10 +7799,10 @@ var useDim = function useDim() {
7744
7799
 
7745
7800
  case 22:
7746
7801
  case "end":
7747
- return _context5.stop();
7802
+ return _context6.stop();
7748
7803
  }
7749
7804
  }
7750
- }, _callee5);
7805
+ }, _callee6);
7751
7806
  }));
7752
7807
  }, []);
7753
7808
  var debouncedUpdateItemExtent = useDebouncedCallback(updateItemExtent, [], 300);
@@ -7759,7 +7814,9 @@ var useDim = function useDim() {
7759
7814
  return {
7760
7815
  setDim: setDimSafe,
7761
7816
  getDim: getDim,
7762
- zoomTo: zoomTo,
7817
+ zoomTo: zoomToCenter,
7818
+ zoomToCenter: zoomToCenter,
7819
+ zoomToExtent: zoomToExtent,
7763
7820
  getCenter: getCenterCoordinates,
7764
7821
  updateItemExtent: debouncedUpdateItemExtent
7765
7822
  };