@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.
@@ -56555,6 +56555,10 @@ const SlideContainer = ({
56555
56555
  // one being travelled TO while the track moves. What the next travel departs
56556
56556
  // from, because it is what one is looking at.
56557
56557
  const drawnAreaRef = useRef(undefined);
56558
+ // The movement the track is playing, while it plays: the slide it is leaving
56559
+ // and the slide it is going to. A hand landing on the box takes it over from
56560
+ // its origin (see onStart in createTravelHandlers).
56561
+ const movingRef = useRef(null);
56558
56562
  // Which way the travel about to be drawn goes, when whatever asked for it
56559
56563
  // knows: a window stepping off its last slide comes back on its first, and
56560
56564
  // only the press says that is a step forward — the map, read between those
@@ -56823,6 +56827,7 @@ const SlideContainer = ({
56823
56827
  }
56824
56828
  stageRef.current = null;
56825
56829
  trackAnimationRef.current = null;
56830
+ movingRef.current = null;
56826
56831
  // At rest the picture IS the current slide, whatever the last gesture wrote
56827
56832
  // there: an indicator has nothing left to lean towards.
56828
56833
  paintTravelProgress(0);
@@ -57017,7 +57022,7 @@ const SlideContainer = ({
57017
57022
  // there, and when it is over this is what holds. Except under a hand-off
57018
57023
  // still waiting for its travel: the track stays where the finger left it,
57019
57024
  // until the render that moves it or the frame after which the gesture gives
57020
- // up on it (see returnToRest in onEnd).
57025
+ // up on it (see settleTowards in onEnd).
57021
57026
  if (!travelFromRef.current) {
57022
57027
  track.style.setProperty("--slide-container-offset", offset);
57023
57028
  }
@@ -57052,6 +57057,10 @@ const SlideContainer = ({
57052
57057
  duration: durationMs * travelRatio,
57053
57058
  easing
57054
57059
  });
57060
+ movingRef.current = {
57061
+ from: drawnArea,
57062
+ to: currentArea
57063
+ };
57055
57064
  // The trait travels with the slides: from where the gesture left it when
57056
57065
  // there was one, from a whole box away when the travel was asked for.
57057
57066
  const progressFrom = travelProgressFromRef.current ?? (travelStep ? travelStep.x || travelStep.y : 0);
@@ -57837,7 +57846,7 @@ const SlideContainer = ({
57837
57846
  // The two slides the gesture can bring in, placed one box either side of the
57838
57847
  // one being dragged — the same stage a travel builds, except that both ends
57839
57848
  // are set up at once because the finger has not said yet which way it goes.
57840
- const stageDrag = drag => {
57849
+ const stageDrag = (drag, currentArea) => {
57841
57850
  const {
57842
57851
  slideElements,
57843
57852
  placeOf
@@ -57865,7 +57874,7 @@ const SlideContainer = ({
57865
57874
  }
57866
57875
  stageRef.current = {
57867
57876
  placeByArea,
57868
- area: drag.area
57877
+ area: currentArea
57869
57878
  };
57870
57879
  for (const slideElement of slideElements) {
57871
57880
  const area = readArea(slideElement);
@@ -57881,33 +57890,63 @@ const SlideContainer = ({
57881
57890
  }
57882
57891
  };
57883
57892
 
57884
- // Let go of without enough of a gesture to travel: the slide comes back to
57885
- // where it was, over the distance it was pulled so a slide barely moved
57886
- // snaps back and one dragged most of the way there takes its time.
57887
- const returnToRest = drag => {
57893
+ // Let go of, and the slides go where the gesture leaves them: back on the
57894
+ // slide being dragged when nothing travels, on to the slide arriving when a
57895
+ // travel caught in flight is let carry on. Over the distance left to cover,
57896
+ // so a slide barely moved snaps back and one dragged most of the way there
57897
+ // takes its time.
57898
+ const settleTowards = (drag, area) => {
57888
57899
  const track = trackRef.current;
57889
57900
  if (!track) {
57890
57901
  return;
57891
57902
  }
57892
- const restOffset = `${drag.baseOffset.x}px ${drag.baseOffset.y}px`;
57903
+ const stage = stageRef.current;
57904
+ const {
57905
+ placeOf
57906
+ } = readMap();
57907
+ const place = stage?.placeByArea.get(area) || placeOf.get(area) || {
57908
+ x: 0,
57909
+ y: 0
57910
+ };
57911
+ const restPx = {
57912
+ x: -place.x * drag.box.width,
57913
+ y: -place.y * drag.box.height
57914
+ };
57915
+ const nowPx = {
57916
+ x: drag.baseOffset.x + drag.pull.x,
57917
+ y: drag.baseOffset.y + drag.pull.y
57918
+ };
57919
+ const restOffset = `${restPx.x}px ${restPx.y}px`;
57893
57920
  const durationMs = durationToMs(duration);
57894
- const pulled = Math.abs(drag.pull[drag.axis]);
57895
57921
  const size = drag.axis === "x" ? drag.box.width : drag.box.height;
57922
+ const left = Math.abs(restPx[drag.axis] - nowPx[drag.axis]);
57896
57923
  trackAnimationRef.current?.cancel();
57897
57924
  trackAnimationRef.current = null;
57898
57925
  track.style.setProperty("--slide-container-offset", restOffset);
57899
- if (!durationMs || !pulled) {
57926
+ if (!durationMs || !left) {
57900
57927
  paintTravelProgress(0);
57901
57928
  settleTravel();
57902
57929
  return;
57903
57930
  }
57904
- animateTravelProgress(drag.progress, durationMs * (pulled / size), "ease-out", drag.areaPulled);
57931
+ // Which other slide the picture leans on while it arrives: the one being
57932
+ // pulled in when it comes back on the dragged slide, the dragged slide
57933
+ // itself when it goes on to the one arriving — and the trait is then a
57934
+ // box short of that one, which is what it has to close.
57935
+ const arrivesOnBase = area === drag.area;
57936
+ const sign = drag.pull[drag.axis] > 0 ? 1 : -1;
57937
+ const progressFrom = arrivesOnBase ? drag.progress : drag.progress - sign;
57938
+ const otherArea = arrivesOnBase ? drag.areaPulled : drag.area;
57939
+ movingRef.current = {
57940
+ from: otherArea,
57941
+ to: area
57942
+ };
57943
+ animateTravelProgress(progressFrom, durationMs * (left / size), "ease-out", otherArea);
57905
57944
  const animation = track.animate([{
57906
- translate: drag.offset
57945
+ translate: `${nowPx.x}px ${nowPx.y}px`
57907
57946
  }, {
57908
57947
  translate: restOffset
57909
57948
  }], {
57910
- duration: durationMs * (pulled / size),
57949
+ duration: durationMs * (left / size),
57911
57950
  easing: "ease-out"
57912
57951
  });
57913
57952
  trackAnimationRef.current = animation;
@@ -57938,11 +57977,14 @@ const SlideContainer = ({
57938
57977
  // value underneath it, which is the far end of the travel — the very jump
57939
57978
  // this is about.
57940
57979
  trackElement.style.setProperty("--slide-container-offset", offsetOnScreen);
57980
+ const moving = movingRef.current || {};
57941
57981
  return {
57942
57982
  trackElement,
57943
57983
  onScreenPx,
57944
57984
  offsetOnScreen,
57945
- offsetTarget: offsetRef.current
57985
+ offsetTarget: offsetRef.current,
57986
+ from: moving.from,
57987
+ to: moving.to
57946
57988
  };
57947
57989
  };
57948
57990
  // Which way a caught travel was going: a hand reaching for something moving
@@ -57989,8 +58031,6 @@ const SlideContainer = ({
57989
58031
  sign,
57990
58032
  target
57991
58033
  }) => {
57992
- let areaBack = axis === "x" ? areaTowards(-1, 0) : areaTowards(0, -1);
57993
- let areaOn = axis === "x" ? areaTowards(1, 0) : areaTowards(0, 1);
57994
58034
  // Everything positional is read HERE rather than when the pointer
57995
58035
  // landed: the travel that was playing then may have arrived since, and
57996
58036
  // it is what the slides are doing at the moment the gesture takes them
@@ -58001,39 +58041,66 @@ const SlideContainer = ({
58001
58041
  placeOf
58002
58042
  } = readMap();
58003
58043
  const currentElement = slideElements.find(slideElement => slideElement.hasAttribute("data-current")) || slideElements[0];
58004
- // The hold goToArea reads at the release, read again HERE, off the same
58005
- // slide and the same attribute: a slide that will refuse the arrival
58006
- // must not offer the journey. A locked direction simply has nowhere to
58007
- // go for the length of this gesture — the one case the gesture already
58008
- // knows, being the last slide of a walk. The hand then gets the wall it
58009
- // can lean on and never walk through (see drag_to_travel), the slide
58010
- // behind it stays offstage instead of being read on the way, and the
58011
- // release has nothing left to refuse.
58012
- // Nothing here about `released` (--navi-done): that is one particular
58013
- // departure letting go, decided as it happens, and a gesture armed
58014
- // before it has no such thing to read — the attribute as rendered is
58015
- // what the hand is answered from.
58016
- if (currentElement?.hasAttribute("data-prevent-nav-previous")) {
58017
- areaBack = undefined;
58018
- }
58019
- if (currentElement?.hasAttribute("data-prevent-nav-next")) {
58020
- areaOn = undefined;
58021
- }
58022
58044
  const box = track.getBoundingClientRect();
58023
- if (!areaBack && !areaOn || !currentElement || !box.width || !box.height ||
58024
- // Something else with a better claim on the gesture: a scroller
58025
- // between the finger and the slide, with room left that way.
58026
- scrollRoomTowards(target, currentElement, axis, sign)) {
58045
+ if (!currentElement || !box.width || !box.height) {
58027
58046
  return false;
58028
58047
  }
58029
- const area = readArea(currentElement);
58030
- // Where the slide being dragged stands: where the stage put it while a
58031
- // travel is playing, its place on the map otherwise.
58048
+ const currentArea = readArea(currentElement);
58032
58049
  const stage = stageRef.current;
58033
- const basePlace = stage?.placeByArea.get(area) || placeOf.get(area) || {
58050
+ // Where a slide stands: where the stage put it while a travel is
58051
+ // playing, its place on the map otherwise.
58052
+ const placeOfArea = someArea => stage?.placeByArea.get(someArea) || placeOf.get(someArea) || {
58034
58053
  x: 0,
58035
58054
  y: 0
58036
58055
  };
58056
+ // A travel caught in flight is measured from the slide it SET OFF from,
58057
+ // with the slide it was going to as the one thing the hand can bring
58058
+ // in — the way drag_to_travel reads a `slack`: how far the box already
58059
+ // sits from its resting place, towards what is being pulled in. That is
58060
+ // what makes its answer "carry on" mean arriving. Based on the slide
58061
+ // arriving instead, the slack would point back at the origin, and a
58062
+ // hand that merely touched the box would send it all the way back.
58063
+ // A movement with no origin of its own (the track re-placed without a
58064
+ // travel) is dragged from the slide shown, like any slide at rest.
58065
+ const origin = caughtTravel && caughtTravel.from !== caughtTravel.to ? caughtTravel.from : null;
58066
+ let area;
58067
+ let areaBack;
58068
+ let areaOn;
58069
+ if (origin) {
58070
+ area = origin;
58071
+ const towardsEnd = axis === "x" ? placeOfArea(currentArea).x > placeOfArea(origin).x : placeOfArea(currentArea).y > placeOfArea(origin).y;
58072
+ areaBack = towardsEnd ? undefined : currentArea;
58073
+ areaOn = towardsEnd ? currentArea : undefined;
58074
+ } else {
58075
+ area = currentArea;
58076
+ areaBack = axis === "x" ? areaTowards(-1, 0) : areaTowards(0, -1);
58077
+ areaOn = axis === "x" ? areaTowards(1, 0) : areaTowards(0, 1);
58078
+ // The hold goToArea reads at the release, read again HERE, off the
58079
+ // same slide and the same attribute: a slide that will refuse the
58080
+ // arrival must not offer the journey. A locked direction simply has
58081
+ // nowhere to go for the length of this gesture — the one case the
58082
+ // gesture already knows, being the last slide of a walk. The hand
58083
+ // then gets the wall it can lean on and never walk through (see
58084
+ // drag_to_travel), the slide behind it stays offstage instead of
58085
+ // being read on the way, and the release has nothing left to refuse.
58086
+ // Nothing here about `released` (--navi-done): that is one particular
58087
+ // departure letting go, decided as it happens, and a gesture armed
58088
+ // before it has no such thing to read — the attribute as rendered is
58089
+ // what the hand is answered from.
58090
+ if (currentElement.hasAttribute("data-prevent-nav-previous")) {
58091
+ areaBack = undefined;
58092
+ }
58093
+ if (currentElement.hasAttribute("data-prevent-nav-next")) {
58094
+ areaOn = undefined;
58095
+ }
58096
+ if (!areaBack && !areaOn ||
58097
+ // Something else with a better claim on the gesture: a scroller
58098
+ // between the finger and the slide, with room left that way.
58099
+ scrollRoomTowards(target, currentElement, axis, sign)) {
58100
+ return false;
58101
+ }
58102
+ }
58103
+ const basePlace = placeOfArea(area);
58037
58104
  const baseOffset = {
58038
58105
  x: -basePlace.x * box.width,
58039
58106
  y: -basePlace.y * box.height
@@ -58064,7 +58131,8 @@ const SlideContainer = ({
58064
58131
  [axis]: slack
58065
58132
  };
58066
58133
  drag.progress = slack / size;
58067
- stageDrag(drag);
58134
+ drag.areaPulled = slack > 0 ? areaBack : slack < 0 ? areaOn : null;
58135
+ stageDrag(drag, currentArea);
58068
58136
  // From here the box is busy, whichever input asked: a wheel gesture and
58069
58137
  // a press must not both be moving the same track.
58070
58138
  dragRef.current = drag;
@@ -58095,24 +58163,50 @@ const SlideContainer = ({
58095
58163
  event
58096
58164
  }) => {
58097
58165
  dragRef.current = null;
58098
- if (!travels) {
58099
- returnToRest(drag);
58166
+ // Where the gesture leaves the slides: on the one it was pulling in
58167
+ // when it says so, back on the one it was dragging otherwise.
58168
+ const destination = travels ? sign > 0 ? drag.areaBack : drag.areaOn : drag.area;
58169
+ const {
58170
+ slideElements,
58171
+ placeOf
58172
+ } = readMap();
58173
+ const currentElement = slideElements.find(slideElement => slideElement.hasAttribute("data-current")) || slideElements[0];
58174
+ const currentArea = currentElement && readArea(currentElement);
58175
+ if (!destination || destination === currentArea) {
58176
+ // Nothing to ask of the state: the slide it names is already the one
58177
+ // shown — a drag let go of short of a travel, a travel caught in
58178
+ // flight and let carry on. The track goes there on its own.
58179
+ settleTowards(drag, destination || drag.area);
58100
58180
  return;
58101
58181
  }
58102
58182
  // Where the slide is being left, for the travel to depart from instead
58103
58183
  // of from the map.
58104
58184
  travelFromRef.current = drag.offset;
58105
58185
  // …and where the indicator is being left, said about the slide that is
58106
- // ARRIVING: the picture is `sign` of a box short of it, and that is
58107
- // what the travel about to be drawn has to close.
58108
- travelProgressFromRef.current = drag.progress - sign;
58109
- const moved = axis === "x" ? move(-sign, 0, event) : move(0, -sign, event);
58186
+ // ARRIVING: a box short of the slide being pulled in, right where the
58187
+ // finger left it when going back to the slide being dragged.
58188
+ travelProgressFromRef.current = travels ? drag.progress - sign : drag.progress;
58189
+ // Which way the travel goes, read off where the two slides stand
58190
+ // rather than off the pull: a travel caught in flight and put back
58191
+ // goes the way it came, whatever the finger did meanwhile.
58192
+ const stage = stageRef.current;
58193
+ const placeOfArea = someArea => stage?.placeByArea.get(someArea) || placeOf.get(someArea) || {
58194
+ x: 0,
58195
+ y: 0
58196
+ };
58197
+ const towards = Math.sign(placeOfArea(destination)[axis] - placeOfArea(currentArea)[axis]);
58198
+ const moved = goToArea(destination, {
58199
+ forward: towards > 0,
58200
+ event,
58201
+ dx: axis === "x" ? towards : 0,
58202
+ dy: axis === "y" ? towards : 0
58203
+ });
58110
58204
  if (!moved) {
58111
58205
  // Nowhere to go after all — a slide holding on to the user
58112
58206
  // (preventNav), or a caller that refused the change.
58113
58207
  travelFromRef.current = null;
58114
58208
  travelProgressFromRef.current = null;
58115
- returnToRest(drag);
58209
+ settleTowards(drag, currentArea);
58116
58210
  return;
58117
58211
  }
58118
58212
  // A container whose `current` is held outside and was not moved: no
@@ -58123,7 +58217,7 @@ const SlideContainer = ({
58123
58217
  if (travelFromRef.current) {
58124
58218
  travelFromRef.current = null;
58125
58219
  travelProgressFromRef.current = null;
58126
- returnToRest(drag);
58220
+ settleTowards(drag, currentArea);
58127
58221
  }
58128
58222
  });
58129
58223
  },
@@ -58138,9 +58232,15 @@ const SlideContainer = ({
58138
58232
  trackElement: trackCaught,
58139
58233
  offsetOnScreen,
58140
58234
  offsetTarget,
58141
- onScreenPx: caughtOnScreenPx
58235
+ onScreenPx: caughtOnScreenPx,
58236
+ from,
58237
+ to
58142
58238
  } = caughtTravel;
58143
58239
  caughtTravel = null;
58240
+ movingRef.current = {
58241
+ from,
58242
+ to
58243
+ };
58144
58244
  if (offsetOnScreen === offsetTarget) {
58145
58245
  settleTravel();
58146
58246
  return;