@jsenv/navi 0.29.362 → 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.
- package/dist/dev/jsenv_navi.js +191 -92
- package/dist/dev/jsenv_navi.js.map +13 -11
- package/dist/jsenv_navi.js +191 -92
- package/dist/jsenv_navi.js.map +13 -11
- package/docs/popup_open.md +2 -1
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -9248,6 +9248,17 @@ const naviI18nFromValidityMessage = ({ key, params }) => {
|
|
|
9248
9248
|
return naviI18n(`constraint.${key}`, params);
|
|
9249
9249
|
};
|
|
9250
9250
|
|
|
9251
|
+
// The characters a ui state holds, for the rules that read a value as text
|
|
9252
|
+
// (length, pattern, number, email…). `undefined` and `null` both hold none:
|
|
9253
|
+
// `String(null)` would hand those rules the four letters "null" — a number
|
|
9254
|
+
// field cleared with `value={null}` then reported "must be a number".
|
|
9255
|
+
const uiStateAsText = (uiState) => {
|
|
9256
|
+
if (uiState === undefined || uiState === null) {
|
|
9257
|
+
return "";
|
|
9258
|
+
}
|
|
9259
|
+
return String(uiState);
|
|
9260
|
+
};
|
|
9261
|
+
|
|
9251
9262
|
/**
|
|
9252
9263
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation
|
|
9253
9264
|
*/
|
|
@@ -9314,8 +9325,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
9314
9325
|
return naviI18n("constraint.required.checkbox");
|
|
9315
9326
|
}
|
|
9316
9327
|
|
|
9317
|
-
const valueAsString =
|
|
9318
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9328
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9319
9329
|
if (valueAsString) {
|
|
9320
9330
|
return null;
|
|
9321
9331
|
}
|
|
@@ -9366,8 +9376,7 @@ const PATTERN_CONSTRAINT = {
|
|
|
9366
9376
|
if (!pattern) {
|
|
9367
9377
|
return null;
|
|
9368
9378
|
}
|
|
9369
|
-
const valueAsString =
|
|
9370
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9379
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9371
9380
|
if (!valueAsString) {
|
|
9372
9381
|
return null;
|
|
9373
9382
|
}
|
|
@@ -9402,8 +9411,7 @@ const TYPE_EMAIL_CONSTRAINT = {
|
|
|
9402
9411
|
if (type !== "email") {
|
|
9403
9412
|
return null;
|
|
9404
9413
|
}
|
|
9405
|
-
const valueAsString =
|
|
9406
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9414
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9407
9415
|
if (!valueAsString) {
|
|
9408
9416
|
return null;
|
|
9409
9417
|
}
|
|
@@ -9436,8 +9444,7 @@ const MIN_LENGTH_CONSTRAINT = {
|
|
|
9436
9444
|
if (minLength === undefined) {
|
|
9437
9445
|
return null;
|
|
9438
9446
|
}
|
|
9439
|
-
const valueAsString =
|
|
9440
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9447
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9441
9448
|
if (!valueAsString && !field.controlHostProps.required) {
|
|
9442
9449
|
return null;
|
|
9443
9450
|
}
|
|
@@ -9532,8 +9539,7 @@ const MAX_LENGTH_CONSTRAINT = {
|
|
|
9532
9539
|
if (maxLength === undefined) {
|
|
9533
9540
|
return null;
|
|
9534
9541
|
}
|
|
9535
|
-
const valueAsString =
|
|
9536
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9542
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9537
9543
|
if (!valueAsString) {
|
|
9538
9544
|
return null;
|
|
9539
9545
|
}
|
|
@@ -9574,8 +9580,7 @@ const TYPE_NUMBER_CONSTRAINT = {
|
|
|
9574
9580
|
if (!isNumberInput(type, naviType)) {
|
|
9575
9581
|
return null;
|
|
9576
9582
|
}
|
|
9577
|
-
const valueAsString =
|
|
9578
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9583
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9579
9584
|
if (!valueAsString) {
|
|
9580
9585
|
return null;
|
|
9581
9586
|
}
|
|
@@ -9640,8 +9645,7 @@ const MIN_CONSTRAINT = {
|
|
|
9640
9645
|
}
|
|
9641
9646
|
const type = field.controlHostProps.type;
|
|
9642
9647
|
const naviInputType = field.controlHostProps["navi-input-type"];
|
|
9643
|
-
const valueAsString =
|
|
9644
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9648
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9645
9649
|
if (!valueAsString) {
|
|
9646
9650
|
return null;
|
|
9647
9651
|
}
|
|
@@ -9740,8 +9744,7 @@ const MAX_CONSTRAINT = {
|
|
|
9740
9744
|
}
|
|
9741
9745
|
const type = field.controlHostProps.type;
|
|
9742
9746
|
const naviInputType = field.controlHostProps["navi-input-type"];
|
|
9743
|
-
const valueAsString =
|
|
9744
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9747
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9745
9748
|
if (!valueAsString) {
|
|
9746
9749
|
return null;
|
|
9747
9750
|
}
|
|
@@ -9874,8 +9877,7 @@ const STEP_CONSTRAINT = {
|
|
|
9874
9877
|
return null;
|
|
9875
9878
|
}
|
|
9876
9879
|
const stepString = String(stepRaw);
|
|
9877
|
-
const valueAsString =
|
|
9878
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9880
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9879
9881
|
if (!valueAsString) {
|
|
9880
9882
|
return null;
|
|
9881
9883
|
}
|
|
@@ -12824,8 +12826,7 @@ const DISPLAYABLE_CONSTRAINT = {
|
|
|
12824
12826
|
if (!isConstraintAttributeOn(displayable)) {
|
|
12825
12827
|
return null;
|
|
12826
12828
|
}
|
|
12827
|
-
const valueAsString =
|
|
12828
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12829
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12829
12830
|
const maxStackedMarksAttribute =
|
|
12830
12831
|
field.controlHostProps["data-max-stacked-marks"];
|
|
12831
12832
|
const result = DISPLAYABLE_RULE.applyOn(true, valueAsString, {
|
|
@@ -12866,8 +12867,7 @@ const MAX_LINE_BREAKS_CONSTRAINT = {
|
|
|
12866
12867
|
if (isNaN(maxLineBreaks)) {
|
|
12867
12868
|
return null;
|
|
12868
12869
|
}
|
|
12869
|
-
const valueAsString =
|
|
12870
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12870
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12871
12871
|
const result = MAX_LINE_BREAKS_RULE.applyOn(maxLineBreaks, valueAsString);
|
|
12872
12872
|
if (!result) {
|
|
12873
12873
|
return null;
|
|
@@ -12896,8 +12896,7 @@ const NO_EMOJI_CONSTRAINT = {
|
|
|
12896
12896
|
if (!isConstraintAttributeOn(noEmoji)) {
|
|
12897
12897
|
return null;
|
|
12898
12898
|
}
|
|
12899
|
-
const valueAsString =
|
|
12900
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12899
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12901
12900
|
const result = NO_EMOJI_RULE.applyOn(true, valueAsString);
|
|
12902
12901
|
if (!result) {
|
|
12903
12902
|
return null;
|
|
@@ -12911,8 +12910,7 @@ const MIN_LOWER_LETTER_CONSTRAINT = {
|
|
|
12911
12910
|
name: "min_lower_letter",
|
|
12912
12911
|
messageAttribute: "data-min-lower-letter-message",
|
|
12913
12912
|
check: (field) => {
|
|
12914
|
-
const valueAsString =
|
|
12915
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12913
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12916
12914
|
const required = field.controlHostProps.required;
|
|
12917
12915
|
if (!valueAsString && !required) {
|
|
12918
12916
|
return "";
|
|
@@ -12957,8 +12955,7 @@ const MIN_UPPER_LETTER_CONSTRAINT = {
|
|
|
12957
12955
|
name: "min_upper_letter",
|
|
12958
12956
|
messageAttribute: "data-min-upper-letter-message",
|
|
12959
12957
|
check: (field) => {
|
|
12960
|
-
const valueAsString =
|
|
12961
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12958
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12962
12959
|
const required = field.controlHostProps.required;
|
|
12963
12960
|
if (!valueAsString && !required) {
|
|
12964
12961
|
return null;
|
|
@@ -12994,8 +12991,7 @@ const MIN_DIGIT_CONSTRAINT = {
|
|
|
12994
12991
|
name: "min_digit",
|
|
12995
12992
|
messageAttribute: "data-min-digit-message",
|
|
12996
12993
|
check: (field) => {
|
|
12997
|
-
const valueAsString =
|
|
12998
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12994
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12999
12995
|
const required = field.controlHostProps.required;
|
|
13000
12996
|
if (!valueAsString && !required) {
|
|
13001
12997
|
return null;
|
|
@@ -13031,8 +13027,7 @@ const MIN_SPECIAL_CHAR_CONSTRAINT = {
|
|
|
13031
13027
|
name: "min_special_char",
|
|
13032
13028
|
messageAttribute: "data-min-special-char-message",
|
|
13033
13029
|
check: (field) => {
|
|
13034
|
-
const valueAsString =
|
|
13035
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
13030
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
13036
13031
|
const required = field.controlHostProps.required;
|
|
13037
13032
|
if (!valueAsString && !required) {
|
|
13038
13033
|
return null;
|
|
@@ -13149,8 +13144,7 @@ const SAME_AS_CONSTRAINT = {
|
|
|
13149
13144
|
// Reference field is empty — nothing to compare against yet.
|
|
13150
13145
|
return null;
|
|
13151
13146
|
}
|
|
13152
|
-
const valueAsString =
|
|
13153
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
13147
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
13154
13148
|
if (valueAsString === otherFieldValue) {
|
|
13155
13149
|
return null;
|
|
13156
13150
|
}
|
|
@@ -13191,8 +13185,7 @@ CONSTRAINT_ATTRIBUTE_SET.add("data-same-as");
|
|
|
13191
13185
|
|
|
13192
13186
|
|
|
13193
13187
|
const applyRule = (field) => {
|
|
13194
|
-
const valueAsString =
|
|
13195
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
13188
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
13196
13189
|
return SINGLE_SPACE_RULE.applyOn(true, valueAsString);
|
|
13197
13190
|
};
|
|
13198
13191
|
|
|
@@ -37479,9 +37472,9 @@ const getInvalidCharsMessage = (
|
|
|
37479
37472
|
uiState,
|
|
37480
37473
|
{ charClass, messageKey, uiStateNow },
|
|
37481
37474
|
) => {
|
|
37482
|
-
const str =
|
|
37475
|
+
const str = uiStateAsText(uiState);
|
|
37483
37476
|
if (compileCharClassAnchored(charClass).test(str)) return null;
|
|
37484
|
-
const strNow =
|
|
37477
|
+
const strNow = uiStateAsText(uiStateNow);
|
|
37485
37478
|
if (
|
|
37486
37479
|
countCharsOutsideClass(str, charClass) <=
|
|
37487
37480
|
countCharsOutsideClass(strNow, charClass)
|
|
@@ -37494,9 +37487,9 @@ const getInvalidCharsMessage = (
|
|
|
37494
37487
|
// Paste / set: truncate what the gesture adds beyond the limit.
|
|
37495
37488
|
const getLengthOverflowResult = (uiState, { maxLength, uiStateNow }) => {
|
|
37496
37489
|
if (maxLength === undefined) return null;
|
|
37497
|
-
const str =
|
|
37490
|
+
const str = uiStateAsText(uiState);
|
|
37498
37491
|
if (str.length <= maxLength) return null;
|
|
37499
|
-
const strNow =
|
|
37492
|
+
const strNow = uiStateAsText(uiStateNow);
|
|
37500
37493
|
if (str.length <= strNow.length) return null;
|
|
37501
37494
|
return {
|
|
37502
37495
|
fixedValue: str.slice(0, maxLength),
|
|
@@ -56562,6 +56555,10 @@ const SlideContainer = ({
|
|
|
56562
56555
|
// one being travelled TO while the track moves. What the next travel departs
|
|
56563
56556
|
// from, because it is what one is looking at.
|
|
56564
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);
|
|
56565
56562
|
// Which way the travel about to be drawn goes, when whatever asked for it
|
|
56566
56563
|
// knows: a window stepping off its last slide comes back on its first, and
|
|
56567
56564
|
// only the press says that is a step forward — the map, read between those
|
|
@@ -56830,6 +56827,7 @@ const SlideContainer = ({
|
|
|
56830
56827
|
}
|
|
56831
56828
|
stageRef.current = null;
|
|
56832
56829
|
trackAnimationRef.current = null;
|
|
56830
|
+
movingRef.current = null;
|
|
56833
56831
|
// At rest the picture IS the current slide, whatever the last gesture wrote
|
|
56834
56832
|
// there: an indicator has nothing left to lean towards.
|
|
56835
56833
|
paintTravelProgress(0);
|
|
@@ -57024,7 +57022,7 @@ const SlideContainer = ({
|
|
|
57024
57022
|
// there, and when it is over this is what holds. Except under a hand-off
|
|
57025
57023
|
// still waiting for its travel: the track stays where the finger left it,
|
|
57026
57024
|
// until the render that moves it or the frame after which the gesture gives
|
|
57027
|
-
// up on it (see
|
|
57025
|
+
// up on it (see settleTowards in onEnd).
|
|
57028
57026
|
if (!travelFromRef.current) {
|
|
57029
57027
|
track.style.setProperty("--slide-container-offset", offset);
|
|
57030
57028
|
}
|
|
@@ -57059,6 +57057,10 @@ const SlideContainer = ({
|
|
|
57059
57057
|
duration: durationMs * travelRatio,
|
|
57060
57058
|
easing
|
|
57061
57059
|
});
|
|
57060
|
+
movingRef.current = {
|
|
57061
|
+
from: drawnArea,
|
|
57062
|
+
to: currentArea
|
|
57063
|
+
};
|
|
57062
57064
|
// The trait travels with the slides: from where the gesture left it when
|
|
57063
57065
|
// there was one, from a whole box away when the travel was asked for.
|
|
57064
57066
|
const progressFrom = travelProgressFromRef.current ?? (travelStep ? travelStep.x || travelStep.y : 0);
|
|
@@ -57844,7 +57846,7 @@ const SlideContainer = ({
|
|
|
57844
57846
|
// The two slides the gesture can bring in, placed one box either side of the
|
|
57845
57847
|
// one being dragged — the same stage a travel builds, except that both ends
|
|
57846
57848
|
// are set up at once because the finger has not said yet which way it goes.
|
|
57847
|
-
const stageDrag = drag => {
|
|
57849
|
+
const stageDrag = (drag, currentArea) => {
|
|
57848
57850
|
const {
|
|
57849
57851
|
slideElements,
|
|
57850
57852
|
placeOf
|
|
@@ -57872,7 +57874,7 @@ const SlideContainer = ({
|
|
|
57872
57874
|
}
|
|
57873
57875
|
stageRef.current = {
|
|
57874
57876
|
placeByArea,
|
|
57875
|
-
area:
|
|
57877
|
+
area: currentArea
|
|
57876
57878
|
};
|
|
57877
57879
|
for (const slideElement of slideElements) {
|
|
57878
57880
|
const area = readArea(slideElement);
|
|
@@ -57888,33 +57890,63 @@ const SlideContainer = ({
|
|
|
57888
57890
|
}
|
|
57889
57891
|
};
|
|
57890
57892
|
|
|
57891
|
-
// Let go of
|
|
57892
|
-
//
|
|
57893
|
-
//
|
|
57894
|
-
|
|
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) => {
|
|
57895
57899
|
const track = trackRef.current;
|
|
57896
57900
|
if (!track) {
|
|
57897
57901
|
return;
|
|
57898
57902
|
}
|
|
57899
|
-
const
|
|
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`;
|
|
57900
57920
|
const durationMs = durationToMs(duration);
|
|
57901
|
-
const pulled = Math.abs(drag.pull[drag.axis]);
|
|
57902
57921
|
const size = drag.axis === "x" ? drag.box.width : drag.box.height;
|
|
57922
|
+
const left = Math.abs(restPx[drag.axis] - nowPx[drag.axis]);
|
|
57903
57923
|
trackAnimationRef.current?.cancel();
|
|
57904
57924
|
trackAnimationRef.current = null;
|
|
57905
57925
|
track.style.setProperty("--slide-container-offset", restOffset);
|
|
57906
|
-
if (!durationMs || !
|
|
57926
|
+
if (!durationMs || !left) {
|
|
57907
57927
|
paintTravelProgress(0);
|
|
57908
57928
|
settleTravel();
|
|
57909
57929
|
return;
|
|
57910
57930
|
}
|
|
57911
|
-
|
|
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);
|
|
57912
57944
|
const animation = track.animate([{
|
|
57913
|
-
translate:
|
|
57945
|
+
translate: `${nowPx.x}px ${nowPx.y}px`
|
|
57914
57946
|
}, {
|
|
57915
57947
|
translate: restOffset
|
|
57916
57948
|
}], {
|
|
57917
|
-
duration: durationMs * (
|
|
57949
|
+
duration: durationMs * (left / size),
|
|
57918
57950
|
easing: "ease-out"
|
|
57919
57951
|
});
|
|
57920
57952
|
trackAnimationRef.current = animation;
|
|
@@ -57945,11 +57977,14 @@ const SlideContainer = ({
|
|
|
57945
57977
|
// value underneath it, which is the far end of the travel — the very jump
|
|
57946
57978
|
// this is about.
|
|
57947
57979
|
trackElement.style.setProperty("--slide-container-offset", offsetOnScreen);
|
|
57980
|
+
const moving = movingRef.current || {};
|
|
57948
57981
|
return {
|
|
57949
57982
|
trackElement,
|
|
57950
57983
|
onScreenPx,
|
|
57951
57984
|
offsetOnScreen,
|
|
57952
|
-
offsetTarget: offsetRef.current
|
|
57985
|
+
offsetTarget: offsetRef.current,
|
|
57986
|
+
from: moving.from,
|
|
57987
|
+
to: moving.to
|
|
57953
57988
|
};
|
|
57954
57989
|
};
|
|
57955
57990
|
// Which way a caught travel was going: a hand reaching for something moving
|
|
@@ -57996,8 +58031,6 @@ const SlideContainer = ({
|
|
|
57996
58031
|
sign,
|
|
57997
58032
|
target
|
|
57998
58033
|
}) => {
|
|
57999
|
-
let areaBack = axis === "x" ? areaTowards(-1, 0) : areaTowards(0, -1);
|
|
58000
|
-
let areaOn = axis === "x" ? areaTowards(1, 0) : areaTowards(0, 1);
|
|
58001
58034
|
// Everything positional is read HERE rather than when the pointer
|
|
58002
58035
|
// landed: the travel that was playing then may have arrived since, and
|
|
58003
58036
|
// it is what the slides are doing at the moment the gesture takes them
|
|
@@ -58008,39 +58041,66 @@ const SlideContainer = ({
|
|
|
58008
58041
|
placeOf
|
|
58009
58042
|
} = readMap();
|
|
58010
58043
|
const currentElement = slideElements.find(slideElement => slideElement.hasAttribute("data-current")) || slideElements[0];
|
|
58011
|
-
// The hold goToArea reads at the release, read again HERE, off the same
|
|
58012
|
-
// slide and the same attribute: a slide that will refuse the arrival
|
|
58013
|
-
// must not offer the journey. A locked direction simply has nowhere to
|
|
58014
|
-
// go for the length of this gesture — the one case the gesture already
|
|
58015
|
-
// knows, being the last slide of a walk. The hand then gets the wall it
|
|
58016
|
-
// can lean on and never walk through (see drag_to_travel), the slide
|
|
58017
|
-
// behind it stays offstage instead of being read on the way, and the
|
|
58018
|
-
// release has nothing left to refuse.
|
|
58019
|
-
// Nothing here about `released` (--navi-done): that is one particular
|
|
58020
|
-
// departure letting go, decided as it happens, and a gesture armed
|
|
58021
|
-
// before it has no such thing to read — the attribute as rendered is
|
|
58022
|
-
// what the hand is answered from.
|
|
58023
|
-
if (currentElement?.hasAttribute("data-prevent-nav-previous")) {
|
|
58024
|
-
areaBack = undefined;
|
|
58025
|
-
}
|
|
58026
|
-
if (currentElement?.hasAttribute("data-prevent-nav-next")) {
|
|
58027
|
-
areaOn = undefined;
|
|
58028
|
-
}
|
|
58029
58044
|
const box = track.getBoundingClientRect();
|
|
58030
|
-
if (!
|
|
58031
|
-
// Something else with a better claim on the gesture: a scroller
|
|
58032
|
-
// between the finger and the slide, with room left that way.
|
|
58033
|
-
scrollRoomTowards(target, currentElement, axis, sign)) {
|
|
58045
|
+
if (!currentElement || !box.width || !box.height) {
|
|
58034
58046
|
return false;
|
|
58035
58047
|
}
|
|
58036
|
-
const
|
|
58037
|
-
// Where the slide being dragged stands: where the stage put it while a
|
|
58038
|
-
// travel is playing, its place on the map otherwise.
|
|
58048
|
+
const currentArea = readArea(currentElement);
|
|
58039
58049
|
const stage = stageRef.current;
|
|
58040
|
-
|
|
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) || {
|
|
58041
58053
|
x: 0,
|
|
58042
58054
|
y: 0
|
|
58043
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);
|
|
58044
58104
|
const baseOffset = {
|
|
58045
58105
|
x: -basePlace.x * box.width,
|
|
58046
58106
|
y: -basePlace.y * box.height
|
|
@@ -58071,7 +58131,8 @@ const SlideContainer = ({
|
|
|
58071
58131
|
[axis]: slack
|
|
58072
58132
|
};
|
|
58073
58133
|
drag.progress = slack / size;
|
|
58074
|
-
|
|
58134
|
+
drag.areaPulled = slack > 0 ? areaBack : slack < 0 ? areaOn : null;
|
|
58135
|
+
stageDrag(drag, currentArea);
|
|
58075
58136
|
// From here the box is busy, whichever input asked: a wheel gesture and
|
|
58076
58137
|
// a press must not both be moving the same track.
|
|
58077
58138
|
dragRef.current = drag;
|
|
@@ -58102,24 +58163,50 @@ const SlideContainer = ({
|
|
|
58102
58163
|
event
|
|
58103
58164
|
}) => {
|
|
58104
58165
|
dragRef.current = null;
|
|
58105
|
-
|
|
58106
|
-
|
|
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);
|
|
58107
58180
|
return;
|
|
58108
58181
|
}
|
|
58109
58182
|
// Where the slide is being left, for the travel to depart from instead
|
|
58110
58183
|
// of from the map.
|
|
58111
58184
|
travelFromRef.current = drag.offset;
|
|
58112
58185
|
// …and where the indicator is being left, said about the slide that is
|
|
58113
|
-
// ARRIVING:
|
|
58114
|
-
//
|
|
58115
|
-
travelProgressFromRef.current = drag.progress - sign;
|
|
58116
|
-
|
|
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
|
+
});
|
|
58117
58204
|
if (!moved) {
|
|
58118
58205
|
// Nowhere to go after all — a slide holding on to the user
|
|
58119
58206
|
// (preventNav), or a caller that refused the change.
|
|
58120
58207
|
travelFromRef.current = null;
|
|
58121
58208
|
travelProgressFromRef.current = null;
|
|
58122
|
-
|
|
58209
|
+
settleTowards(drag, currentArea);
|
|
58123
58210
|
return;
|
|
58124
58211
|
}
|
|
58125
58212
|
// A container whose `current` is held outside and was not moved: no
|
|
@@ -58130,7 +58217,7 @@ const SlideContainer = ({
|
|
|
58130
58217
|
if (travelFromRef.current) {
|
|
58131
58218
|
travelFromRef.current = null;
|
|
58132
58219
|
travelProgressFromRef.current = null;
|
|
58133
|
-
|
|
58220
|
+
settleTowards(drag, currentArea);
|
|
58134
58221
|
}
|
|
58135
58222
|
});
|
|
58136
58223
|
},
|
|
@@ -58145,9 +58232,15 @@ const SlideContainer = ({
|
|
|
58145
58232
|
trackElement: trackCaught,
|
|
58146
58233
|
offsetOnScreen,
|
|
58147
58234
|
offsetTarget,
|
|
58148
|
-
onScreenPx: caughtOnScreenPx
|
|
58235
|
+
onScreenPx: caughtOnScreenPx,
|
|
58236
|
+
from,
|
|
58237
|
+
to
|
|
58149
58238
|
} = caughtTravel;
|
|
58150
58239
|
caughtTravel = null;
|
|
58240
|
+
movingRef.current = {
|
|
58241
|
+
from,
|
|
58242
|
+
to
|
|
58243
|
+
};
|
|
58151
58244
|
if (offsetOnScreen === offsetTarget) {
|
|
58152
58245
|
settleTravel();
|
|
58153
58246
|
return;
|
|
@@ -65237,6 +65330,12 @@ const PickerCustom = props => {
|
|
|
65237
65330
|
// PickerNative takes.
|
|
65238
65331
|
pickerProps.resetOnError = true;
|
|
65239
65332
|
}
|
|
65333
|
+
if (pickerProps.resetOnAbort === undefined) {
|
|
65334
|
+
// Same reasoning for an action the app abandons (an AbortError, e.g. a
|
|
65335
|
+
// verification step the user dismissed): the popup is already closed, so
|
|
65336
|
+
// the abandoned value rolls back instead of staying selected in the list.
|
|
65337
|
+
pickerProps.resetOnAbort = true;
|
|
65338
|
+
}
|
|
65240
65339
|
// ref
|
|
65241
65340
|
const popupRef = useRef(null);
|
|
65242
65341
|
popupProps.ref = popupRef;
|