@jsenv/navi 0.29.82 → 0.29.84
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/jsenv_navi.js +221 -30
- package/dist/jsenv_navi.js.map +17 -8
- package/docs/AI_INSTRUCTIONS.md +3 -1
- package/docs/control_object.md +83 -0
- package/docs/control_value.md +13 -0
- package/docs/navigation.md +61 -3
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -22656,6 +22656,87 @@ const scrollTo = ({ x, y }) => {
|
|
|
22656
22656
|
const [publishBeforeRouting, observeBeforeRouting] = createPubSub();
|
|
22657
22657
|
const [publishAfterRouting, observeAfterRouting] = createPubSub();
|
|
22658
22658
|
|
|
22659
|
+
/**
|
|
22660
|
+
* Is there an entry of THIS document behind the current one? And ahead of it?
|
|
22661
|
+
*
|
|
22662
|
+
* A back arrow drawn inside an app promises to give back the screen it came
|
|
22663
|
+
* from — never the page the reader was on before the app. A url opened cold
|
|
22664
|
+
* (a shared link, a bookmark, a notification) has someone else's page under
|
|
22665
|
+
* it, and `window.history.length` cannot tell the two apart: it counts the
|
|
22666
|
+
* whole tab.
|
|
22667
|
+
*
|
|
22668
|
+
* So the count is kept here, and written into the state of each entry as it is
|
|
22669
|
+
* created, so it survives a reload in the middle of the stack. It cannot be
|
|
22670
|
+
* read back from an entry alone: a replaced entry inherits the state of the
|
|
22671
|
+
* one it takes the place of, so an entry's state does not say how it arrived.
|
|
22672
|
+
* Only the navigation being applied says that, which is why the integrations
|
|
22673
|
+
* (via_history.js, via_navigation.js) hand each navigation over here as they
|
|
22674
|
+
* apply it — the one place no push and no replace can escape.
|
|
22675
|
+
*/
|
|
22676
|
+
|
|
22677
|
+
|
|
22678
|
+
const NAV_DEPTH_STATE_KEY = "jsenv_nav_depth";
|
|
22679
|
+
|
|
22680
|
+
const canNavBackSignal = signal(false);
|
|
22681
|
+
const useCanNavBack = () => {
|
|
22682
|
+
return canNavBackSignal.value;
|
|
22683
|
+
};
|
|
22684
|
+
|
|
22685
|
+
const canNavForwardSignal = signal(false);
|
|
22686
|
+
const useCanNavForward = () => {
|
|
22687
|
+
return canNavForwardSignal.value;
|
|
22688
|
+
};
|
|
22689
|
+
|
|
22690
|
+
// How many entries of this document stand under the current one, and how high
|
|
22691
|
+
// the stack goes above it. Both are unknown for entries this document never
|
|
22692
|
+
// created (a fragment navigation makes its own, and the browser stores no
|
|
22693
|
+
// state on it): those leave the count as it is, which under-reports rather
|
|
22694
|
+
// than promising a screen that is not there.
|
|
22695
|
+
let navDepth = 0;
|
|
22696
|
+
let navDepthMax = 0;
|
|
22697
|
+
|
|
22698
|
+
const getNavDepth = () => navDepth;
|
|
22699
|
+
|
|
22700
|
+
const applyNavigationToNavDepth = (navigationType, state) => {
|
|
22701
|
+
if (navigationType === "push") {
|
|
22702
|
+
navDepth++;
|
|
22703
|
+
// A push cuts whatever stood ahead.
|
|
22704
|
+
navDepthMax = navDepth;
|
|
22705
|
+
} else if (navigationType === "replace") ; else {
|
|
22706
|
+
// load, reload, traverse: the entry itself says where it stands.
|
|
22707
|
+
const depthInState =
|
|
22708
|
+
state && typeof state[NAV_DEPTH_STATE_KEY] === "number"
|
|
22709
|
+
? state[NAV_DEPTH_STATE_KEY]
|
|
22710
|
+
: undefined;
|
|
22711
|
+
if (depthInState !== undefined) {
|
|
22712
|
+
navDepth = depthInState;
|
|
22713
|
+
if (navDepth > navDepthMax) {
|
|
22714
|
+
navDepthMax = navDepth;
|
|
22715
|
+
}
|
|
22716
|
+
}
|
|
22717
|
+
}
|
|
22718
|
+
canNavBackSignal.value = navDepth > 0;
|
|
22719
|
+
canNavForwardSignal.value = navDepth < navDepthMax;
|
|
22720
|
+
};
|
|
22721
|
+
|
|
22722
|
+
/*
|
|
22723
|
+
* A press aims at a place; it does not always go one step deeper. A row of tabs
|
|
22724
|
+
* is a lateral move — the neighbour is one finger away — so the whole row should
|
|
22725
|
+
* weigh one history entry: the arrow at the top and the phone's back button then
|
|
22726
|
+
* leave by where the reader came in, and the swipe (which replaces already, see
|
|
22727
|
+
* route_travel.jsx) and the press say the same thing.
|
|
22728
|
+
*
|
|
22729
|
+
* `<Link replace>` is that, and it travels as an attribute because the click
|
|
22730
|
+
* handler sees the anchor, not the component that rendered it — the same mouth
|
|
22731
|
+
* as what a link asks of a route transition.
|
|
22732
|
+
*/
|
|
22733
|
+
|
|
22734
|
+
const LINK_REPLACE_ATTRIBUTE = "data-navi-replace";
|
|
22735
|
+
|
|
22736
|
+
const linkAsksForReplace = (linkElement) => {
|
|
22737
|
+
return linkElement.hasAttribute(LINK_REPLACE_ATTRIBUTE);
|
|
22738
|
+
};
|
|
22739
|
+
|
|
22659
22740
|
const setupBrowserIntegrationViaHistory = ({
|
|
22660
22741
|
applyActions,
|
|
22661
22742
|
applyRouting,
|
|
@@ -22797,6 +22878,11 @@ const setupBrowserIntegrationViaHistory = ({
|
|
|
22797
22878
|
state,
|
|
22798
22879
|
} = options;
|
|
22799
22880
|
|
|
22881
|
+
// Where the entry being reached stands in this document's own stack —
|
|
22882
|
+
// decided before the state that carries it is built (see
|
|
22883
|
+
// document_back_and_forward.js).
|
|
22884
|
+
applyNavigationToNavDepth(navigationType, state);
|
|
22885
|
+
|
|
22800
22886
|
if (navigationType === "push" || navigationType === "replace") {
|
|
22801
22887
|
markUrlAsVisited(url);
|
|
22802
22888
|
// undefined → inherit current state (link click, neutral navigation)
|
|
@@ -22806,6 +22892,7 @@ const setupBrowserIntegrationViaHistory = ({
|
|
|
22806
22892
|
let effectiveState;
|
|
22807
22893
|
const sharedState = {
|
|
22808
22894
|
jsenv_visited_urls: Array.from(visitedUrlSet),
|
|
22895
|
+
[NAV_DEPTH_STATE_KEY]: getNavDepth(),
|
|
22809
22896
|
};
|
|
22810
22897
|
if (state === undefined) {
|
|
22811
22898
|
effectiveState = {
|
|
@@ -22936,7 +23023,9 @@ const setupBrowserIntegrationViaHistory = ({
|
|
|
22936
23023
|
e.preventDefault();
|
|
22937
23024
|
handleRoutingTask(href, {
|
|
22938
23025
|
reason: `"click" on a[href="${href}"]`,
|
|
22939
|
-
|
|
23026
|
+
// A link that takes the place of the current entry instead of stacking
|
|
23027
|
+
// on it says so on itself (see link_replace.js).
|
|
23028
|
+
navigationType: linkAsksForReplace(linkElement) ? "replace" : "push",
|
|
22940
23029
|
// Who started it. Announced with the navigation because a press
|
|
22941
23030
|
// carries things the url does not: what a link asks of a route
|
|
22942
23031
|
// transition is the first of them (see route_transition.jsx). Read by
|
|
@@ -23006,8 +23095,18 @@ const setupBrowserIntegrationViaHistory = ({
|
|
|
23006
23095
|
});
|
|
23007
23096
|
};
|
|
23008
23097
|
|
|
23009
|
-
const navBack = () => {
|
|
23010
|
-
|
|
23098
|
+
const navBack = ({ fallback } = {}) => {
|
|
23099
|
+
if (canNavBackSignal.peek()) {
|
|
23100
|
+
window.history.back();
|
|
23101
|
+
return;
|
|
23102
|
+
}
|
|
23103
|
+
if (fallback === undefined) {
|
|
23104
|
+
return;
|
|
23105
|
+
}
|
|
23106
|
+
// Replace, not push: pushing the fallback would put the screen just left
|
|
23107
|
+
// one press ahead, and the device's own back button would walk straight
|
|
23108
|
+
// back into it — a loop with no way out of the app.
|
|
23109
|
+
navTo(fallback, { replace: true });
|
|
23011
23110
|
};
|
|
23012
23111
|
|
|
23013
23112
|
const navForward = () => {
|
|
@@ -23218,6 +23317,21 @@ const stopLoad = (reason = "stopLoad() called") => {
|
|
|
23218
23317
|
}
|
|
23219
23318
|
};
|
|
23220
23319
|
const reload = browserIntegration.reload;
|
|
23320
|
+
/**
|
|
23321
|
+
* Go back to the screen this document came from.
|
|
23322
|
+
*
|
|
23323
|
+
* Only ever within this document: at the bottom of the stack (a url opened
|
|
23324
|
+
* cold — a shared link, a bookmark, a notification), the entry underneath
|
|
23325
|
+
* belongs to whoever sent the reader here, and going back there would take
|
|
23326
|
+
* them out of the app. Ask `canNavBackSignal`/`useCanNavBack()` to know which
|
|
23327
|
+
* of the two cases the arrow is in.
|
|
23328
|
+
*
|
|
23329
|
+
* @param {object} [options]
|
|
23330
|
+
* @param {string} [options.fallback]
|
|
23331
|
+
* Where to land when there is nothing of this document behind. It takes the
|
|
23332
|
+
* place of the current entry rather than stacking on it. Without it, a
|
|
23333
|
+
* navBack() with nowhere to go does nothing.
|
|
23334
|
+
*/
|
|
23221
23335
|
const navBack = browserIntegration.navBack;
|
|
23222
23336
|
const navForward = browserIntegration.navForward;
|
|
23223
23337
|
const isVisited = browserIntegration.isVisited;
|
|
@@ -24908,6 +25022,20 @@ const useUIStateController = (
|
|
|
24908
25022
|
})
|
|
24909
25023
|
: ownUIStateSignal;
|
|
24910
25024
|
|
|
25025
|
+
// The two-way half of a bound `signal` prop: setting it re-renders and
|
|
25026
|
+
// re-syncs via state_prop_change, but with the same value → guarded as a
|
|
25027
|
+
// no-op, so no loop. For a checkbox/radio the signal holds the boolean
|
|
25028
|
+
// checked state.
|
|
25029
|
+
const writeBoundSignal = (uiState) => {
|
|
25030
|
+
const boundSignal = s.controlInfo?.signal;
|
|
25031
|
+
if (!boundSignal) {
|
|
25032
|
+
return;
|
|
25033
|
+
}
|
|
25034
|
+
boundSignal.value = s.controlInfo.signalHoldsChecked
|
|
25035
|
+
? uiState !== undefined
|
|
25036
|
+
: uiState;
|
|
25037
|
+
};
|
|
25038
|
+
|
|
24911
25039
|
const controller = {
|
|
24912
25040
|
controlType,
|
|
24913
25041
|
parentUIStateController,
|
|
@@ -24978,16 +25106,7 @@ const useUIStateController = (
|
|
|
24978
25106
|
}
|
|
24979
25107
|
// Trigger uiAction/command side effects without changing UI state.
|
|
24980
25108
|
const currentUIState = controller.uiState;
|
|
24981
|
-
|
|
24982
|
-
// prop). Setting it re-renders and re-syncs via state_prop_change, but
|
|
24983
|
-
// with the same value → guarded as a no-op, so no loop. For a
|
|
24984
|
-
// checkbox/radio the signal holds the boolean checked state.
|
|
24985
|
-
const boundSignal = s.controlInfo?.signal;
|
|
24986
|
-
if (boundSignal) {
|
|
24987
|
-
boundSignal.value = s.controlInfo.signalHoldsChecked
|
|
24988
|
-
? currentUIState !== undefined
|
|
24989
|
-
: currentUIState;
|
|
24990
|
-
}
|
|
25109
|
+
writeBoundSignal(currentUIState);
|
|
24991
25110
|
s.uiActionInternal?.(currentUIState, e);
|
|
24992
25111
|
if (s.uiAction) {
|
|
24993
25112
|
debugUIState(`calling uiAction for ${controlType}`, currentUIState);
|
|
@@ -25147,6 +25266,11 @@ const useUIStateController = (
|
|
|
25147
25266
|
}
|
|
25148
25267
|
}
|
|
25149
25268
|
if (isInternalEvent(e)) {
|
|
25269
|
+
if (isPropagateDownEvent(e)) {
|
|
25270
|
+
// A bound signal mirrors what the control holds, and what it
|
|
25271
|
+
// holds just changed — see isPropagateDownEvent.
|
|
25272
|
+
writeBoundSignal(newUIState);
|
|
25273
|
+
}
|
|
25150
25274
|
if (e.type === "facade_child_mount_sync") {
|
|
25151
25275
|
const wasEmptyString =
|
|
25152
25276
|
currentUIState === "" && newUIState === undefined;
|
|
@@ -25807,12 +25931,12 @@ const useUIGroupStateController = (
|
|
|
25807
25931
|
// makes from its own setUIState (see useUIStateController's boundSignal),
|
|
25808
25932
|
// for a group whose value is its children's put together.
|
|
25809
25933
|
//
|
|
25810
|
-
// Called from
|
|
25811
|
-
// the change is notified outward, syncInternalState when
|
|
25812
|
-
// brings itself up to date
|
|
25813
|
-
//
|
|
25814
|
-
//
|
|
25815
|
-
//
|
|
25934
|
+
// Called from every path where what the group holds really moves:
|
|
25935
|
+
// applyState when the change is notified outward, syncInternalState when
|
|
25936
|
+
// the group only brings itself up to date, and the value arriving from
|
|
25937
|
+
// above (see isPropagateDownEvent). Which one it is gets decided at each
|
|
25938
|
+
// call site rather than guessed at here — the initial push and the
|
|
25939
|
+
// mount/unmount syncs leave the signal alone.
|
|
25816
25940
|
const writeBoundSignal = (newUIState) => {
|
|
25817
25941
|
const boundSignal = s.props?.signal;
|
|
25818
25942
|
if (boundSignal) {
|
|
@@ -25915,6 +26039,9 @@ const useUIGroupStateController = (
|
|
|
25915
26039
|
return;
|
|
25916
26040
|
}
|
|
25917
26041
|
applyState(groupUIState, e, { internalBehavior: true });
|
|
26042
|
+
if (isPropagateDownEvent(e)) {
|
|
26043
|
+
writeBoundSignal(groupUIState);
|
|
26044
|
+
}
|
|
25918
26045
|
},
|
|
25919
26046
|
syncInternalState: (newUIState) => {
|
|
25920
26047
|
const currentUIState = controller.uiState;
|
|
@@ -26517,6 +26644,27 @@ const isInternalEvent = (e) => {
|
|
|
26517
26644
|
return INTERNAL_EVENT_SET.has(e.type);
|
|
26518
26645
|
};
|
|
26519
26646
|
|
|
26647
|
+
/**
|
|
26648
|
+
* A value handed DOWN to a control by whoever owns it: a picker filling its
|
|
26649
|
+
* popup (on open, and again when Escape puts back what it held), a group
|
|
26650
|
+
* placing its children, a reset cascading through them.
|
|
26651
|
+
*
|
|
26652
|
+
* Internal, so no reaction fires — nobody acted. But the control's state really
|
|
26653
|
+
* did move, and a bound `signal` is that state's mirror rather than a reaction
|
|
26654
|
+
* to it: leaving it behind makes the app and the control disagree about what is
|
|
26655
|
+
* on screen, which is how a popup reopens on the tab the user cancelled out of.
|
|
26656
|
+
* The way UP is deliberately not part of this: a picker's own signal is written
|
|
26657
|
+
* when the picker commits, not while its popup is being played with.
|
|
26658
|
+
*/
|
|
26659
|
+
const PROPAGATE_DOWN_EVENT_SET = new Set([
|
|
26660
|
+
"propagate_down_set_ui_state",
|
|
26661
|
+
"propagate_down_reset_ui_state",
|
|
26662
|
+
"propagate_down_clear_ui_state",
|
|
26663
|
+
]);
|
|
26664
|
+
const isPropagateDownEvent = (e) => {
|
|
26665
|
+
return PROPAGATE_DOWN_EVENT_SET.has(e.type);
|
|
26666
|
+
};
|
|
26667
|
+
|
|
26520
26668
|
/**
|
|
26521
26669
|
* The synthetic "input" event is how the new state reaches the outside world
|
|
26522
26670
|
* (`uiAction` is called from the input handler it triggers). It carries what
|
|
@@ -44333,6 +44481,12 @@ Object.assign(PSEUDO_CLASSES, {
|
|
|
44333
44481
|
* the pair's movement and only turns it round, which is what the rare way
|
|
44334
44482
|
* round a pair usually needs. Said nowhere else, the relations answer as
|
|
44335
44483
|
* they always do.
|
|
44484
|
+
* @param {boolean} [props.replace] - Go to the destination by TAKING THE PLACE
|
|
44485
|
+
* of the current history entry instead of stacking onto it: the link stays a
|
|
44486
|
+
* link (an address, a middle click, the keyboard, `aria-current`), only the
|
|
44487
|
+
* way there changes. What a row of tabs wants — the neighbour is a lateral
|
|
44488
|
+
* move, not a step deeper, so the whole row weighs one entry and the back
|
|
44489
|
+
* button leaves by where the reader came in.
|
|
44336
44490
|
* @param {boolean} [props.preventDefault] - Call `event.preventDefault()` on
|
|
44337
44491
|
* click (navigation suppressed; `onClick` still runs).
|
|
44338
44492
|
* @param {(event: MouseEvent) => void} [props.onClick]
|
|
@@ -44397,6 +44551,7 @@ const LinkPlain = props => {
|
|
|
44397
44551
|
revealOnInteraction = false,
|
|
44398
44552
|
hrefFallback = !anchor,
|
|
44399
44553
|
routeTransition,
|
|
44554
|
+
replace,
|
|
44400
44555
|
children
|
|
44401
44556
|
} = props;
|
|
44402
44557
|
if (anchor && !props.id) {
|
|
@@ -44510,6 +44665,13 @@ const LinkPlain = props => {
|
|
|
44510
44665
|
// a name; anything more travels as JSON, which is also how a plain <a>
|
|
44511
44666
|
// writes it by hand.
|
|
44512
44667
|
const routeTransitionRequest = routeTransition === undefined || routeTransition === null ? undefined : typeof routeTransition === "string" ? routeTransition : JSON.stringify(routeTransition);
|
|
44668
|
+
|
|
44669
|
+
// Which way this link goes to the place it aims at, worn as an attribute so
|
|
44670
|
+
// that whoever answers the press reads it off the anchor (see
|
|
44671
|
+
// link_replace.js, which owns the name and does the reading).
|
|
44672
|
+
const replaceRequest = replace ? {
|
|
44673
|
+
[LINK_REPLACE_ATTRIBUTE]: ""
|
|
44674
|
+
} : null;
|
|
44513
44675
|
const innerChildren = children || (hrefFallback ? href : children);
|
|
44514
44676
|
const startIconEl = startIcon;
|
|
44515
44677
|
const endIconEl = innerEndIcon;
|
|
@@ -44561,7 +44723,9 @@ const LinkPlain = props => {
|
|
|
44561
44723
|
endIcon: undefined,
|
|
44562
44724
|
hrefFallback: undefined,
|
|
44563
44725
|
routeTransition: undefined,
|
|
44726
|
+
replace: undefined,
|
|
44564
44727
|
"data-navi-route-transition-request": routeTransitionRequest,
|
|
44728
|
+
...replaceRequest,
|
|
44565
44729
|
onClick: e => {
|
|
44566
44730
|
onClick?.(e);
|
|
44567
44731
|
if (slide) {
|
|
@@ -52064,8 +52228,8 @@ const causeOfEvent = event => {
|
|
|
52064
52228
|
const readArea = slideElement => slideElement.getAttribute("data-slide-area") || slideElement.id || "";
|
|
52065
52229
|
|
|
52066
52230
|
/**
|
|
52067
|
-
* The slide shown can be driven from outside (`
|
|
52068
|
-
* left to the container, which then answers the
|
|
52231
|
+
* The slide shown can be driven from outside (a `signal`, or `current` +
|
|
52232
|
+
* `onCurrentChange`) or left to the container, which then answers the
|
|
52069
52233
|
* --navi-left/--navi-right/--navi-up/--navi-down commands sent from anything
|
|
52070
52234
|
* inside it.
|
|
52071
52235
|
*
|
|
@@ -52098,6 +52262,15 @@ const readArea = slideElement => slideElement.getAttribute("data-slide-area") ||
|
|
|
52098
52262
|
* written is simply not there.
|
|
52099
52263
|
* @param {string} [props.current] - area (or id) of the slide being shown; omit
|
|
52100
52264
|
* to keep it here and drive it by command.
|
|
52265
|
+
* @param {import("@preact/signals").Signal<string>} [props.signal] - the same
|
|
52266
|
+
* thing said the way every navi control says it: the container shows the area
|
|
52267
|
+
* the signal holds, and writes into it the area it travels to. One binding
|
|
52268
|
+
* instead of `current` + `onCurrentChange`, and the state stays where the app
|
|
52269
|
+
* put it — which is what lets something else read where the slides are (a
|
|
52270
|
+
* field carrying the current tab into a form, see
|
|
52271
|
+
* docs/control_object.md#a-settings-sheet) or move them by writing it.
|
|
52272
|
+
* Excludes `current`; `onCurrentChange` still fires, for the `cause` and for
|
|
52273
|
+
* the right to refuse.
|
|
52101
52274
|
* @param {string} [props.defaultCurrent] - which slide to open on, when the
|
|
52102
52275
|
* travel is left to the container. Mount-only, like every other `default*`:
|
|
52103
52276
|
* it says where one starts, not where one is — say `current` for that.
|
|
@@ -52169,6 +52342,7 @@ const readArea = slideElement => slideElement.getAttribute("data-slide-area") ||
|
|
|
52169
52342
|
const SlideContainer = ({
|
|
52170
52343
|
layout = "row",
|
|
52171
52344
|
current: currentProp,
|
|
52345
|
+
signal: currentSignal,
|
|
52172
52346
|
defaultCurrent,
|
|
52173
52347
|
onCurrentChange,
|
|
52174
52348
|
commit = "now",
|
|
@@ -52267,7 +52441,8 @@ const SlideContainer = ({
|
|
|
52267
52441
|
// draw in CSS alone, at the pace of the travel and under the finger, with
|
|
52268
52442
|
// nothing measured per frame.
|
|
52269
52443
|
const followerElementsRef = useRef([]);
|
|
52270
|
-
const
|
|
52444
|
+
const currentFromCaller = currentSignal ? currentSignal.value : currentProp;
|
|
52445
|
+
const current = rollingArea ?? provisionalArea ?? currentFromCaller ?? currentAreaState;
|
|
52271
52446
|
const vertical = layout === "column";
|
|
52272
52447
|
// What the map has, and what each way of asking is allowed to use of it.
|
|
52273
52448
|
const mapAxes = travelAxesOf(layout);
|
|
@@ -52302,11 +52477,11 @@ const SlideContainer = ({
|
|
|
52302
52477
|
if (provisionalArea === null) {
|
|
52303
52478
|
return;
|
|
52304
52479
|
}
|
|
52305
|
-
const heldOutside =
|
|
52480
|
+
const heldOutside = currentFromCaller ?? currentAreaState;
|
|
52306
52481
|
if (heldOutside === provisionalArea) {
|
|
52307
52482
|
setProvisionalArea(null);
|
|
52308
52483
|
}
|
|
52309
|
-
}, [provisionalArea,
|
|
52484
|
+
}, [provisionalArea, currentFromCaller, currentAreaState]);
|
|
52310
52485
|
|
|
52311
52486
|
// The travel is given back as soon as the picture it must not animate has
|
|
52312
52487
|
// been painted: one frame with it off is all it takes.
|
|
@@ -52483,10 +52658,10 @@ const SlideContainer = ({
|
|
|
52483
52658
|
const commitAtRest = commitAtRestRef.current;
|
|
52484
52659
|
if (commitAtRest && commitAtRest.area === currentArea) {
|
|
52485
52660
|
commitAtRestRef.current = null;
|
|
52486
|
-
|
|
52661
|
+
tellCurrentChange(commitAtRest.area, {
|
|
52487
52662
|
cause: commitAtRest.cause,
|
|
52488
52663
|
event: commitAtRest.event
|
|
52489
|
-
}
|
|
52664
|
+
}, commitAtRest.leftArea);
|
|
52490
52665
|
}
|
|
52491
52666
|
};
|
|
52492
52667
|
|
|
@@ -52860,7 +53035,7 @@ const SlideContainer = ({
|
|
|
52860
53035
|
}
|
|
52861
53036
|
const leftArea = readArea(currentElement);
|
|
52862
53037
|
setCurrentAreaState(area);
|
|
52863
|
-
if (!onCurrentChange) {
|
|
53038
|
+
if (!onCurrentChange && !currentSignal) {
|
|
52864
53039
|
return true;
|
|
52865
53040
|
}
|
|
52866
53041
|
// What asked for this, read off the interaction rather than carried down
|
|
@@ -52884,13 +53059,26 @@ const SlideContainer = ({
|
|
|
52884
53059
|
};
|
|
52885
53060
|
return true;
|
|
52886
53061
|
}
|
|
52887
|
-
|
|
53062
|
+
tellCurrentChange(area, {
|
|
52888
53063
|
cause,
|
|
52889
53064
|
event
|
|
52890
|
-
}
|
|
53065
|
+
}, leftArea);
|
|
52891
53066
|
return true;
|
|
52892
53067
|
};
|
|
52893
53068
|
|
|
53069
|
+
// The caller learns where the container went: the bound signal is written and
|
|
53070
|
+
// `onCurrentChange` is called, in that order, so a caller reading the signal
|
|
53071
|
+
// from inside its own handler reads where it now is.
|
|
53072
|
+
const tellCurrentChange = (area, detail, leftArea) => {
|
|
53073
|
+
if (currentSignal) {
|
|
53074
|
+
currentSignal.value = area;
|
|
53075
|
+
}
|
|
53076
|
+
if (!onCurrentChange) {
|
|
53077
|
+
return;
|
|
53078
|
+
}
|
|
53079
|
+
answerCurrentChange(onCurrentChange(area, detail), leftArea);
|
|
53080
|
+
};
|
|
53081
|
+
|
|
52894
53082
|
// What a caller says back about a change it was told about: nothing, or a
|
|
52895
53083
|
// refusal. `false` refuses it — a guard that says no, a session that is gone —
|
|
52896
53084
|
// and a promise refuses it late, once whatever it had to ask has answered. A
|
|
@@ -52912,6 +53100,9 @@ const SlideContainer = ({
|
|
|
52912
53100
|
const goBackToRefusedArea = leftArea => {
|
|
52913
53101
|
setProvisionalArea(null);
|
|
52914
53102
|
setCurrentAreaState(leftArea);
|
|
53103
|
+
if (currentSignal) {
|
|
53104
|
+
currentSignal.value = leftArea;
|
|
53105
|
+
}
|
|
52915
53106
|
};
|
|
52916
53107
|
|
|
52917
53108
|
// The press kept during a roll, taken once the window rests and the travel is
|
|
@@ -75172,5 +75363,5 @@ const UserSvg = () => jsx("svg", {
|
|
|
75172
75363
|
})
|
|
75173
75364
|
});
|
|
75174
75365
|
|
|
75175
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTransitionArea, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeSpin, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, coarsePointerSignal, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, defineRouteDefaultTransition, defineRouteTransition, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
75366
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTransitionArea, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeSpin, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, canNavBackSignal, canNavForwardSignal, coarsePointerSignal, compareTwoJsValues, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineNaviConfirmPopupOptions, defineRouteDefaultTransition, defineRouteTransition, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutRequestClose, useCanNavBack, useCanNavForward, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
75176
75367
|
//# sourceMappingURL=jsenv_navi.js.map
|