@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/jsenv_navi.js
CHANGED
|
@@ -8914,6 +8914,17 @@ const naviI18nFromValidityMessage = ({ key, params }) => {
|
|
|
8914
8914
|
return naviI18n(`constraint.${key}`, params);
|
|
8915
8915
|
};
|
|
8916
8916
|
|
|
8917
|
+
// The characters a ui state holds, for the rules that read a value as text
|
|
8918
|
+
// (length, pattern, number, email…). `undefined` and `null` both hold none:
|
|
8919
|
+
// `String(null)` would hand those rules the four letters "null" — a number
|
|
8920
|
+
// field cleared with `value={null}` then reported "must be a number".
|
|
8921
|
+
const uiStateAsText = (uiState) => {
|
|
8922
|
+
if (uiState === undefined || uiState === null) {
|
|
8923
|
+
return "";
|
|
8924
|
+
}
|
|
8925
|
+
return String(uiState);
|
|
8926
|
+
};
|
|
8927
|
+
|
|
8917
8928
|
/**
|
|
8918
8929
|
* https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation
|
|
8919
8930
|
*/
|
|
@@ -8980,8 +8991,7 @@ const REQUIRED_CONSTRAINT = {
|
|
|
8980
8991
|
return naviI18n("constraint.required.checkbox");
|
|
8981
8992
|
}
|
|
8982
8993
|
|
|
8983
|
-
const valueAsString =
|
|
8984
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
8994
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
8985
8995
|
if (valueAsString) {
|
|
8986
8996
|
return null;
|
|
8987
8997
|
}
|
|
@@ -9032,8 +9042,7 @@ const PATTERN_CONSTRAINT = {
|
|
|
9032
9042
|
if (!pattern) {
|
|
9033
9043
|
return null;
|
|
9034
9044
|
}
|
|
9035
|
-
const valueAsString =
|
|
9036
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9045
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9037
9046
|
if (!valueAsString) {
|
|
9038
9047
|
return null;
|
|
9039
9048
|
}
|
|
@@ -9068,8 +9077,7 @@ const TYPE_EMAIL_CONSTRAINT = {
|
|
|
9068
9077
|
if (type !== "email") {
|
|
9069
9078
|
return null;
|
|
9070
9079
|
}
|
|
9071
|
-
const valueAsString =
|
|
9072
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9080
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9073
9081
|
if (!valueAsString) {
|
|
9074
9082
|
return null;
|
|
9075
9083
|
}
|
|
@@ -9102,8 +9110,7 @@ const MIN_LENGTH_CONSTRAINT = {
|
|
|
9102
9110
|
if (minLength === undefined) {
|
|
9103
9111
|
return null;
|
|
9104
9112
|
}
|
|
9105
|
-
const valueAsString =
|
|
9106
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9113
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9107
9114
|
if (!valueAsString && !field.controlHostProps.required) {
|
|
9108
9115
|
return null;
|
|
9109
9116
|
}
|
|
@@ -9198,8 +9205,7 @@ const MAX_LENGTH_CONSTRAINT = {
|
|
|
9198
9205
|
if (maxLength === undefined) {
|
|
9199
9206
|
return null;
|
|
9200
9207
|
}
|
|
9201
|
-
const valueAsString =
|
|
9202
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9208
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9203
9209
|
if (!valueAsString) {
|
|
9204
9210
|
return null;
|
|
9205
9211
|
}
|
|
@@ -9240,8 +9246,7 @@ const TYPE_NUMBER_CONSTRAINT = {
|
|
|
9240
9246
|
if (!isNumberInput(type, naviType)) {
|
|
9241
9247
|
return null;
|
|
9242
9248
|
}
|
|
9243
|
-
const valueAsString =
|
|
9244
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9249
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9245
9250
|
if (!valueAsString) {
|
|
9246
9251
|
return null;
|
|
9247
9252
|
}
|
|
@@ -9306,8 +9311,7 @@ const MIN_CONSTRAINT = {
|
|
|
9306
9311
|
}
|
|
9307
9312
|
const type = field.controlHostProps.type;
|
|
9308
9313
|
const naviInputType = field.controlHostProps["navi-input-type"];
|
|
9309
|
-
const valueAsString =
|
|
9310
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9314
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9311
9315
|
if (!valueAsString) {
|
|
9312
9316
|
return null;
|
|
9313
9317
|
}
|
|
@@ -9406,8 +9410,7 @@ const MAX_CONSTRAINT = {
|
|
|
9406
9410
|
}
|
|
9407
9411
|
const type = field.controlHostProps.type;
|
|
9408
9412
|
const naviInputType = field.controlHostProps["navi-input-type"];
|
|
9409
|
-
const valueAsString =
|
|
9410
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9413
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9411
9414
|
if (!valueAsString) {
|
|
9412
9415
|
return null;
|
|
9413
9416
|
}
|
|
@@ -9540,8 +9543,7 @@ const STEP_CONSTRAINT = {
|
|
|
9540
9543
|
return null;
|
|
9541
9544
|
}
|
|
9542
9545
|
const stepString = String(stepRaw);
|
|
9543
|
-
const valueAsString =
|
|
9544
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
9546
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
9545
9547
|
if (!valueAsString) {
|
|
9546
9548
|
return null;
|
|
9547
9549
|
}
|
|
@@ -12341,8 +12343,7 @@ const DISPLAYABLE_CONSTRAINT = {
|
|
|
12341
12343
|
if (!isConstraintAttributeOn(displayable)) {
|
|
12342
12344
|
return null;
|
|
12343
12345
|
}
|
|
12344
|
-
const valueAsString =
|
|
12345
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12346
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12346
12347
|
const maxStackedMarksAttribute =
|
|
12347
12348
|
field.controlHostProps["data-max-stacked-marks"];
|
|
12348
12349
|
const result = DISPLAYABLE_RULE.applyOn(true, valueAsString, {
|
|
@@ -12383,8 +12384,7 @@ const MAX_LINE_BREAKS_CONSTRAINT = {
|
|
|
12383
12384
|
if (isNaN(maxLineBreaks)) {
|
|
12384
12385
|
return null;
|
|
12385
12386
|
}
|
|
12386
|
-
const valueAsString =
|
|
12387
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12387
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12388
12388
|
const result = MAX_LINE_BREAKS_RULE.applyOn(maxLineBreaks, valueAsString);
|
|
12389
12389
|
if (!result) {
|
|
12390
12390
|
return null;
|
|
@@ -12413,8 +12413,7 @@ const NO_EMOJI_CONSTRAINT = {
|
|
|
12413
12413
|
if (!isConstraintAttributeOn(noEmoji)) {
|
|
12414
12414
|
return null;
|
|
12415
12415
|
}
|
|
12416
|
-
const valueAsString =
|
|
12417
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12416
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12418
12417
|
const result = NO_EMOJI_RULE.applyOn(true, valueAsString);
|
|
12419
12418
|
if (!result) {
|
|
12420
12419
|
return null;
|
|
@@ -12428,8 +12427,7 @@ const MIN_LOWER_LETTER_CONSTRAINT = {
|
|
|
12428
12427
|
name: "min_lower_letter",
|
|
12429
12428
|
messageAttribute: "data-min-lower-letter-message",
|
|
12430
12429
|
check: (field) => {
|
|
12431
|
-
const valueAsString =
|
|
12432
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12430
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12433
12431
|
const required = field.controlHostProps.required;
|
|
12434
12432
|
if (!valueAsString && !required) {
|
|
12435
12433
|
return "";
|
|
@@ -12474,8 +12472,7 @@ const MIN_UPPER_LETTER_CONSTRAINT = {
|
|
|
12474
12472
|
name: "min_upper_letter",
|
|
12475
12473
|
messageAttribute: "data-min-upper-letter-message",
|
|
12476
12474
|
check: (field) => {
|
|
12477
|
-
const valueAsString =
|
|
12478
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12475
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12479
12476
|
const required = field.controlHostProps.required;
|
|
12480
12477
|
if (!valueAsString && !required) {
|
|
12481
12478
|
return null;
|
|
@@ -12511,8 +12508,7 @@ const MIN_DIGIT_CONSTRAINT = {
|
|
|
12511
12508
|
name: "min_digit",
|
|
12512
12509
|
messageAttribute: "data-min-digit-message",
|
|
12513
12510
|
check: (field) => {
|
|
12514
|
-
const valueAsString =
|
|
12515
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12511
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12516
12512
|
const required = field.controlHostProps.required;
|
|
12517
12513
|
if (!valueAsString && !required) {
|
|
12518
12514
|
return null;
|
|
@@ -12548,8 +12544,7 @@ const MIN_SPECIAL_CHAR_CONSTRAINT = {
|
|
|
12548
12544
|
name: "min_special_char",
|
|
12549
12545
|
messageAttribute: "data-min-special-char-message",
|
|
12550
12546
|
check: (field) => {
|
|
12551
|
-
const valueAsString =
|
|
12552
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12547
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12553
12548
|
const required = field.controlHostProps.required;
|
|
12554
12549
|
if (!valueAsString && !required) {
|
|
12555
12550
|
return null;
|
|
@@ -12666,8 +12661,7 @@ const SAME_AS_CONSTRAINT = {
|
|
|
12666
12661
|
// Reference field is empty — nothing to compare against yet.
|
|
12667
12662
|
return null;
|
|
12668
12663
|
}
|
|
12669
|
-
const valueAsString =
|
|
12670
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12664
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12671
12665
|
if (valueAsString === otherFieldValue) {
|
|
12672
12666
|
return null;
|
|
12673
12667
|
}
|
|
@@ -12708,8 +12702,7 @@ CONSTRAINT_ATTRIBUTE_SET.add("data-same-as");
|
|
|
12708
12702
|
|
|
12709
12703
|
|
|
12710
12704
|
const applyRule = (field) => {
|
|
12711
|
-
const valueAsString =
|
|
12712
|
-
field.uiState === undefined ? "" : String(field.uiState);
|
|
12705
|
+
const valueAsString = uiStateAsText(field.uiState);
|
|
12713
12706
|
return SINGLE_SPACE_RULE.applyOn(true, valueAsString);
|
|
12714
12707
|
};
|
|
12715
12708
|
|
|
@@ -36535,9 +36528,9 @@ const getInvalidCharsMessage = (
|
|
|
36535
36528
|
uiState,
|
|
36536
36529
|
{ charClass, messageKey, uiStateNow },
|
|
36537
36530
|
) => {
|
|
36538
|
-
const str =
|
|
36531
|
+
const str = uiStateAsText(uiState);
|
|
36539
36532
|
if (compileCharClassAnchored(charClass).test(str)) return null;
|
|
36540
|
-
const strNow =
|
|
36533
|
+
const strNow = uiStateAsText(uiStateNow);
|
|
36541
36534
|
if (
|
|
36542
36535
|
countCharsOutsideClass(str, charClass) <=
|
|
36543
36536
|
countCharsOutsideClass(strNow, charClass)
|
|
@@ -36550,9 +36543,9 @@ const getInvalidCharsMessage = (
|
|
|
36550
36543
|
// Paste / set: truncate what the gesture adds beyond the limit.
|
|
36551
36544
|
const getLengthOverflowResult = (uiState, { maxLength, uiStateNow }) => {
|
|
36552
36545
|
if (maxLength === undefined) return null;
|
|
36553
|
-
const str =
|
|
36546
|
+
const str = uiStateAsText(uiState);
|
|
36554
36547
|
if (str.length <= maxLength) return null;
|
|
36555
|
-
const strNow =
|
|
36548
|
+
const strNow = uiStateAsText(uiStateNow);
|
|
36556
36549
|
if (str.length <= strNow.length) return null;
|
|
36557
36550
|
return {
|
|
36558
36551
|
fixedValue: str.slice(0, maxLength),
|
|
@@ -55439,6 +55432,10 @@ const SlideContainer = ({
|
|
|
55439
55432
|
// one being travelled TO while the track moves. What the next travel departs
|
|
55440
55433
|
// from, because it is what one is looking at.
|
|
55441
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);
|
|
55442
55439
|
// Which way the travel about to be drawn goes, when whatever asked for it
|
|
55443
55440
|
// knows: a window stepping off its last slide comes back on its first, and
|
|
55444
55441
|
// only the press says that is a step forward — the map, read between those
|
|
@@ -55700,6 +55697,7 @@ const SlideContainer = ({
|
|
|
55700
55697
|
}
|
|
55701
55698
|
stageRef.current = null;
|
|
55702
55699
|
trackAnimationRef.current = null;
|
|
55700
|
+
movingRef.current = null;
|
|
55703
55701
|
// At rest the picture IS the current slide, whatever the last gesture wrote
|
|
55704
55702
|
// there: an indicator has nothing left to lean towards.
|
|
55705
55703
|
paintTravelProgress(0);
|
|
@@ -55894,7 +55892,7 @@ const SlideContainer = ({
|
|
|
55894
55892
|
// there, and when it is over this is what holds. Except under a hand-off
|
|
55895
55893
|
// still waiting for its travel: the track stays where the finger left it,
|
|
55896
55894
|
// until the render that moves it or the frame after which the gesture gives
|
|
55897
|
-
// up on it (see
|
|
55895
|
+
// up on it (see settleTowards in onEnd).
|
|
55898
55896
|
if (!travelFromRef.current) {
|
|
55899
55897
|
track.style.setProperty("--slide-container-offset", offset);
|
|
55900
55898
|
}
|
|
@@ -55929,6 +55927,10 @@ const SlideContainer = ({
|
|
|
55929
55927
|
duration: durationMs * travelRatio,
|
|
55930
55928
|
easing
|
|
55931
55929
|
});
|
|
55930
|
+
movingRef.current = {
|
|
55931
|
+
from: drawnArea,
|
|
55932
|
+
to: currentArea
|
|
55933
|
+
};
|
|
55932
55934
|
// The trait travels with the slides: from where the gesture left it when
|
|
55933
55935
|
// there was one, from a whole box away when the travel was asked for.
|
|
55934
55936
|
const progressFrom = travelProgressFromRef.current ?? (travelStep ? travelStep.x || travelStep.y : 0);
|
|
@@ -56714,7 +56716,7 @@ const SlideContainer = ({
|
|
|
56714
56716
|
// The two slides the gesture can bring in, placed one box either side of the
|
|
56715
56717
|
// one being dragged — the same stage a travel builds, except that both ends
|
|
56716
56718
|
// are set up at once because the finger has not said yet which way it goes.
|
|
56717
|
-
const stageDrag = drag => {
|
|
56719
|
+
const stageDrag = (drag, currentArea) => {
|
|
56718
56720
|
const {
|
|
56719
56721
|
slideElements,
|
|
56720
56722
|
placeOf
|
|
@@ -56742,7 +56744,7 @@ const SlideContainer = ({
|
|
|
56742
56744
|
}
|
|
56743
56745
|
stageRef.current = {
|
|
56744
56746
|
placeByArea,
|
|
56745
|
-
area:
|
|
56747
|
+
area: currentArea
|
|
56746
56748
|
};
|
|
56747
56749
|
for (const slideElement of slideElements) {
|
|
56748
56750
|
const area = readArea(slideElement);
|
|
@@ -56758,33 +56760,63 @@ const SlideContainer = ({
|
|
|
56758
56760
|
}
|
|
56759
56761
|
};
|
|
56760
56762
|
|
|
56761
|
-
// Let go of
|
|
56762
|
-
//
|
|
56763
|
-
//
|
|
56764
|
-
|
|
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) => {
|
|
56765
56769
|
const track = trackRef.current;
|
|
56766
56770
|
if (!track) {
|
|
56767
56771
|
return;
|
|
56768
56772
|
}
|
|
56769
|
-
const
|
|
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`;
|
|
56770
56790
|
const durationMs = durationToMs(duration);
|
|
56771
|
-
const pulled = Math.abs(drag.pull[drag.axis]);
|
|
56772
56791
|
const size = drag.axis === "x" ? drag.box.width : drag.box.height;
|
|
56792
|
+
const left = Math.abs(restPx[drag.axis] - nowPx[drag.axis]);
|
|
56773
56793
|
trackAnimationRef.current?.cancel();
|
|
56774
56794
|
trackAnimationRef.current = null;
|
|
56775
56795
|
track.style.setProperty("--slide-container-offset", restOffset);
|
|
56776
|
-
if (!durationMs || !
|
|
56796
|
+
if (!durationMs || !left) {
|
|
56777
56797
|
paintTravelProgress(0);
|
|
56778
56798
|
settleTravel();
|
|
56779
56799
|
return;
|
|
56780
56800
|
}
|
|
56781
|
-
|
|
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);
|
|
56782
56814
|
const animation = track.animate([{
|
|
56783
|
-
translate:
|
|
56815
|
+
translate: `${nowPx.x}px ${nowPx.y}px`
|
|
56784
56816
|
}, {
|
|
56785
56817
|
translate: restOffset
|
|
56786
56818
|
}], {
|
|
56787
|
-
duration: durationMs * (
|
|
56819
|
+
duration: durationMs * (left / size),
|
|
56788
56820
|
easing: "ease-out"
|
|
56789
56821
|
});
|
|
56790
56822
|
trackAnimationRef.current = animation;
|
|
@@ -56815,11 +56847,14 @@ const SlideContainer = ({
|
|
|
56815
56847
|
// value underneath it, which is the far end of the travel — the very jump
|
|
56816
56848
|
// this is about.
|
|
56817
56849
|
trackElement.style.setProperty("--slide-container-offset", offsetOnScreen);
|
|
56850
|
+
const moving = movingRef.current || {};
|
|
56818
56851
|
return {
|
|
56819
56852
|
trackElement,
|
|
56820
56853
|
onScreenPx,
|
|
56821
56854
|
offsetOnScreen,
|
|
56822
|
-
offsetTarget: offsetRef.current
|
|
56855
|
+
offsetTarget: offsetRef.current,
|
|
56856
|
+
from: moving.from,
|
|
56857
|
+
to: moving.to
|
|
56823
56858
|
};
|
|
56824
56859
|
};
|
|
56825
56860
|
// Which way a caught travel was going: a hand reaching for something moving
|
|
@@ -56866,8 +56901,6 @@ const SlideContainer = ({
|
|
|
56866
56901
|
sign,
|
|
56867
56902
|
target
|
|
56868
56903
|
}) => {
|
|
56869
|
-
let areaBack = axis === "x" ? areaTowards(-1, 0) : areaTowards(0, -1);
|
|
56870
|
-
let areaOn = axis === "x" ? areaTowards(1, 0) : areaTowards(0, 1);
|
|
56871
56904
|
// Everything positional is read HERE rather than when the pointer
|
|
56872
56905
|
// landed: the travel that was playing then may have arrived since, and
|
|
56873
56906
|
// it is what the slides are doing at the moment the gesture takes them
|
|
@@ -56878,39 +56911,66 @@ const SlideContainer = ({
|
|
|
56878
56911
|
placeOf
|
|
56879
56912
|
} = readMap();
|
|
56880
56913
|
const currentElement = slideElements.find(slideElement => slideElement.hasAttribute("data-current")) || slideElements[0];
|
|
56881
|
-
// The hold goToArea reads at the release, read again HERE, off the same
|
|
56882
|
-
// slide and the same attribute: a slide that will refuse the arrival
|
|
56883
|
-
// must not offer the journey. A locked direction simply has nowhere to
|
|
56884
|
-
// go for the length of this gesture — the one case the gesture already
|
|
56885
|
-
// knows, being the last slide of a walk. The hand then gets the wall it
|
|
56886
|
-
// can lean on and never walk through (see drag_to_travel), the slide
|
|
56887
|
-
// behind it stays offstage instead of being read on the way, and the
|
|
56888
|
-
// release has nothing left to refuse.
|
|
56889
|
-
// Nothing here about `released` (--navi-done): that is one particular
|
|
56890
|
-
// departure letting go, decided as it happens, and a gesture armed
|
|
56891
|
-
// before it has no such thing to read — the attribute as rendered is
|
|
56892
|
-
// what the hand is answered from.
|
|
56893
|
-
if (currentElement?.hasAttribute("data-prevent-nav-previous")) {
|
|
56894
|
-
areaBack = undefined;
|
|
56895
|
-
}
|
|
56896
|
-
if (currentElement?.hasAttribute("data-prevent-nav-next")) {
|
|
56897
|
-
areaOn = undefined;
|
|
56898
|
-
}
|
|
56899
56914
|
const box = track.getBoundingClientRect();
|
|
56900
|
-
if (!
|
|
56901
|
-
// Something else with a better claim on the gesture: a scroller
|
|
56902
|
-
// between the finger and the slide, with room left that way.
|
|
56903
|
-
scrollRoomTowards(target, currentElement, axis, sign)) {
|
|
56915
|
+
if (!currentElement || !box.width || !box.height) {
|
|
56904
56916
|
return false;
|
|
56905
56917
|
}
|
|
56906
|
-
const
|
|
56907
|
-
// Where the slide being dragged stands: where the stage put it while a
|
|
56908
|
-
// travel is playing, its place on the map otherwise.
|
|
56918
|
+
const currentArea = readArea(currentElement);
|
|
56909
56919
|
const stage = stageRef.current;
|
|
56910
|
-
|
|
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) || {
|
|
56911
56923
|
x: 0,
|
|
56912
56924
|
y: 0
|
|
56913
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);
|
|
56914
56974
|
const baseOffset = {
|
|
56915
56975
|
x: -basePlace.x * box.width,
|
|
56916
56976
|
y: -basePlace.y * box.height
|
|
@@ -56941,7 +57001,8 @@ const SlideContainer = ({
|
|
|
56941
57001
|
[axis]: slack
|
|
56942
57002
|
};
|
|
56943
57003
|
drag.progress = slack / size;
|
|
56944
|
-
|
|
57004
|
+
drag.areaPulled = slack > 0 ? areaBack : slack < 0 ? areaOn : null;
|
|
57005
|
+
stageDrag(drag, currentArea);
|
|
56945
57006
|
// From here the box is busy, whichever input asked: a wheel gesture and
|
|
56946
57007
|
// a press must not both be moving the same track.
|
|
56947
57008
|
dragRef.current = drag;
|
|
@@ -56972,24 +57033,50 @@ const SlideContainer = ({
|
|
|
56972
57033
|
event
|
|
56973
57034
|
}) => {
|
|
56974
57035
|
dragRef.current = null;
|
|
56975
|
-
|
|
56976
|
-
|
|
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);
|
|
56977
57050
|
return;
|
|
56978
57051
|
}
|
|
56979
57052
|
// Where the slide is being left, for the travel to depart from instead
|
|
56980
57053
|
// of from the map.
|
|
56981
57054
|
travelFromRef.current = drag.offset;
|
|
56982
57055
|
// …and where the indicator is being left, said about the slide that is
|
|
56983
|
-
// ARRIVING:
|
|
56984
|
-
//
|
|
56985
|
-
travelProgressFromRef.current = drag.progress - sign;
|
|
56986
|
-
|
|
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
|
+
});
|
|
56987
57074
|
if (!moved) {
|
|
56988
57075
|
// Nowhere to go after all — a slide holding on to the user
|
|
56989
57076
|
// (preventNav), or a caller that refused the change.
|
|
56990
57077
|
travelFromRef.current = null;
|
|
56991
57078
|
travelProgressFromRef.current = null;
|
|
56992
|
-
|
|
57079
|
+
settleTowards(drag, currentArea);
|
|
56993
57080
|
return;
|
|
56994
57081
|
}
|
|
56995
57082
|
// A container whose `current` is held outside and was not moved: no
|
|
@@ -57000,7 +57087,7 @@ const SlideContainer = ({
|
|
|
57000
57087
|
if (travelFromRef.current) {
|
|
57001
57088
|
travelFromRef.current = null;
|
|
57002
57089
|
travelProgressFromRef.current = null;
|
|
57003
|
-
|
|
57090
|
+
settleTowards(drag, currentArea);
|
|
57004
57091
|
}
|
|
57005
57092
|
});
|
|
57006
57093
|
},
|
|
@@ -57015,9 +57102,15 @@ const SlideContainer = ({
|
|
|
57015
57102
|
trackElement: trackCaught,
|
|
57016
57103
|
offsetOnScreen,
|
|
57017
57104
|
offsetTarget,
|
|
57018
|
-
onScreenPx: caughtOnScreenPx
|
|
57105
|
+
onScreenPx: caughtOnScreenPx,
|
|
57106
|
+
from,
|
|
57107
|
+
to
|
|
57019
57108
|
} = caughtTravel;
|
|
57020
57109
|
caughtTravel = null;
|
|
57110
|
+
movingRef.current = {
|
|
57111
|
+
from,
|
|
57112
|
+
to
|
|
57113
|
+
};
|
|
57021
57114
|
if (offsetOnScreen === offsetTarget) {
|
|
57022
57115
|
settleTravel();
|
|
57023
57116
|
return;
|
|
@@ -63943,6 +64036,12 @@ const PickerCustom = props => {
|
|
|
63943
64036
|
// PickerNative takes.
|
|
63944
64037
|
pickerProps.resetOnError = true;
|
|
63945
64038
|
}
|
|
64039
|
+
if (pickerProps.resetOnAbort === undefined) {
|
|
64040
|
+
// Same reasoning for an action the app abandons (an AbortError, e.g. a
|
|
64041
|
+
// verification step the user dismissed): the popup is already closed, so
|
|
64042
|
+
// the abandoned value rolls back instead of staying selected in the list.
|
|
64043
|
+
pickerProps.resetOnAbort = true;
|
|
64044
|
+
}
|
|
63946
64045
|
// ref
|
|
63947
64046
|
const popupRef = useRef(null);
|
|
63948
64047
|
popupProps.ref = popupRef;
|