@sigx/lynx-navigation 0.4.4 → 0.4.5
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/components/Layer.d.ts +18 -11
- package/dist/components/Layer.d.ts.map +1 -1
- package/dist/components/Layer.js +33 -21
- package/dist/components/Layer.js.map +1 -1
- package/dist/components/NavigationRoot.d.ts +9 -1
- package/dist/components/NavigationRoot.d.ts.map +1 -1
- package/dist/components/NavigationRoot.js +12 -1
- package/dist/components/NavigationRoot.js.map +1 -1
- package/dist/components/Stack.d.ts +19 -7
- package/dist/components/Stack.d.ts.map +1 -1
- package/dist/components/Stack.js +28 -15
- package/dist/components/Stack.js.map +1 -1
- package/dist/hooks/use-hardware-back.d.ts +30 -12
- package/dist/hooks/use-hardware-back.d.ts.map +1 -1
- package/dist/hooks/use-hardware-back.js +99 -54
- package/dist/hooks/use-hardware-back.js.map +1 -1
- package/dist/internal/layer-plan.d.ts +56 -30
- package/dist/internal/layer-plan.d.ts.map +1 -1
- package/dist/internal/layer-plan.js +84 -48
- package/dist/internal/layer-plan.js.map +1 -1
- package/dist/navigator/core.d.ts.map +1 -1
- package/dist/navigator/core.js +41 -21
- package/dist/navigator/core.js.map +1 -1
- package/package.json +10 -10
- package/src/components/Layer.tsx +41 -22
- package/src/components/NavigationRoot.tsx +21 -1
- package/src/components/Stack.tsx +58 -14
- package/src/hooks/use-hardware-back.ts +102 -54
- package/src/internal/layer-plan.ts +128 -75
- package/src/navigator/core.ts +42 -21
|
@@ -5,17 +5,16 @@
|
|
|
5
5
|
* by a `SharedValue<number>` from the navigator's transition state.
|
|
6
6
|
*
|
|
7
7
|
* `<Stack>` emits one `<Layer>` per entry returned by
|
|
8
|
-
* `computeLayers(...)`. Layer.key in the parent is
|
|
9
|
-
*
|
|
8
|
+
* `computeLayers(...)`. Layer.key in the parent is `layer-${entry.key}` —
|
|
9
|
+
* stable for the entry's whole life. The host view, `<EntryScope>`, and the
|
|
10
|
+
* screen component therefore stay mounted across every animation phase
|
|
11
|
+
* (animated → static, push/pop transitions), so a screen's `onMounted` /
|
|
12
|
+
* data fetches fire exactly once per navigation and no state is lost.
|
|
10
13
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* top after its push transition completes) remounts so the
|
|
16
|
-
* `useAnimatedStyle` binding can be rebound — the underlying
|
|
17
|
-
* `useAnimatedStyle` is set-once at setup and can't switch its
|
|
18
|
-
* mapper at runtime.
|
|
14
|
+
* The transform binding is the only thing that changes as the layer animates
|
|
15
|
+
* vs rests: it's driven by the *reactive* form of `useAnimatedStyle`, which
|
|
16
|
+
* (re)registers/unregisters the MT style binding on this same element as
|
|
17
|
+
* `props.animation` flips between a spec and `null`. No remount needed.
|
|
19
18
|
*
|
|
20
19
|
* Layouts:
|
|
21
20
|
* - Host view is `position: absolute; top/right/bottom/left: 0;
|
|
@@ -29,6 +28,14 @@ import type { LayerAnimation } from '../internal/layer-plan.js';
|
|
|
29
28
|
import type { RouteMap, StackEntry } from '../types.js';
|
|
30
29
|
export type LayerProps = Define.Prop<'entry', StackEntry, true> & Define.Prop<'routes', RouteMap, true>
|
|
31
30
|
/** When set, the host view animates per the transform spec. */
|
|
32
|
-
& Define.Prop<'animation', LayerAnimation | null, false
|
|
31
|
+
& Define.Prop<'animation', LayerAnimation | null, false>
|
|
32
|
+
/**
|
|
33
|
+
* Retained-but-covered layer: render with `display: none` so the
|
|
34
|
+
* screen subtree stays mounted (state/scroll preserved) without
|
|
35
|
+
* costing paint/layout while a higher opaque card covers it.
|
|
36
|
+
* Toggling this is a style change on the stable host view — never a
|
|
37
|
+
* remount. Mirrors how `<Tabs>` hides inactive tab bodies.
|
|
38
|
+
*/
|
|
39
|
+
& Define.Prop<'hidden', boolean, false>;
|
|
33
40
|
export declare const Layer: ComponentFactory<LayerProps, void, {}>;
|
|
34
41
|
//# sourceMappingURL=Layer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layer.d.ts","sourceRoot":"","sources":["../../src/components/Layer.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Layer.d.ts","sourceRoot":"","sources":["../../src/components/Layer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAIH,KAAK,gBAAgB,EACrB,KAAK,MAAM,EAEd,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGxD,MAAM,MAAM,UAAU,GAChB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,GACtC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC;AACvC,+DAA+D;GAC7D,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,GAAG,IAAI,EAAE,KAAK,CAAC;AACxD;;;;;;GAMG;GACD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAE5C,eAAO,MAAM,KAAK,wCA8DhB,CAAC"}
|
package/dist/components/Layer.js
CHANGED
|
@@ -6,17 +6,16 @@ import { jsx as _jsx } from "@sigx/lynx/jsx-runtime";
|
|
|
6
6
|
* by a `SharedValue<number>` from the navigator's transition state.
|
|
7
7
|
*
|
|
8
8
|
* `<Stack>` emits one `<Layer>` per entry returned by
|
|
9
|
-
* `computeLayers(...)`. Layer.key in the parent is
|
|
10
|
-
*
|
|
9
|
+
* `computeLayers(...)`. Layer.key in the parent is `layer-${entry.key}` —
|
|
10
|
+
* stable for the entry's whole life. The host view, `<EntryScope>`, and the
|
|
11
|
+
* screen component therefore stay mounted across every animation phase
|
|
12
|
+
* (animated → static, push/pop transitions), so a screen's `onMounted` /
|
|
13
|
+
* data fetches fire exactly once per navigation and no state is lost.
|
|
11
14
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* top after its push transition completes) remounts so the
|
|
17
|
-
* `useAnimatedStyle` binding can be rebound — the underlying
|
|
18
|
-
* `useAnimatedStyle` is set-once at setup and can't switch its
|
|
19
|
-
* mapper at runtime.
|
|
15
|
+
* The transform binding is the only thing that changes as the layer animates
|
|
16
|
+
* vs rests: it's driven by the *reactive* form of `useAnimatedStyle`, which
|
|
17
|
+
* (re)registers/unregisters the MT style binding on this same element as
|
|
18
|
+
* `props.animation` flips between a spec and `null`. No remount needed.
|
|
20
19
|
*
|
|
21
20
|
* Layouts:
|
|
22
21
|
* - Host view is `position: absolute; top/right/bottom/left: 0;
|
|
@@ -30,17 +29,27 @@ import { Suspense, isLazyComponent } from '@sigx/lynx';
|
|
|
30
29
|
import { EntryScope } from './EntryScope.js';
|
|
31
30
|
export const Layer = component(({ props }) => {
|
|
32
31
|
const ref = useMainThreadRef(null);
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
|
|
32
|
+
// Reactive binding: the Layer's key is stable for the entry's life, so
|
|
33
|
+
// `props.animation` changes (spec ↔ null) at runtime as the layer
|
|
34
|
+
// animates and then settles. The reactive `useAnimatedStyle` re-binds the
|
|
35
|
+
// MT transform on this same element each time, leaving the host view and
|
|
36
|
+
// the screen subtree mounted throughout. Going static returns `null`,
|
|
37
|
+
// which unregisters the binding (required: the navigator reuses one
|
|
38
|
+
// shared progress SharedValue that resets to 0 on the next transition, so
|
|
39
|
+
// a resting layer must not stay bound).
|
|
40
|
+
useAnimatedStyle(ref, () => {
|
|
38
41
|
const a = props.animation;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (!a)
|
|
43
|
+
return null;
|
|
44
|
+
return {
|
|
45
|
+
sv: a.progress,
|
|
46
|
+
mapperName: a.axis,
|
|
47
|
+
params: {
|
|
48
|
+
inputRange: [a.inputRange[0], a.inputRange[1]],
|
|
49
|
+
outputRange: [a.outputRange[0], a.outputRange[1]],
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
});
|
|
44
53
|
return () => {
|
|
45
54
|
const route = props.routes[props.entry.route];
|
|
46
55
|
if (!route)
|
|
@@ -58,7 +67,10 @@ export const Layer = component(({ props }) => {
|
|
|
58
67
|
left: '0',
|
|
59
68
|
right: '0',
|
|
60
69
|
bottom: '0',
|
|
61
|
-
|
|
70
|
+
// `none` keeps a covered card mounted but unpainted;
|
|
71
|
+
// reading `props.hidden` here re-renders (no remount)
|
|
72
|
+
// when the layer is covered/revealed.
|
|
73
|
+
display: props.hidden ? 'none' : 'flex',
|
|
62
74
|
flexDirection: 'column',
|
|
63
75
|
}, children: _jsx(EntryScope, { entry: props.entry, children: body }, props.entry.key) }));
|
|
64
76
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layer.js","sourceRoot":"","sources":["../../src/components/Layer.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"Layer.js","sourceRoot":"","sources":["../../src/components/Layer.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACH,SAAS,EACT,gBAAgB,EAChB,gBAAgB,GAInB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGvD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAgB7C,MAAM,CAAC,MAAM,KAAK,GAAG,SAAS,CAAa,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACrD,MAAM,GAAG,GAAG,gBAAgB,CAA4B,IAAI,CAAC,CAAC;IAC9D,uEAAuE;IACvE,kEAAkE;IAClE,0EAA0E;IAC1E,yEAAyE;IACzE,sEAAsE;IACtE,oEAAoE;IACpE,0EAA0E;IAC1E,wCAAwC;IACxC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE;QACvB,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;QAC1B,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,OAAO;YACH,EAAE,EAAE,CAAC,CAAC,QAAQ;YACd,UAAU,EAAE,CAAC,CAAC,IAAI;YAClB,MAAM,EAAE;gBACJ,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC9C,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;aACpD;SACJ,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACR,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,SAIlB,CAAC;QACF,IAAI,OAAO,IAAI,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC;QAC5C,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,MAAiC,CAAC;QAClE,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ;YAChD,CAAC,CAAC,CACE,KAAC,QAAQ,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAiB,YACvC,KAAC,IAAI,OAAK,WAAW,GAAI,GAClB,CACd;YACD,CAAC,CAAC,KAAC,IAAI,OAAK,WAAW,GAAI,CAAC;QAChC,OAAO,CACH,kCACqB,GAAG,EACpB,KAAK,EAAE;gBACH,QAAQ,EAAE,UAAU;gBACpB,GAAG,EAAE,GAAG;gBACR,IAAI,EAAE,GAAG;gBACT,KAAK,EAAE,GAAG;gBACV,MAAM,EAAE,GAAG;gBACX,qDAAqD;gBACrD,sDAAsD;gBACtD,sCAAsC;gBACtC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;gBACvC,aAAa,EAAE,QAAQ;aAC1B,YAED,KAAC,UAAU,IAAuB,KAAK,EAAE,KAAK,CAAC,KAAK,YAC/C,IAAI,IADQ,KAAK,CAAC,KAAK,CAAC,GAAG,CAEnB,GACV,CACV,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC,CAAC"}
|
|
@@ -13,7 +13,15 @@ type NavigationRootProps = Define.Prop<'routes', RouteMap, true> & Define.Prop<'
|
|
|
13
13
|
* to false if it conflicts with screen content on the leftmost 20px,
|
|
14
14
|
* or while debugging gesture issues.
|
|
15
15
|
*/
|
|
16
|
-
& Define.Prop<'edgeSwipeEnabled', boolean>
|
|
16
|
+
& Define.Prop<'edgeSwipeEnabled', boolean>
|
|
17
|
+
/**
|
|
18
|
+
* Subscribe the Android hardware back button / system back gesture to
|
|
19
|
+
* this navigator. Defaults to true — a back press pops the deepest
|
|
20
|
+
* focused stack, falling through to `exitApp()` only at the base entry.
|
|
21
|
+
* Set to false to handle hardware back yourself (then call
|
|
22
|
+
* `useHardwareBack()` in your own component). No-op on iOS.
|
|
23
|
+
*/
|
|
24
|
+
& Define.Prop<'hardwareBack', boolean> & Define.Slot<'default'>;
|
|
17
25
|
/**
|
|
18
26
|
* Root of a navigator subtree.
|
|
19
27
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationRoot.d.ts","sourceRoot":"","sources":["../../src/components/NavigationRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"NavigationRoot.d.ts","sourceRoot":"","sources":["../../src/components/NavigationRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoE,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAK3G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAgB,QAAQ,EAAc,MAAM,aAAa,CAAC;AAGtE,KAAK,mBAAmB,GAClB,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,GACrC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GACpC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACrD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD;;;;GAIG;GACD,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC;AAClC;;;;GAIG;GACD,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC;AAC1C;;;;;;GAMG;GACD,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GACpC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAE7B;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;EA4DzB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { component, defineProvide, useSharedValue } from '@sigx/lynx';
|
|
1
|
+
import { component, defineProvide, onMounted, onUnmounted, useSharedValue } from '@sigx/lynx';
|
|
2
2
|
import { createNavigatorState } from '../navigator/core.js';
|
|
3
3
|
import { useNav } from '../hooks/use-nav.js';
|
|
4
|
+
import { wireHardwareBack } from '../hooks/use-hardware-back.js';
|
|
4
5
|
import { useNavInternals, useNavRoutes } from '../hooks/use-nav-internal.js';
|
|
5
6
|
import { _setRouteRegistry } from '../url/registry.js';
|
|
6
7
|
/**
|
|
@@ -62,6 +63,16 @@ export const NavigationRoot = component(({ props, slots }) => {
|
|
|
62
63
|
edgeSwipeEnabled,
|
|
63
64
|
screens: navState._screens,
|
|
64
65
|
}));
|
|
66
|
+
// Auto-wire Android hardware/system back unless opted out. Without this,
|
|
67
|
+
// the OS back gesture fires `hardwareBackPress` but nothing pops — every
|
|
68
|
+
// app would otherwise have to remember to call `useHardwareBack()`.
|
|
69
|
+
// Idempotent per tree (see `wireHardwareBack`), so a manual call still
|
|
70
|
+
// works and never double-pops. No-op on iOS / non-native runtimes.
|
|
71
|
+
if (props.hardwareBack !== false) {
|
|
72
|
+
let dispose = () => { };
|
|
73
|
+
onMounted(() => { dispose = wireHardwareBack(navState.nav); });
|
|
74
|
+
onUnmounted(() => { dispose(); });
|
|
75
|
+
}
|
|
65
76
|
return () => slots.default?.();
|
|
66
77
|
});
|
|
67
78
|
//# sourceMappingURL=NavigationRoot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationRoot.js","sourceRoot":"","sources":["../../src/components/NavigationRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAe,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"NavigationRoot.js","sourceRoot":"","sources":["../../src/components/NavigationRoot.tsx"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,17 @@ Define.Prop<'initialRoute', string>
|
|
|
18
18
|
& Define.Prop<'initialParams', Record<string, unknown>>
|
|
19
19
|
/** Initial search for the nested-stack base entry. */
|
|
20
20
|
& Define.Prop<'initialSearch', Record<string, unknown>>
|
|
21
|
+
/**
|
|
22
|
+
* Max number of *covered* cards kept mounted-but-hidden beneath the
|
|
23
|
+
* visible top (card-stack screen retention). Covered cards stay
|
|
24
|
+
* mounted so back-navigation reveals them instantly with state
|
|
25
|
+
* intact, instead of rebuilding. Omit to retain all (bounded only by
|
|
26
|
+
* the renderer's `MAX_LAYERS` slot cap). Set a small number to bound
|
|
27
|
+
* memory — the deepest covered cards beyond the window unmount and
|
|
28
|
+
* rebuild on pop-back. Mirrors React Navigation's
|
|
29
|
+
* `detachInactiveScreens` / `maxRetainedScreens`.
|
|
30
|
+
*/
|
|
31
|
+
& Define.Prop<'maxRetainedScreens', number>
|
|
21
32
|
/**
|
|
22
33
|
* Optional chrome rendered *above* the active screen, **inside this
|
|
23
34
|
* Stack's nav scope**. The intended use is `<Header />`, which needs
|
|
@@ -76,13 +87,14 @@ Define.Prop<'initialRoute', string>
|
|
|
76
87
|
* transform. After settle, the overlay either joins the static
|
|
77
88
|
* idle stack (push) or unmounts (pop).
|
|
78
89
|
*
|
|
79
|
-
* Layer keys are `layer-${entry.key}
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
90
|
+
* Layer keys are `layer-${entry.key}` — stable for the entry's whole
|
|
91
|
+
* life. A layer is never remounted just because its animation state
|
|
92
|
+
* changes; instead `<Layer>` drives the *reactive* `useAnimatedStyle`,
|
|
93
|
+
* which re-binds the MT transform on the same element as the entry
|
|
94
|
+
* animates and then settles. So a single push mounts the target screen
|
|
95
|
+
* exactly once (one `onMounted`, one data fetch) and the underneath /
|
|
96
|
+
* modal-underneath subtrees (per-tab Stack navigators, scroll positions,
|
|
97
|
+
* in-flight inputs) survive the whole transition.
|
|
86
98
|
*/
|
|
87
99
|
export declare const Stack: import("@sigx/runtime-core").ComponentFactory<StackProps, void, {
|
|
88
100
|
default: () => import("@sigx/runtime-core").JSXElement | import("@sigx/runtime-core").JSXElement[] | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../src/components/Stack.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOH,KAAK,MAAM,EACd,MAAM,YAAY,CAAC;AAepB,KAAK,UAAU;AACX;;;;;;;;;;;;GAYG;AACD,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC;AACrC,sDAAsD;GACpD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD,sDAAsD;GACpD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD;;;;;;;;;;GAUG;GACD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../src/components/Stack.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOH,KAAK,MAAM,EACd,MAAM,YAAY,CAAC;AAepB,KAAK,UAAU;AACX;;;;;;;;;;;;GAYG;AACD,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC;AACrC,sDAAsD;GACpD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD,sDAAsD;GACpD,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD;;;;;;;;;GASG;GACD,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC;AAC3C;;;;;;;;;;GAUG;GACD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAoB7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,KAAK;;EAuQhB,CAAC"}
|
package/dist/components/Stack.js
CHANGED
|
@@ -3,11 +3,21 @@ import { component, defineProvide, effect, onUnmounted, untrack, useSharedValue,
|
|
|
3
3
|
import { createNavigatorState } from '../navigator/core.js';
|
|
4
4
|
import { useNav } from '../hooks/use-nav.js';
|
|
5
5
|
import { useCurrentEntry, useNavInternals, useNavRoutes, } from '../hooks/use-nav-internal.js';
|
|
6
|
-
import {
|
|
6
|
+
import { computeLayers, isOverlayPresentation } from '../internal/layer-plan.js';
|
|
7
7
|
import { EdgeBackHandle } from './EdgeBackHandle.js';
|
|
8
8
|
import { Layer } from './Layer.js';
|
|
9
9
|
import { useTabScreenName, useTabs } from './Tabs.js';
|
|
10
10
|
let _nestedKeyCounter = 0;
|
|
11
|
+
/**
|
|
12
|
+
* Number of `renderLayerNode(layers[n])` slots unrolled in the render
|
|
13
|
+
* below. Must equal `MAX_LAYERS` — `computeLayers` trims its output to
|
|
14
|
+
* `MAX_LAYERS`, so any layer beyond this count would be silently
|
|
15
|
+
* dropped. The type-level check fails to compile if the two drift, so
|
|
16
|
+
* raising `MAX_LAYERS` forces you to add matching slots here.
|
|
17
|
+
*/
|
|
18
|
+
const RENDERED_LAYER_SLOTS = 24;
|
|
19
|
+
const _slotCountOk = true;
|
|
20
|
+
void _slotCountOk;
|
|
11
21
|
/**
|
|
12
22
|
* Stack navigator — renders the topmost stack entry's component at rest, or
|
|
13
23
|
* the top + underneath entries during a transition.
|
|
@@ -54,13 +64,14 @@ let _nestedKeyCounter = 0;
|
|
|
54
64
|
* transform. After settle, the overlay either joins the static
|
|
55
65
|
* idle stack (push) or unmounts (pop).
|
|
56
66
|
*
|
|
57
|
-
* Layer keys are `layer-${entry.key}
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
67
|
+
* Layer keys are `layer-${entry.key}` — stable for the entry's whole
|
|
68
|
+
* life. A layer is never remounted just because its animation state
|
|
69
|
+
* changes; instead `<Layer>` drives the *reactive* `useAnimatedStyle`,
|
|
70
|
+
* which re-binds the MT transform on the same element as the entry
|
|
71
|
+
* animates and then settles. So a single push mounts the target screen
|
|
72
|
+
* exactly once (one `onMounted`, one data fetch) and the underneath /
|
|
73
|
+
* modal-underneath subtrees (per-tab Stack navigators, scroll positions,
|
|
74
|
+
* in-flight inputs) survive the whole transition.
|
|
64
75
|
*/
|
|
65
76
|
export const Stack = component(({ props, slots }) => {
|
|
66
77
|
// Capture enclosing scope's nav + routes + internals BEFORE any of the
|
|
@@ -200,8 +211,8 @@ export const Stack = component(({ props, slots }) => {
|
|
|
200
211
|
};
|
|
201
212
|
return () => {
|
|
202
213
|
const chrome = slots.default?.();
|
|
203
|
-
const layers = computeLayers(nav.stack, nav.transition, internals.progress);
|
|
204
|
-
const renderLayerNode = (layer) => layer ? (_jsx(Layer, { entry: layer.entry, routes: routes, animation: layer.animation }, `layer-${layer.entry.key}
|
|
214
|
+
const layers = computeLayers(nav.stack, nav.transition, internals.progress, props.maxRetainedScreens);
|
|
215
|
+
const renderLayerNode = (layer) => layer ? (_jsx(Layer, { entry: layer.entry, routes: routes, animation: layer.animation, hidden: layer.hidden }, `layer-${layer.entry.key}`)) : null;
|
|
205
216
|
// sigx's reconciler treats a single array-valued JSX child as
|
|
206
217
|
// one "slot": when the array's *length* changes between
|
|
207
218
|
// renders, keyed children inside can be remounted even if
|
|
@@ -211,10 +222,12 @@ export const Stack = component(({ props, slots }) => {
|
|
|
211
222
|
// JSX child slot rather than as an array. The slots are
|
|
212
223
|
// position-stable across renders — the only thing that
|
|
213
224
|
// changes is a slot turning from `null` to a Layer (mount) or
|
|
214
|
-
// vice versa (unmount).
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
//
|
|
225
|
+
// vice versa (unmount). The slot count MUST equal MAX_LAYERS
|
|
226
|
+
// (the cap `computeLayers` trims to); card retention keeps
|
|
227
|
+
// covered cards mounted, so the slots now also hold a deep
|
|
228
|
+
// card history, not just 2-3 overlays. If you raise MAX_LAYERS,
|
|
229
|
+
// add matching slots below — the unrolled shape is just
|
|
230
|
+
// verbose, not algorithmically limited.
|
|
218
231
|
// Edge-swipe handle on top, gated on:
|
|
219
232
|
// - `internals.edgeSwipeEnabled` — opt-out flag (also off
|
|
220
233
|
// when the navigator has no progress SharedValue, i.e.
|
|
@@ -248,7 +261,7 @@ export const Stack = component(({ props, slots }) => {
|
|
|
248
261
|
// screen so the slide doesn't bleed past the
|
|
249
262
|
// Stack's bounds.
|
|
250
263
|
overflow: 'hidden',
|
|
251
|
-
}, children: [renderLayerNode(layers[0]), renderLayerNode(layers[1]), renderLayerNode(layers[2]), renderLayerNode(layers[3]), renderLayerNode(layers[4]), renderLayerNode(layers[5]), renderLayerNode(layers[6]), renderLayerNode(layers[7]), renderLayerNode(layers[8]), renderLayerNode(layers[9]), renderLayerNode(layers[10]), renderLayerNode(layers[11]), renderLayerNode(layers[12]), renderLayerNode(layers[13]), renderLayerNode(layers[14]), renderLayerNode(layers[15]), edgeHandle] }));
|
|
264
|
+
}, children: [renderLayerNode(layers[0]), renderLayerNode(layers[1]), renderLayerNode(layers[2]), renderLayerNode(layers[3]), renderLayerNode(layers[4]), renderLayerNode(layers[5]), renderLayerNode(layers[6]), renderLayerNode(layers[7]), renderLayerNode(layers[8]), renderLayerNode(layers[9]), renderLayerNode(layers[10]), renderLayerNode(layers[11]), renderLayerNode(layers[12]), renderLayerNode(layers[13]), renderLayerNode(layers[14]), renderLayerNode(layers[15]), renderLayerNode(layers[16]), renderLayerNode(layers[17]), renderLayerNode(layers[18]), renderLayerNode(layers[19]), renderLayerNode(layers[20]), renderLayerNode(layers[21]), renderLayerNode(layers[22]), renderLayerNode(layers[23]), edgeHandle] }));
|
|
252
265
|
if (chrome == null)
|
|
253
266
|
return body;
|
|
254
267
|
return (_jsxs("view", { style: flexColumnFill, children: [chrome, _jsx("view", { style: flexColumnFill, children: body })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Stack.js","sourceRoot":"","sources":["../../src/components/Stack.tsx"],"names":[],"mappings":";AAAA,OAAO,EACH,SAAS,EACT,aAAa,EACb,MAAM,EACN,WAAW,EACX,OAAO,EACP,cAAc,GAEjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAY,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACH,eAAe,EACf,eAAe,EACf,YAAY,GAEf,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Stack.js","sourceRoot":"","sources":["../../src/components/Stack.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,25 +1,43 @@
|
|
|
1
|
+
import { type Nav } from './use-nav.js';
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
+
* Subscribe the Android hardware back button/gesture to a navigator tree.
|
|
3
4
|
*
|
|
4
5
|
* Listens for `hardwareBackPress` events from `@sigx/lynx-linking`'s
|
|
5
6
|
* `BackHandler` (which the native side dispatches from
|
|
6
|
-
* `MainActivity.onBackPressed`). On press the handler walks
|
|
7
|
-
* deepest currently-focused navigator (per-tab `<Stack>`s
|
|
8
|
-
* their parent), then walks back up the `parent` chain looking
|
|
9
|
-
* first nav that `canGoBack`:
|
|
7
|
+
* `MainActivity.onBackPressed`). On press the handler walks from the tree's
|
|
8
|
+
* root to the deepest currently-focused navigator (per-tab `<Stack>`s
|
|
9
|
+
* register with their parent), then walks back up the `parent` chain looking
|
|
10
|
+
* for the first nav that `canGoBack`:
|
|
10
11
|
*
|
|
11
12
|
* - If any nav in the chain can go back → `nav.pop()` on that nav.
|
|
12
13
|
* - Otherwise → `BackHandler.exitApp()` (Android: `moveTaskToBack(true)`,
|
|
13
14
|
* keeps the bundle warm; iOS: rejects, since iOS doesn't permit
|
|
14
15
|
* programmatic termination).
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* **Idempotent per tree.** Only the first registration for a given root
|
|
18
|
+
* actually subscribes; later calls return a no-op disposer. So `<NavigationRoot>`
|
|
19
|
+
* auto-wiring this and an app calling `useHardwareBack()` coexist without
|
|
20
|
+
* double-popping.
|
|
21
|
+
*
|
|
22
|
+
* Returns a disposer that unsubscribes (and frees the root for re-wiring).
|
|
23
|
+
* No-op on iOS (event never fires) and in non-native environments (no
|
|
24
|
+
* `GlobalEventEmitter`, e.g. web/SSR/tests) — `addEventListener` returns a
|
|
25
|
+
* no-op subscription there.
|
|
26
|
+
*
|
|
27
|
+
* @internal Apps should rely on `<NavigationRoot>`'s default or call
|
|
28
|
+
* `useHardwareBack()`; this raw form exists so the root can wire from setup.
|
|
29
|
+
*/
|
|
30
|
+
export declare function wireHardwareBack(nav: Nav): () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Wire the Android hardware back button to the active navigator.
|
|
33
|
+
*
|
|
34
|
+
* `<NavigationRoot>` already does this by default (see its `hardwareBack`
|
|
35
|
+
* prop). Use this hook only when you've opted out (`hardwareBack={false}`)
|
|
36
|
+
* and want to wire it yourself — it's safe to call regardless thanks to the
|
|
37
|
+
* idempotency in {@link wireHardwareBack}.
|
|
19
38
|
*
|
|
20
|
-
* Call
|
|
21
|
-
*
|
|
22
|
-
* hook is a no-op there.
|
|
39
|
+
* Call it once in any component under `<NavigationRoot>`. iOS doesn't fire
|
|
40
|
+
* the event so the hook is a no-op there.
|
|
23
41
|
*
|
|
24
42
|
* @example
|
|
25
43
|
* ```tsx
|
|
@@ -28,7 +46,7 @@
|
|
|
28
46
|
* return () => null;
|
|
29
47
|
* });
|
|
30
48
|
*
|
|
31
|
-
* <NavigationRoot routes={routes}>
|
|
49
|
+
* <NavigationRoot routes={routes} hardwareBack={false}>
|
|
32
50
|
* <BackHandlerWiring />
|
|
33
51
|
* <Stack />
|
|
34
52
|
* </NavigationRoot>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hardware-back.d.ts","sourceRoot":"","sources":["../../src/hooks/use-hardware-back.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-hardware-back.d.ts","sourceRoot":"","sources":["../../src/hooks/use-hardware-back.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,GAAG,EAAE,MAAM,cAAc,CAAC;AAmBhD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,IAAI,CAiDrD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAOtC"}
|