@jsenv/navi 0.29.363 → 0.29.364

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.
@@ -55432,6 +55432,10 @@ const SlideContainer = ({
55432
55432
  // one being travelled TO while the track moves. What the next travel departs
55433
55433
  // from, because it is what one is looking at.
55434
55434
  const drawnAreaRef = useRef(undefined);
55435
+ // The movement the track is playing, while it plays: the slide it is leaving
55436
+ // and the slide it is going to. A hand landing on the box takes it over from
55437
+ // its origin (see onStart in createTravelHandlers).
55438
+ const movingRef = useRef(null);
55435
55439
  // Which way the travel about to be drawn goes, when whatever asked for it
55436
55440
  // knows: a window stepping off its last slide comes back on its first, and
55437
55441
  // only the press says that is a step forward — the map, read between those
@@ -55693,6 +55697,7 @@ const SlideContainer = ({
55693
55697
  }
55694
55698
  stageRef.current = null;
55695
55699
  trackAnimationRef.current = null;
55700
+ movingRef.current = null;
55696
55701
  // At rest the picture IS the current slide, whatever the last gesture wrote
55697
55702
  // there: an indicator has nothing left to lean towards.
55698
55703
  paintTravelProgress(0);
@@ -55887,7 +55892,7 @@ const SlideContainer = ({
55887
55892
  // there, and when it is over this is what holds. Except under a hand-off
55888
55893
  // still waiting for its travel: the track stays where the finger left it,
55889
55894
  // until the render that moves it or the frame after which the gesture gives
55890
- // up on it (see returnToRest in onEnd).
55895
+ // up on it (see settleTowards in onEnd).
55891
55896
  if (!travelFromRef.current) {
55892
55897
  track.style.setProperty("--slide-container-offset", offset);
55893
55898
  }
@@ -55922,6 +55927,10 @@ const SlideContainer = ({
55922
55927
  duration: durationMs * travelRatio,
55923
55928
  easing
55924
55929
  });
55930
+ movingRef.current = {
55931
+ from: drawnArea,
55932
+ to: currentArea
55933
+ };
55925
55934
  // The trait travels with the slides: from where the gesture left it when
55926
55935
  // there was one, from a whole box away when the travel was asked for.
55927
55936
  const progressFrom = travelProgressFromRef.current ?? (travelStep ? travelStep.x || travelStep.y : 0);
@@ -56707,7 +56716,7 @@ const SlideContainer = ({
56707
56716
  // The two slides the gesture can bring in, placed one box either side of the
56708
56717
  // one being dragged — the same stage a travel builds, except that both ends
56709
56718
  // are set up at once because the finger has not said yet which way it goes.
56710
- const stageDrag = drag => {
56719
+ const stageDrag = (drag, currentArea) => {
56711
56720
  const {
56712
56721
  slideElements,
56713
56722
  placeOf
@@ -56735,7 +56744,7 @@ const SlideContainer = ({
56735
56744
  }
56736
56745
  stageRef.current = {
56737
56746
  placeByArea,
56738
- area: drag.area
56747
+ area: currentArea
56739
56748
  };
56740
56749
  for (const slideElement of slideElements) {
56741
56750
  const area = readArea(slideElement);
@@ -56751,33 +56760,63 @@ const SlideContainer = ({
56751
56760
  }
56752
56761
  };
56753
56762
 
56754
- // Let go of without enough of a gesture to travel: the slide comes back to
56755
- // where it was, over the distance it was pulled so a slide barely moved
56756
- // snaps back and one dragged most of the way there takes its time.
56757
- const returnToRest = drag => {
56763
+ // Let go of, and the slides go where the gesture leaves them: back on the
56764
+ // slide being dragged when nothing travels, on to the slide arriving when a
56765
+ // travel caught in flight is let carry on. Over the distance left to cover,
56766
+ // so a slide barely moved snaps back and one dragged most of the way there
56767
+ // takes its time.
56768
+ const settleTowards = (drag, area) => {
56758
56769
  const track = trackRef.current;
56759
56770
  if (!track) {
56760
56771
  return;
56761
56772
  }
56762
- const restOffset = `${drag.baseOffset.x}px ${drag.baseOffset.y}px`;
56773
+ const stage = stageRef.current;
56774
+ const {
56775
+ placeOf
56776
+ } = readMap();
56777
+ const place = stage?.placeByArea.get(area) || placeOf.get(area) || {
56778
+ x: 0,
56779
+ y: 0
56780
+ };
56781
+ const restPx = {
56782
+ x: -place.x * drag.box.width,
56783
+ y: -place.y * drag.box.height
56784
+ };
56785
+ const nowPx = {
56786
+ x: drag.baseOffset.x + drag.pull.x,
56787
+ y: drag.baseOffset.y + drag.pull.y
56788
+ };
56789
+ const restOffset = `${restPx.x}px ${restPx.y}px`;
56763
56790
  const durationMs = durationToMs(duration);
56764
- const pulled = Math.abs(drag.pull[drag.axis]);
56765
56791
  const size = drag.axis === "x" ? drag.box.width : drag.box.height;
56792
+ const left = Math.abs(restPx[drag.axis] - nowPx[drag.axis]);
56766
56793
  trackAnimationRef.current?.cancel();
56767
56794
  trackAnimationRef.current = null;
56768
56795
  track.style.setProperty("--slide-container-offset", restOffset);
56769
- if (!durationMs || !pulled) {
56796
+ if (!durationMs || !left) {
56770
56797
  paintTravelProgress(0);
56771
56798
  settleTravel();
56772
56799
  return;
56773
56800
  }
56774
- animateTravelProgress(drag.progress, durationMs * (pulled / size), "ease-out", drag.areaPulled);
56801
+ // Which other slide the picture leans on while it arrives: the one being
56802
+ // pulled in when it comes back on the dragged slide, the dragged slide
56803
+ // itself when it goes on to the one arriving — and the trait is then a
56804
+ // box short of that one, which is what it has to close.
56805
+ const arrivesOnBase = area === drag.area;
56806
+ const sign = drag.pull[drag.axis] > 0 ? 1 : -1;
56807
+ const progressFrom = arrivesOnBase ? drag.progress : drag.progress - sign;
56808
+ const otherArea = arrivesOnBase ? drag.areaPulled : drag.area;
56809
+ movingRef.current = {
56810
+ from: otherArea,
56811
+ to: area
56812
+ };
56813
+ animateTravelProgress(progressFrom, durationMs * (left / size), "ease-out", otherArea);
56775
56814
  const animation = track.animate([{
56776
- translate: drag.offset
56815
+ translate: `${nowPx.x}px ${nowPx.y}px`
56777
56816
  }, {
56778
56817
  translate: restOffset
56779
56818
  }], {
56780
- duration: durationMs * (pulled / size),
56819
+ duration: durationMs * (left / size),
56781
56820
  easing: "ease-out"
56782
56821
  });
56783
56822
  trackAnimationRef.current = animation;
@@ -56808,11 +56847,14 @@ const SlideContainer = ({
56808
56847
  // value underneath it, which is the far end of the travel — the very jump
56809
56848
  // this is about.
56810
56849
  trackElement.style.setProperty("--slide-container-offset", offsetOnScreen);
56850
+ const moving = movingRef.current || {};
56811
56851
  return {
56812
56852
  trackElement,
56813
56853
  onScreenPx,
56814
56854
  offsetOnScreen,
56815
- offsetTarget: offsetRef.current
56855
+ offsetTarget: offsetRef.current,
56856
+ from: moving.from,
56857
+ to: moving.to
56816
56858
  };
56817
56859
  };
56818
56860
  // Which way a caught travel was going: a hand reaching for something moving
@@ -56859,8 +56901,6 @@ const SlideContainer = ({
56859
56901
  sign,
56860
56902
  target
56861
56903
  }) => {
56862
- let areaBack = axis === "x" ? areaTowards(-1, 0) : areaTowards(0, -1);
56863
- let areaOn = axis === "x" ? areaTowards(1, 0) : areaTowards(0, 1);
56864
56904
  // Everything positional is read HERE rather than when the pointer
56865
56905
  // landed: the travel that was playing then may have arrived since, and
56866
56906
  // it is what the slides are doing at the moment the gesture takes them
@@ -56871,39 +56911,66 @@ const SlideContainer = ({
56871
56911
  placeOf
56872
56912
  } = readMap();
56873
56913
  const currentElement = slideElements.find(slideElement => slideElement.hasAttribute("data-current")) || slideElements[0];
56874
- // The hold goToArea reads at the release, read again HERE, off the same
56875
- // slide and the same attribute: a slide that will refuse the arrival
56876
- // must not offer the journey. A locked direction simply has nowhere to
56877
- // go for the length of this gesture — the one case the gesture already
56878
- // knows, being the last slide of a walk. The hand then gets the wall it
56879
- // can lean on and never walk through (see drag_to_travel), the slide
56880
- // behind it stays offstage instead of being read on the way, and the
56881
- // release has nothing left to refuse.
56882
- // Nothing here about `released` (--navi-done): that is one particular
56883
- // departure letting go, decided as it happens, and a gesture armed
56884
- // before it has no such thing to read — the attribute as rendered is
56885
- // what the hand is answered from.
56886
- if (currentElement?.hasAttribute("data-prevent-nav-previous")) {
56887
- areaBack = undefined;
56888
- }
56889
- if (currentElement?.hasAttribute("data-prevent-nav-next")) {
56890
- areaOn = undefined;
56891
- }
56892
56914
  const box = track.getBoundingClientRect();
56893
- if (!areaBack && !areaOn || !currentElement || !box.width || !box.height ||
56894
- // Something else with a better claim on the gesture: a scroller
56895
- // between the finger and the slide, with room left that way.
56896
- scrollRoomTowards(target, currentElement, axis, sign)) {
56915
+ if (!currentElement || !box.width || !box.height) {
56897
56916
  return false;
56898
56917
  }
56899
- const area = readArea(currentElement);
56900
- // Where the slide being dragged stands: where the stage put it while a
56901
- // travel is playing, its place on the map otherwise.
56918
+ const currentArea = readArea(currentElement);
56902
56919
  const stage = stageRef.current;
56903
- const basePlace = stage?.placeByArea.get(area) || placeOf.get(area) || {
56920
+ // Where a slide stands: where the stage put it while a travel is
56921
+ // playing, its place on the map otherwise.
56922
+ const placeOfArea = someArea => stage?.placeByArea.get(someArea) || placeOf.get(someArea) || {
56904
56923
  x: 0,
56905
56924
  y: 0
56906
56925
  };
56926
+ // A travel caught in flight is measured from the slide it SET OFF from,
56927
+ // with the slide it was going to as the one thing the hand can bring
56928
+ // in — the way drag_to_travel reads a `slack`: how far the box already
56929
+ // sits from its resting place, towards what is being pulled in. That is
56930
+ // what makes its answer "carry on" mean arriving. Based on the slide
56931
+ // arriving instead, the slack would point back at the origin, and a
56932
+ // hand that merely touched the box would send it all the way back.
56933
+ // A movement with no origin of its own (the track re-placed without a
56934
+ // travel) is dragged from the slide shown, like any slide at rest.
56935
+ const origin = caughtTravel && caughtTravel.from !== caughtTravel.to ? caughtTravel.from : null;
56936
+ let area;
56937
+ let areaBack;
56938
+ let areaOn;
56939
+ if (origin) {
56940
+ area = origin;
56941
+ const towardsEnd = axis === "x" ? placeOfArea(currentArea).x > placeOfArea(origin).x : placeOfArea(currentArea).y > placeOfArea(origin).y;
56942
+ areaBack = towardsEnd ? undefined : currentArea;
56943
+ areaOn = towardsEnd ? currentArea : undefined;
56944
+ } else {
56945
+ area = currentArea;
56946
+ areaBack = axis === "x" ? areaTowards(-1, 0) : areaTowards(0, -1);
56947
+ areaOn = axis === "x" ? areaTowards(1, 0) : areaTowards(0, 1);
56948
+ // The hold goToArea reads at the release, read again HERE, off the
56949
+ // same slide and the same attribute: a slide that will refuse the
56950
+ // arrival must not offer the journey. A locked direction simply has
56951
+ // nowhere to go for the length of this gesture — the one case the
56952
+ // gesture already knows, being the last slide of a walk. The hand
56953
+ // then gets the wall it can lean on and never walk through (see
56954
+ // drag_to_travel), the slide behind it stays offstage instead of
56955
+ // being read on the way, and the release has nothing left to refuse.
56956
+ // Nothing here about `released` (--navi-done): that is one particular
56957
+ // departure letting go, decided as it happens, and a gesture armed
56958
+ // before it has no such thing to read — the attribute as rendered is
56959
+ // what the hand is answered from.
56960
+ if (currentElement.hasAttribute("data-prevent-nav-previous")) {
56961
+ areaBack = undefined;
56962
+ }
56963
+ if (currentElement.hasAttribute("data-prevent-nav-next")) {
56964
+ areaOn = undefined;
56965
+ }
56966
+ if (!areaBack && !areaOn ||
56967
+ // Something else with a better claim on the gesture: a scroller
56968
+ // between the finger and the slide, with room left that way.
56969
+ scrollRoomTowards(target, currentElement, axis, sign)) {
56970
+ return false;
56971
+ }
56972
+ }
56973
+ const basePlace = placeOfArea(area);
56907
56974
  const baseOffset = {
56908
56975
  x: -basePlace.x * box.width,
56909
56976
  y: -basePlace.y * box.height
@@ -56934,7 +57001,8 @@ const SlideContainer = ({
56934
57001
  [axis]: slack
56935
57002
  };
56936
57003
  drag.progress = slack / size;
56937
- stageDrag(drag);
57004
+ drag.areaPulled = slack > 0 ? areaBack : slack < 0 ? areaOn : null;
57005
+ stageDrag(drag, currentArea);
56938
57006
  // From here the box is busy, whichever input asked: a wheel gesture and
56939
57007
  // a press must not both be moving the same track.
56940
57008
  dragRef.current = drag;
@@ -56965,24 +57033,50 @@ const SlideContainer = ({
56965
57033
  event
56966
57034
  }) => {
56967
57035
  dragRef.current = null;
56968
- if (!travels) {
56969
- returnToRest(drag);
57036
+ // Where the gesture leaves the slides: on the one it was pulling in
57037
+ // when it says so, back on the one it was dragging otherwise.
57038
+ const destination = travels ? sign > 0 ? drag.areaBack : drag.areaOn : drag.area;
57039
+ const {
57040
+ slideElements,
57041
+ placeOf
57042
+ } = readMap();
57043
+ const currentElement = slideElements.find(slideElement => slideElement.hasAttribute("data-current")) || slideElements[0];
57044
+ const currentArea = currentElement && readArea(currentElement);
57045
+ if (!destination || destination === currentArea) {
57046
+ // Nothing to ask of the state: the slide it names is already the one
57047
+ // shown — a drag let go of short of a travel, a travel caught in
57048
+ // flight and let carry on. The track goes there on its own.
57049
+ settleTowards(drag, destination || drag.area);
56970
57050
  return;
56971
57051
  }
56972
57052
  // Where the slide is being left, for the travel to depart from instead
56973
57053
  // of from the map.
56974
57054
  travelFromRef.current = drag.offset;
56975
57055
  // …and where the indicator is being left, said about the slide that is
56976
- // ARRIVING: the picture is `sign` of a box short of it, and that is
56977
- // what the travel about to be drawn has to close.
56978
- travelProgressFromRef.current = drag.progress - sign;
56979
- const moved = axis === "x" ? move(-sign, 0, event) : move(0, -sign, event);
57056
+ // ARRIVING: a box short of the slide being pulled in, right where the
57057
+ // finger left it when going back to the slide being dragged.
57058
+ travelProgressFromRef.current = travels ? drag.progress - sign : drag.progress;
57059
+ // Which way the travel goes, read off where the two slides stand
57060
+ // rather than off the pull: a travel caught in flight and put back
57061
+ // goes the way it came, whatever the finger did meanwhile.
57062
+ const stage = stageRef.current;
57063
+ const placeOfArea = someArea => stage?.placeByArea.get(someArea) || placeOf.get(someArea) || {
57064
+ x: 0,
57065
+ y: 0
57066
+ };
57067
+ const towards = Math.sign(placeOfArea(destination)[axis] - placeOfArea(currentArea)[axis]);
57068
+ const moved = goToArea(destination, {
57069
+ forward: towards > 0,
57070
+ event,
57071
+ dx: axis === "x" ? towards : 0,
57072
+ dy: axis === "y" ? towards : 0
57073
+ });
56980
57074
  if (!moved) {
56981
57075
  // Nowhere to go after all — a slide holding on to the user
56982
57076
  // (preventNav), or a caller that refused the change.
56983
57077
  travelFromRef.current = null;
56984
57078
  travelProgressFromRef.current = null;
56985
- returnToRest(drag);
57079
+ settleTowards(drag, currentArea);
56986
57080
  return;
56987
57081
  }
56988
57082
  // A container whose `current` is held outside and was not moved: no
@@ -56993,7 +57087,7 @@ const SlideContainer = ({
56993
57087
  if (travelFromRef.current) {
56994
57088
  travelFromRef.current = null;
56995
57089
  travelProgressFromRef.current = null;
56996
- returnToRest(drag);
57090
+ settleTowards(drag, currentArea);
56997
57091
  }
56998
57092
  });
56999
57093
  },
@@ -57008,9 +57102,15 @@ const SlideContainer = ({
57008
57102
  trackElement: trackCaught,
57009
57103
  offsetOnScreen,
57010
57104
  offsetTarget,
57011
- onScreenPx: caughtOnScreenPx
57105
+ onScreenPx: caughtOnScreenPx,
57106
+ from,
57107
+ to
57012
57108
  } = caughtTravel;
57013
57109
  caughtTravel = null;
57110
+ movingRef.current = {
57111
+ from,
57112
+ to
57113
+ };
57014
57114
  if (offsetOnScreen === offsetTarget) {
57015
57115
  settleTravel();
57016
57116
  return;