@sigx/lynx-navigation 0.4.0 → 0.4.1
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/Drawer.js +74 -0
- package/dist/components/Drawer.js.map +1 -0
- package/dist/components/EdgeBackHandle.js +144 -0
- package/dist/components/EdgeBackHandle.js.map +1 -0
- package/dist/components/EntryScope.d.ts +1 -1
- package/dist/components/EntryScope.d.ts.map +1 -1
- package/dist/components/EntryScope.js +39 -0
- package/dist/components/EntryScope.js.map +1 -0
- package/dist/components/Header.js +103 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/Layer.d.ts +2 -2
- package/dist/components/Layer.d.ts.map +1 -1
- package/dist/components/Layer.js +66 -0
- package/dist/components/Layer.js.map +1 -0
- package/dist/components/Link.d.ts +2 -2
- package/dist/components/Link.d.ts.map +1 -1
- package/dist/components/Link.js +51 -0
- package/dist/components/Link.js.map +1 -0
- package/dist/components/NavigationRoot.d.ts +2 -2
- package/dist/components/NavigationRoot.d.ts.map +1 -1
- package/dist/components/NavigationRoot.js +67 -0
- package/dist/components/NavigationRoot.js.map +1 -0
- package/dist/components/Screen.js +98 -0
- package/dist/components/Screen.js.map +1 -0
- package/dist/components/Stack.js +257 -0
- package/dist/components/Stack.js.map +1 -0
- package/dist/components/TabBar.d.ts +1 -1
- package/dist/components/TabBar.d.ts.map +1 -1
- package/dist/components/TabBar.js +63 -0
- package/dist/components/TabBar.js.map +1 -0
- package/dist/components/Tabs.js +168 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/define-routes.d.ts +1 -1
- package/dist/define-routes.d.ts.map +1 -1
- package/{src/define-routes.d.ts → dist/define-routes.js} +4 -2
- package/dist/define-routes.js.map +1 -0
- package/dist/hooks/use-focus.js +87 -0
- package/dist/hooks/use-focus.js.map +1 -0
- package/dist/hooks/use-hardware-back.js +84 -0
- package/dist/hooks/use-hardware-back.js.map +1 -0
- package/dist/hooks/use-linking-nav.d.ts +3 -3
- package/dist/hooks/use-linking-nav.d.ts.map +1 -1
- package/dist/hooks/use-linking-nav.js +109 -0
- package/dist/hooks/use-linking-nav.js.map +1 -0
- package/dist/hooks/use-nav-internal.d.ts +2 -2
- package/dist/hooks/use-nav-internal.d.ts.map +1 -1
- package/dist/hooks/use-nav-internal.js +55 -0
- package/dist/hooks/use-nav-internal.js.map +1 -0
- package/dist/hooks/use-nav-serializer.d.ts +1 -1
- package/dist/hooks/use-nav-serializer.d.ts.map +1 -1
- package/dist/hooks/use-nav-serializer.js +181 -0
- package/dist/hooks/use-nav-serializer.js.map +1 -0
- package/dist/hooks/use-nav.d.ts +2 -2
- package/dist/hooks/use-nav.d.ts.map +1 -1
- package/dist/hooks/use-nav.js +11 -0
- package/dist/hooks/use-nav.js.map +1 -0
- package/dist/hooks/use-params.d.ts +1 -1
- package/dist/hooks/use-params.d.ts.map +1 -1
- package/{src/hooks/use-params.d.ts → dist/hooks/use-params.js} +6 -2
- package/dist/hooks/use-params.js.map +1 -0
- package/dist/hooks/use-screen-chrome.d.ts +1 -1
- package/dist/hooks/use-screen-chrome.d.ts.map +1 -1
- package/dist/hooks/use-screen-chrome.js +102 -0
- package/dist/hooks/use-screen-chrome.js.map +1 -0
- package/dist/hooks/use-screen-options.d.ts +1 -1
- package/dist/hooks/use-screen-options.d.ts.map +1 -1
- package/dist/hooks/use-screen-options.js +43 -0
- package/dist/hooks/use-screen-options.js.map +1 -0
- package/dist/hooks/use-search.d.ts +1 -1
- package/dist/hooks/use-search.d.ts.map +1 -1
- package/{src/hooks/use-search.d.ts → dist/hooks/use-search.js} +6 -2
- package/dist/hooks/use-search.js.map +1 -0
- package/dist/href.d.ts +2 -2
- package/dist/href.d.ts.map +1 -1
- package/dist/href.js +57 -0
- package/dist/href.js.map +1 -0
- package/dist/index.d.ts +33 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -1160
- package/dist/index.js.map +1 -1
- package/dist/internal/layer-plan.d.ts +1 -1
- package/dist/internal/layer-plan.d.ts.map +1 -1
- package/dist/internal/layer-plan.js +102 -0
- package/dist/internal/layer-plan.js.map +1 -0
- package/dist/internal/screen-registry.d.ts +1 -1
- package/dist/internal/screen-registry.d.ts.map +1 -1
- package/{src/internal/screen-registry.d.ts → dist/internal/screen-registry.js} +32 -21
- package/dist/internal/screen-registry.js.map +1 -0
- package/{src/internal/screen-width.d.ts → dist/internal/screen-width.js} +17 -2
- package/dist/internal/screen-width.js.map +1 -0
- package/dist/navigator/core.d.ts +3 -3
- package/dist/navigator/core.d.ts.map +1 -1
- package/dist/navigator/core.js +394 -0
- package/dist/navigator/core.js.map +1 -0
- package/dist/register.d.ts +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +2 -0
- package/dist/register.js.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/url/build.js +30 -0
- package/dist/url/build.js.map +1 -0
- package/dist/url/compile.js +83 -0
- package/dist/url/compile.js.map +1 -0
- package/dist/url/format.js +102 -0
- package/dist/url/format.js.map +1 -0
- package/dist/url/index.d.ts +6 -6
- package/dist/url/index.d.ts.map +1 -1
- package/dist/url/index.js +13 -0
- package/dist/url/index.js.map +1 -0
- package/dist/url/parse.d.ts +1 -1
- package/dist/url/parse.d.ts.map +1 -1
- package/dist/url/parse.js +94 -0
- package/dist/url/parse.js.map +1 -0
- package/dist/url/registry.d.ts +2 -2
- package/dist/url/registry.d.ts.map +1 -1
- package/{src/url/registry.d.ts → dist/url/registry.js} +28 -12
- package/dist/url/registry.js.map +1 -0
- package/dist/url/validate.d.ts +1 -1
- package/dist/url/validate.d.ts.map +1 -1
- package/dist/url/validate.js +37 -0
- package/dist/url/validate.js.map +1 -0
- package/package.json +13 -12
- package/src/components/EdgeBackHandle.tsx +2 -2
- package/src/components/EntryScope.tsx +3 -3
- package/src/components/Header.tsx +3 -3
- package/src/components/Layer.tsx +3 -3
- package/src/components/Link.tsx +4 -4
- package/src/components/NavigationRoot.tsx +6 -6
- package/src/components/Screen.tsx +3 -3
- package/src/components/Stack.tsx +8 -8
- package/src/components/TabBar.tsx +1 -1
- package/src/define-routes.ts +1 -1
- package/src/hooks/use-focus.ts +2 -2
- package/src/hooks/use-hardware-back.ts +1 -1
- package/src/hooks/use-linking-nav.ts +4 -4
- package/src/hooks/use-nav-internal.ts +2 -2
- package/src/hooks/use-nav-serializer.ts +3 -3
- package/src/hooks/use-nav.ts +2 -2
- package/src/hooks/use-params.ts +2 -2
- package/src/hooks/use-screen-chrome.ts +3 -3
- package/src/hooks/use-screen-options.ts +3 -3
- package/src/hooks/use-search.ts +2 -2
- package/src/href.ts +6 -6
- package/src/index.ts +33 -33
- package/src/internal/layer-plan.ts +2 -2
- package/src/internal/screen-registry.ts +1 -1
- package/src/navigator/core.ts +3 -3
- package/src/register.ts +1 -1
- package/src/url/build.ts +2 -2
- package/src/url/index.ts +6 -6
- package/src/url/parse.ts +6 -6
- package/src/url/registry.ts +3 -3
- package/src/url/validate.ts +1 -1
- package/src/components/Drawer.d.ts +0 -55
- package/src/components/EdgeBackHandle.d.ts +0 -1
- package/src/components/EntryScope.d.ts +0 -25
- package/src/components/Header.d.ts +0 -6
- package/src/components/Layer.d.ts +0 -33
- package/src/components/Link.d.ts +0 -60
- package/src/components/NavigationRoot.d.ts +0 -36
- package/src/components/Screen.d.ts +0 -97
- package/src/components/Stack.d.ts +0 -90
- package/src/components/TabBar.d.ts +0 -38
- package/src/components/Tabs.d.ts +0 -109
- package/src/hooks/use-focus.d.ts +0 -45
- package/src/hooks/use-hardware-back.d.ts +0 -37
- package/src/hooks/use-linking-nav.d.ts +0 -91
- package/src/hooks/use-nav-internal.d.ts +0 -91
- package/src/hooks/use-nav-serializer.d.ts +0 -82
- package/src/hooks/use-nav.d.ts +0 -111
- package/src/hooks/use-screen-chrome.d.ts +0 -18
- package/src/hooks/use-screen-options.d.ts +0 -2
- package/src/href.d.ts +0 -54
- package/src/index.d.ts +0 -39
- package/src/internal/layer-plan.d.ts +0 -68
- package/src/navigator/core.d.ts +0 -96
- package/src/register.d.ts +0 -37
- package/src/types.d.ts +0 -217
- package/src/url/build.d.ts +0 -15
- package/src/url/compile.d.ts +0 -34
- package/src/url/format.d.ts +0 -28
- package/src/url/parse.d.ts +0 -20
- package/src/url/validate.d.ts +0 -23
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { type SharedValue } from '@sigx/lynx';
|
|
2
|
-
import type { ScreenRegistry } from '../internal/screen-registry';
|
|
3
|
-
import type { RouteMap, StackEntry } from '../types';
|
|
4
|
-
/**
|
|
5
|
-
* Internal injectable: the `StackEntry` the calling screen was rendered for.
|
|
6
|
-
*
|
|
7
|
-
* Provided by `<EntryScope>` which `<Stack>` and `<ScreenContainer>` wrap
|
|
8
|
-
* around each screen component mount. Screens use this to derive their own
|
|
9
|
-
* focus state (`useIsFocused`, `useFocusEffect`) without having to track
|
|
10
|
-
* `entry.key` themselves.
|
|
11
|
-
*
|
|
12
|
-
* Default throws so calling `useIsFocused()` outside a screen mounted by a
|
|
13
|
-
* navigator surfaces a clear error rather than silently returning `false`.
|
|
14
|
-
*/
|
|
15
|
-
export declare const useCurrentEntry: import("@sigx/runtime-core").InjectableFunction<StackEntry<string, unknown, unknown>>;
|
|
16
|
-
/**
|
|
17
|
-
* Soft companion to {@link useCurrentEntry} — returns the current scope's
|
|
18
|
-
* entry if any, `null` when called outside an `<EntryScope>` instead of
|
|
19
|
-
* throwing. Provided alongside the strict version by `<EntryScope>`.
|
|
20
|
-
*
|
|
21
|
-
* Used by chrome consumers (`useScreenChrome`) where "no scoped entry"
|
|
22
|
-
* is a legitimate state (a Stack chrome slot lives outside the screen's
|
|
23
|
-
* EntryScope) and the caller wants to soft-fallback to the navigator's
|
|
24
|
-
* destination entry rather than crash.
|
|
25
|
-
*/
|
|
26
|
-
export declare const useCurrentEntryOptional: import("@sigx/runtime-core").InjectableFunction<StackEntry<string, unknown, unknown> | null>;
|
|
27
|
-
/**
|
|
28
|
-
* Internal injectable: the route registry passed into `<NavigationRoot>`.
|
|
29
|
-
* Components (Stack, Screen) read this to look up route definitions by name.
|
|
30
|
-
*
|
|
31
|
-
* Not exported from the package barrel — use `useNav()` for navigation, and
|
|
32
|
-
* the registry is implicit from `<NavigationRoot routes={...}>`.
|
|
33
|
-
*/
|
|
34
|
-
export declare const useNavRoutes: import("@sigx/runtime-core").InjectableFunction<RouteMap>;
|
|
35
|
-
/**
|
|
36
|
-
* Internal injectable: low-level navigator handles used by the edge-back
|
|
37
|
-
* gesture. Holds the progress SharedValue (so gesture worklets can write it
|
|
38
|
-
* directly on MT) plus BG-side begin/commit/cancel functions invoked via
|
|
39
|
-
* `runOnBackground` from gesture worklets.
|
|
40
|
-
*
|
|
41
|
-
* `progress` is `null` when the navigator was created with `animated={false}`
|
|
42
|
-
* (e.g. tests). `beginBackGesture` is also a no-op in that case.
|
|
43
|
-
*/
|
|
44
|
-
export interface NavInternals {
|
|
45
|
-
/** MT-driven transition progress; null when animations are disabled. */
|
|
46
|
-
readonly progress: SharedValue<number> | null;
|
|
47
|
-
/**
|
|
48
|
-
* Set transition state for a gesture-driven pop. Does not start any
|
|
49
|
-
* automatic animation — the gesture worklet writes `progress` directly
|
|
50
|
-
* per frame, then animates to the commit/cancel endpoint on release.
|
|
51
|
-
*/
|
|
52
|
-
beginBackGesture(): void;
|
|
53
|
-
/** Commit the back gesture: pop top entry + clear transition. */
|
|
54
|
-
commitBackGesture(): void;
|
|
55
|
-
/** Cancel the back gesture: clear transition without popping. */
|
|
56
|
-
cancelBackGesture(): void;
|
|
57
|
-
/** Whether the user opted into the edge-swipe-back gesture. */
|
|
58
|
-
readonly edgeSwipeEnabled: boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Cross-entry screen registry controller. `<EntryScope>` calls
|
|
61
|
-
* `register` on mount and `unregister` on unmount. Persistent chrome
|
|
62
|
-
* (HeaderBar / TabBar — later slices) calls `get(entryKey)` to read
|
|
63
|
-
* the focused screen's options + slot fills without remounting itself.
|
|
64
|
-
*/
|
|
65
|
-
readonly screens: {
|
|
66
|
-
register(registry: ScreenRegistry): void;
|
|
67
|
-
/**
|
|
68
|
-
* Identity-checked: only removes the entry if `registry` is the
|
|
69
|
-
* one currently registered under its `entry.key`. A no-op when
|
|
70
|
-
* a newer registry has already taken that slot (which happens
|
|
71
|
-
* at the transition→idle handoff, where a fresh `<EntryScope>`
|
|
72
|
-
* for the same entry mounts before the old one's unmount fires).
|
|
73
|
-
*/
|
|
74
|
-
unregister(registry: ScreenRegistry): void;
|
|
75
|
-
get(entryKey: string): ScreenRegistry | undefined;
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
export declare const useNavInternals: import("@sigx/runtime-core").InjectableFunction<NavInternals>;
|
|
79
|
-
/**
|
|
80
|
-
* Internal injectable: the calling screen's `ScreenRegistry`.
|
|
81
|
-
*
|
|
82
|
-
* Provided by `<EntryScope>` alongside `useCurrentEntry`. The `<Screen>`
|
|
83
|
-
* component and its slot-filling sub-components write options and slot
|
|
84
|
-
* fills here; the navigator's persistent chrome (HeaderBar, TabBar — later
|
|
85
|
-
* slices) reads from this registry via `getScreenRegistry(key)` on the
|
|
86
|
-
* navigator state, which keys into a cross-entry map.
|
|
87
|
-
*
|
|
88
|
-
* Throws when used outside an EntryScope so calling `<Screen>` at the app
|
|
89
|
-
* root surfaces a clear error rather than silently no-op'ing.
|
|
90
|
-
*/
|
|
91
|
-
export declare const useScreenRegistry: import("@sigx/runtime-core").InjectableFunction<ScreenRegistry>;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import type { StackEntry } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Plain JSON snapshot of a navigator. The whole point of holding navigation
|
|
4
|
-
* state in signals is that this is a one-liner — `JSON.stringify(nav.stack)`.
|
|
5
|
-
*
|
|
6
|
-
* Shape is deliberately minimal:
|
|
7
|
-
*
|
|
8
|
-
* {
|
|
9
|
-
* version: 1,
|
|
10
|
-
* stack: [ { key, route, params, search, state, presentation }, ... ],
|
|
11
|
-
* }
|
|
12
|
-
*
|
|
13
|
-
* `version` lets future schema migrations (or hard breakage) reject old
|
|
14
|
-
* snapshots cleanly rather than restoring incompatible state.
|
|
15
|
-
*
|
|
16
|
-
* Per spec resolved-decisions: only the root navigator is persisted in v1.
|
|
17
|
-
* Per-tab / nested-navigator stacks are deferred until the nested-navigators
|
|
18
|
-
* follow-up slice lands.
|
|
19
|
-
*/
|
|
20
|
-
export interface NavSnapshot {
|
|
21
|
-
version: number;
|
|
22
|
-
stack: StackEntry[];
|
|
23
|
-
}
|
|
24
|
-
export declare const NAV_SNAPSHOT_VERSION = 1;
|
|
25
|
-
/**
|
|
26
|
-
* Adapter contract for `useNavSerializer`. Implementations bridge to whatever
|
|
27
|
-
* storage backend the host app uses — `@sigx/lynx-storage`, `localStorage`,
|
|
28
|
-
* an MMKV bridge, etc. Both methods may be async; the hook awaits load before
|
|
29
|
-
* applying anything to the stack and fires save in a debounced manner.
|
|
30
|
-
*
|
|
31
|
-
* - `load()` returns `null` (or rejects) when no snapshot exists, when the
|
|
32
|
-
* stored payload is malformed, or when the host opts not to restore on
|
|
33
|
-
* this launch.
|
|
34
|
-
* - `save(snapshot)` persists the latest stack. The hook drops save errors
|
|
35
|
-
* on the floor — losing a write is preferable to crashing the navigator.
|
|
36
|
-
*/
|
|
37
|
-
export interface NavStorageAdapter {
|
|
38
|
-
load(): Promise<NavSnapshot | null> | NavSnapshot | null;
|
|
39
|
-
save(snapshot: NavSnapshot): Promise<void> | void;
|
|
40
|
-
}
|
|
41
|
-
export interface UseNavSerializerOptions {
|
|
42
|
-
storage: NavStorageAdapter;
|
|
43
|
-
/**
|
|
44
|
-
* Trailing-edge debounce in ms before pushing a stack change to storage.
|
|
45
|
-
* Defaults to 250ms — quick enough that a force-quit one tick after a
|
|
46
|
-
* push is recoverable, slow enough that rapid `pop/push` flurries
|
|
47
|
-
* coalesce into one write.
|
|
48
|
-
*/
|
|
49
|
-
debounceMs?: number;
|
|
50
|
-
/**
|
|
51
|
-
* Optional callback after a successful restore — lets the host run
|
|
52
|
-
* post-restore wiring (analytics, focus shifts, etc.) only when we
|
|
53
|
-
* actually applied state, not on every mount.
|
|
54
|
-
*/
|
|
55
|
-
onRestored?: (snapshot: NavSnapshot) => void;
|
|
56
|
-
/**
|
|
57
|
-
* Optional callback when a snapshot is rejected (validation failed or
|
|
58
|
-
* load threw). Defaults to silent. Useful for logging during migration.
|
|
59
|
-
*/
|
|
60
|
-
onRestoreError?: (reason: 'version' | 'shape' | 'unknown-route' | 'load-threw', err?: unknown) => void;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Wire a navigator's stack to a storage adapter.
|
|
64
|
-
*
|
|
65
|
-
* On mount:
|
|
66
|
-
* 1. Call `storage.load()`.
|
|
67
|
-
* 2. Validate the snapshot (version match, every entry's route still
|
|
68
|
-
* registered).
|
|
69
|
-
* 3. On success, `nav.reset({ stack })` to apply.
|
|
70
|
-
* 4. On any failure, leave the stack alone (initial route remains).
|
|
71
|
-
*
|
|
72
|
-
* Then subscribe to `nav.stack` and call `storage.save(snapshot)` debounced.
|
|
73
|
-
*
|
|
74
|
-
* Why we don't validate `params` / `search` against schemas here: schemas
|
|
75
|
-
* are part of the route definition, and re-running them across all entries
|
|
76
|
-
* on every launch costs more than it's worth. The contract is "entries were
|
|
77
|
-
* validated when they were pushed; if the schema has since changed in a
|
|
78
|
-
* breaking way, bump `version` to reject old snapshots wholesale." Callers
|
|
79
|
-
* who want a stricter check can run their own validation in
|
|
80
|
-
* `storage.load()` and return `null` on mismatch.
|
|
81
|
-
*/
|
|
82
|
-
export declare function useNavSerializer(options: UseNavSerializerOptions): void;
|
package/src/hooks/use-nav.d.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type { RegisteredRoutes, RouteId, RouteParams, RouteSearch } from '../register';
|
|
2
|
-
import type { PopOptions, PushOptions, RouteRequiresParams, StackEntry, TransitionState } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* Subset of registered route names that declare a `params` schema (and so
|
|
5
|
-
* require a `params` argument when navigating).
|
|
6
|
-
*
|
|
7
|
-
* Computed via mapped-type filtering rather than a conditional inside the
|
|
8
|
-
* method signature: when a conditional like `RouteRequiresParams<R[K]>` is
|
|
9
|
-
* embedded inside a generic method parameter, TS evaluates it at definition
|
|
10
|
-
* time with K bound to the *whole* union of route ids — which distributes
|
|
11
|
-
* `RouteRequiresParams` over every route and collapses the result to
|
|
12
|
-
* `boolean`, breaking the conditional. Filtering once at the type level avoids
|
|
13
|
-
* the issue and produces clean overload candidates.
|
|
14
|
-
*/
|
|
15
|
-
export type RoutesWithParams = {
|
|
16
|
-
[K in RouteId]: RouteRequiresParams<RegisteredRoutes[K]> extends true ? K : never;
|
|
17
|
-
}[RouteId];
|
|
18
|
-
/** Routes that don't declare a `params` schema. */
|
|
19
|
-
export type RoutesWithoutParams = Exclude<RouteId, RoutesWithParams>;
|
|
20
|
-
/**
|
|
21
|
-
* The navigator handle returned by `useNav()`.
|
|
22
|
-
*
|
|
23
|
-
* Read access (`current`, `stack`, `canGoBack`) is reactive — these properties
|
|
24
|
-
* are getters that read from the underlying stack signal, so accessing them
|
|
25
|
-
* inside a component's render function (or inside `effect` / `computed`) takes
|
|
26
|
-
* a reactive dependency. Mutating methods (`push`, `pop`, etc.) trigger the
|
|
27
|
-
* dependents to update.
|
|
28
|
-
*
|
|
29
|
-
* `push` and `replace` are split into two overloads — one for routes without a
|
|
30
|
-
* params schema (no params arg) and one for routes with a params schema
|
|
31
|
-
* (params required). See `RoutesWithParams` above for why this isn't a single
|
|
32
|
-
* conditional return type.
|
|
33
|
-
*/
|
|
34
|
-
export interface Nav {
|
|
35
|
-
/** Push a route that has no params schema. */
|
|
36
|
-
push<K extends RoutesWithoutParams>(name: K, search?: RouteSearch<K>, options?: PushOptions): void;
|
|
37
|
-
/** Push a route that requires params. */
|
|
38
|
-
push<K extends RoutesWithParams>(name: K, params: RouteParams<K>, search?: RouteSearch<K>, options?: PushOptions): void;
|
|
39
|
-
/** Replace the top entry — same overload pattern as push. */
|
|
40
|
-
replace<K extends RoutesWithoutParams>(name: K, search?: RouteSearch<K>, options?: PushOptions): void;
|
|
41
|
-
replace<K extends RoutesWithParams>(name: K, params: RouteParams<K>, search?: RouteSearch<K>, options?: PushOptions): void;
|
|
42
|
-
/** Pop one or more entries off the top of the stack. */
|
|
43
|
-
pop(count?: number, options?: PopOptions): void;
|
|
44
|
-
/** Pop entries until the named route is at the top. */
|
|
45
|
-
popTo<K extends RouteId>(name: K): void;
|
|
46
|
-
/** Pop all the way to the root entry. */
|
|
47
|
-
popToRoot(): void;
|
|
48
|
-
/** Wholesale-replace the stack. */
|
|
49
|
-
reset(state: {
|
|
50
|
-
stack: ReadonlyArray<StackEntry>;
|
|
51
|
-
}): void;
|
|
52
|
-
/** Dismiss the topmost modal stack (no-op if none active). */
|
|
53
|
-
dismiss(): void;
|
|
54
|
-
/** Currently-focused entry. Reactive via property access. */
|
|
55
|
-
readonly current: StackEntry;
|
|
56
|
-
/** Full stack, top last. Reactive. */
|
|
57
|
-
readonly stack: ReadonlyArray<StackEntry>;
|
|
58
|
-
/** Whether the user can go back from the current entry. Reactive. */
|
|
59
|
-
readonly canGoBack: boolean;
|
|
60
|
-
/**
|
|
61
|
-
* Parent navigator (e.g. the root nav above a per-tab `<Stack>`), or null
|
|
62
|
-
* at the root. Set when a `<Stack>` mints its own navigator via
|
|
63
|
-
* `<Stack initialRoute="…">` — that stack's `useNav()` returns a nav
|
|
64
|
-
* whose `parent` is the enclosing nav.
|
|
65
|
-
*
|
|
66
|
-
* `push` calls for routes whose resolved presentation is non-`card`
|
|
67
|
-
* (`modal` / `fullScreen` / `transparent-modal`) escalate up the
|
|
68
|
-
* `parent` chain automatically — you don't normally need to reach
|
|
69
|
-
* through `parent` to present modals. `parent` is exposed as an escape
|
|
70
|
-
* hatch for power users (e.g. imperative `parent.pop()` from a child
|
|
71
|
-
* stack). Avoid pushing card routes onto `parent` directly — that
|
|
72
|
-
* defeats per-tab stack isolation.
|
|
73
|
-
*/
|
|
74
|
-
readonly parent: Nav | null;
|
|
75
|
-
/**
|
|
76
|
-
* Whether this navigator is part of the currently-focused chain. True
|
|
77
|
-
* for the root nav at all times; for a nested nav (e.g. a per-tab
|
|
78
|
-
* stack), true only when its host entry is the top of `parent`, the
|
|
79
|
-
* parent itself is locally focused, and any extra gate (e.g. the
|
|
80
|
-
* enclosing tab is active) reports active.
|
|
81
|
-
*
|
|
82
|
-
* Reactive. `useIsFocused()` ANDs `nav.current.key === myKey` with
|
|
83
|
-
* `nav.isLocallyFocused`.
|
|
84
|
-
*/
|
|
85
|
-
readonly isLocallyFocused: boolean;
|
|
86
|
-
/**
|
|
87
|
-
* @internal
|
|
88
|
-
* Set of child navigators (per-tab `<Stack>` instances) that have
|
|
89
|
-
* registered themselves under this nav. Used by `useHardwareBack` to
|
|
90
|
-
* find the deepest currently-focused nav and route the back press
|
|
91
|
-
* there before falling back up the chain.
|
|
92
|
-
*
|
|
93
|
-
* Not part of the public API — leading-underscore marks it as
|
|
94
|
-
* implementation detail.
|
|
95
|
-
*/
|
|
96
|
-
readonly _children: Set<Nav>;
|
|
97
|
-
/**
|
|
98
|
-
* In-flight transition, or null when navigation is at rest. Reactive —
|
|
99
|
-
* `<Stack>` reads this to decide whether to render one screen or two
|
|
100
|
-
* (during a slide transition both the outgoing and incoming screens
|
|
101
|
-
* stay mounted with `useAnimatedStyle`-driven transforms).
|
|
102
|
-
*/
|
|
103
|
-
readonly transition: TransitionState | null;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Access the innermost navigator. Provided by `<NavigationRoot>` via
|
|
107
|
-
* `defineProvide`. Throws when called outside a NavigationRoot subtree.
|
|
108
|
-
*
|
|
109
|
-
* Mirrors `@sigx/router`'s `useRouter` pattern (`packages/router/src/router.ts:30`).
|
|
110
|
-
*/
|
|
111
|
-
export declare const useNav: import("@sigx/runtime-core").InjectableFunction<Nav>;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ScreenSlotFills } from '../types';
|
|
2
|
-
export interface ScreenChrome {
|
|
3
|
-
/** Resolved screen title — `options.title` (string or getter) or the route name as fallback. Reactive. */
|
|
4
|
-
readonly title: string;
|
|
5
|
-
/** Whether the header should render. Defaults to true unless the screen set `headerShown: false`. Reactive. */
|
|
6
|
-
readonly headerShown: boolean;
|
|
7
|
-
/** True when the current stack has more than one entry — i.e. there's something to pop back to. Reactive. */
|
|
8
|
-
readonly canGoBack: boolean;
|
|
9
|
-
/** Pop the top entry. No-op when `!canGoBack`. */
|
|
10
|
-
pop(): void;
|
|
11
|
-
/** Full header override slot, if `<Screen.Header>` was set. Render its return value in place of the default layout. */
|
|
12
|
-
readonly header: ScreenSlotFills['header'] | undefined;
|
|
13
|
-
/** Left-aligned slot (typically a back button). Reactive. */
|
|
14
|
-
readonly headerLeft: ScreenSlotFills['headerLeft'] | undefined;
|
|
15
|
-
/** Right-aligned slot (typically actions). Reactive. */
|
|
16
|
-
readonly headerRight: ScreenSlotFills['headerRight'] | undefined;
|
|
17
|
-
}
|
|
18
|
-
export declare function useScreenChrome(): ScreenChrome;
|
package/src/href.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { RouteId, RouteParams, RouteSearch } from './register';
|
|
2
|
-
import type { RoutesWithoutParams, RoutesWithParams } from './hooks/use-nav';
|
|
3
|
-
/**
|
|
4
|
-
* A typed reference to a navigation target — what `<Link to={...}>` consumes
|
|
5
|
-
* and what `hrefFor()` produces.
|
|
6
|
-
*
|
|
7
|
-
* Holds both the typed pieces (route name, params, search) and the serialized
|
|
8
|
-
* URL form (when the route declares a `path` template). Either side can drive
|
|
9
|
-
* navigation — typed for in-app links, URL for deep links / sharing.
|
|
10
|
-
*/
|
|
11
|
-
export interface Href<K extends RouteId = RouteId> {
|
|
12
|
-
readonly route: K;
|
|
13
|
-
readonly params: RouteParams<K>;
|
|
14
|
-
readonly search: RouteSearch<K>;
|
|
15
|
-
/** URL form. `null` when the route declares no `path` template. */
|
|
16
|
-
readonly url: string | null;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Build a typed Href for a given route. Validates params against the route's
|
|
20
|
-
* schema at runtime; type-checks them at compile time.
|
|
21
|
-
*
|
|
22
|
-
* Overloaded the same way as `nav.push` — one signature for routes without a
|
|
23
|
-
* params schema, one for routes that require params. See `RoutesWithParams`
|
|
24
|
-
* in `./hooks/use-nav.js` for why this isn't expressed as a single conditional.
|
|
25
|
-
*
|
|
26
|
-
* Requires a `<NavigationRoot>` (or an explicit `_setRouteRegistry` call) to
|
|
27
|
-
* have run — the URL form is built against the active route registry. The
|
|
28
|
-
* typed pieces (`route`, `params`, `search`) are returned regardless; `url`
|
|
29
|
-
* is `null` when the route declares no `path` template.
|
|
30
|
-
*
|
|
31
|
-
* Schema validation errors throw — pass already-validated values from
|
|
32
|
-
* `useParams` / `useSearch` to round-trip safely, or wrap in try/catch when
|
|
33
|
-
* building hrefs from external input.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* hrefFor('profile', { id: '42' }); // → { route, params, search: {}, url: '/users/42' }
|
|
38
|
-
* hrefFor('profile', { id: '42' }, { tab: 'about' });
|
|
39
|
-
* hrefFor('home'); // params arg omitted (no schema)
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
export declare function hrefFor<K extends RoutesWithoutParams>(name: K, search?: RouteSearch<K>): Href<K>;
|
|
43
|
-
export declare function hrefFor<K extends RoutesWithParams>(name: K, params: RouteParams<K>, search?: RouteSearch<K>): Href<K>;
|
|
44
|
-
/**
|
|
45
|
-
* Parse a URL string into a typed Href against the registered routes.
|
|
46
|
-
* Returns `null` if no route's `path` template matches the URL or if the
|
|
47
|
-
* extracted params/search fail the route's schema validation.
|
|
48
|
-
*
|
|
49
|
-
* Accepts both absolute (`myapp://host/path?q`) and pathname-only
|
|
50
|
-
* (`/path?q`) forms — the pathname is matched against each route's
|
|
51
|
-
* compiled template. Iteration order is the registration order; first match
|
|
52
|
-
* wins.
|
|
53
|
-
*/
|
|
54
|
-
export declare function parseHref(url: string): Href | null;
|
package/src/index.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @sigx/lynx-navigation — type-first native stack router.
|
|
3
|
-
*
|
|
4
|
-
* Phase 0.1 (current): typed registry, stack runtime, NavigationRoot + Stack.
|
|
5
|
-
* Coming next: Screen with slot-based header API, MTS transitions, Tabs.
|
|
6
|
-
*/
|
|
7
|
-
export { defineRoutes } from './define-routes';
|
|
8
|
-
export type { Register, RegisteredRoutes, RouteId, RouteParams, RouteSearch } from './register';
|
|
9
|
-
export { useNav } from './hooks/use-nav';
|
|
10
|
-
export type { Nav, RoutesWithoutParams, RoutesWithParams } from './hooks/use-nav';
|
|
11
|
-
export { useParams } from './hooks/use-params';
|
|
12
|
-
export { useSearch } from './hooks/use-search';
|
|
13
|
-
export { useHardwareBack } from './hooks/use-hardware-back';
|
|
14
|
-
export { useLinkingNav } from './hooks/use-linking-nav';
|
|
15
|
-
export type { UseLinkingNavOptions } from './hooks/use-linking-nav';
|
|
16
|
-
export { useIsFocused, useFocusEffect } from './hooks/use-focus';
|
|
17
|
-
export { useScreenOptions } from './hooks/use-screen-options';
|
|
18
|
-
export { useScreenChrome } from './hooks/use-screen-chrome';
|
|
19
|
-
export type { ScreenChrome } from './hooks/use-screen-chrome';
|
|
20
|
-
export { useNavSerializer, NAV_SNAPSHOT_VERSION, } from './hooks/use-nav-serializer';
|
|
21
|
-
export type { NavSnapshot, NavStorageAdapter, UseNavSerializerOptions, } from './hooks/use-nav-serializer';
|
|
22
|
-
export { hrefFor, parseHref } from './href';
|
|
23
|
-
export type { Href } from './href';
|
|
24
|
-
export { _setRouteRegistry, _clearRouteRegistry } from './url/registry';
|
|
25
|
-
export { compilePath } from './url/compile';
|
|
26
|
-
export type { CompiledPath } from './url/compile';
|
|
27
|
-
export { NavigationRoot } from './components/NavigationRoot';
|
|
28
|
-
export { Stack } from './components/Stack';
|
|
29
|
-
export { Screen } from './components/Screen';
|
|
30
|
-
export { Header } from './components/Header';
|
|
31
|
-
export { Tabs, useTabs } from './components/Tabs';
|
|
32
|
-
export type { TabInfo, TabsNav } from './components/Tabs';
|
|
33
|
-
export { TabBar } from './components/TabBar';
|
|
34
|
-
export type { TabRenderContext } from './components/TabBar';
|
|
35
|
-
export { Drawer, useDrawer } from './components/Drawer';
|
|
36
|
-
export type { DrawerNav } from './components/Drawer';
|
|
37
|
-
export { Link } from './components/Link';
|
|
38
|
-
export type { LinkProps } from './components/Link';
|
|
39
|
-
export type { ComponentLike, EmptyParams, InferOutput, ParamsOf, PopOptions, Presentation, PushOptions, RouteDefinition, RouteMap, RouteRequiresParams, ScreenOptions, ScreenSlotFills, SearchOf, StackEntry, StandardSchemaV1, TransitionKind, TransitionRole, TransitionState, } from './types';
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure layer-plan computation for `<Stack>`'s render.
|
|
3
|
-
*
|
|
4
|
-
* Given (stack, transition, progress), produces an ordered list of
|
|
5
|
-
* `Layer`s — each is an entry to render plus an optional transform
|
|
6
|
-
* spec for animation. The Stack render emits one absolutely-positioned
|
|
7
|
-
* `<view>` per layer, stacked bottom-to-top in document order.
|
|
8
|
-
*
|
|
9
|
-
* Why this is its own module: the layer-selection logic is the only
|
|
10
|
-
* non-obvious part of the navigator's render path, and the rules are
|
|
11
|
-
* easier to read (and unit-test) as a pure function over the
|
|
12
|
-
* navigator's state than as inline render branches.
|
|
13
|
-
*
|
|
14
|
-
* Rules:
|
|
15
|
-
*
|
|
16
|
-
* - **Idle (no transition).** Render the topmost non-overlay entry
|
|
17
|
-
* as the base, plus every overlay entry above it. Overlays
|
|
18
|
-
* (`modal` / `fullScreen` / `transparent-modal`) keep their
|
|
19
|
-
* underneath mounted; cards replace their underneath in the base
|
|
20
|
-
* layer.
|
|
21
|
-
*
|
|
22
|
-
* - **Card transition.** Two layers: the underneath entry (animated
|
|
23
|
-
* with the parallax-card-underneath spec) and the top entry
|
|
24
|
-
* (animated with the slide-in-from-right spec). After the
|
|
25
|
-
* transition completes, the idle rule kicks in — the underneath
|
|
26
|
-
* unmounts because the new top becomes the sole base.
|
|
27
|
-
*
|
|
28
|
-
* - **Overlay transition.** The full idle layer stack up through the
|
|
29
|
-
* underneath entry stays static (no transform). The animated top
|
|
30
|
-
* is the only layer with a transform. After the transition, the
|
|
31
|
-
* overlay either joins the static idle stack (push) or unmounts
|
|
32
|
-
* (pop).
|
|
33
|
-
*
|
|
34
|
-
* The Layer.key for the Stack render is
|
|
35
|
-
* `layer-${entry.key}-${animVariant(layer.animation)}`. The variant
|
|
36
|
-
* suffix forces a remount when an entry transitions from animated to
|
|
37
|
-
* static (or vice versa) — `useAnimatedStyle` can't re-bind mid-life,
|
|
38
|
-
* so we get a fresh `useAnimatedStyle` call per animation state.
|
|
39
|
-
* Modal underneath layers never animate, so they stay statically
|
|
40
|
-
* keyed across the modal lifecycle and their state (per-tab Stack,
|
|
41
|
-
* scroll, in-flight inputs) survives.
|
|
42
|
-
*/
|
|
43
|
-
import type { SharedValue } from '@sigx/lynx';
|
|
44
|
-
import type { Presentation, StackEntry, TransitionState } from '../types';
|
|
45
|
-
export type LayerAnimation = {
|
|
46
|
-
axis: 'translateX' | 'translateY';
|
|
47
|
-
inputRange: readonly [number, number];
|
|
48
|
-
outputRange: readonly [number, number];
|
|
49
|
-
progress: SharedValue<number>;
|
|
50
|
-
};
|
|
51
|
-
export interface Layer {
|
|
52
|
-
/** The entry whose component renders inside this layer. */
|
|
53
|
-
readonly entry: StackEntry;
|
|
54
|
-
/** When non-null, the layer's host view binds a `useAnimatedStyle` mapper. */
|
|
55
|
-
readonly animation: LayerAnimation | null;
|
|
56
|
-
}
|
|
57
|
-
export declare function isOverlayPresentation(p: Presentation): boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Suffix used in a layer's render key. Stable for the layer's
|
|
60
|
-
* lifetime (same entry, same animation kind) and changes when the
|
|
61
|
-
* animation transitions on/off so the Layer remounts and rebinds.
|
|
62
|
-
*/
|
|
63
|
-
export declare function animationVariant(animation: LayerAnimation | null): string;
|
|
64
|
-
/**
|
|
65
|
-
* Compute the visible-layer list for one render of `<Stack>`. Pure —
|
|
66
|
-
* unit-testable independently of the renderer.
|
|
67
|
-
*/
|
|
68
|
-
export declare function computeLayers(stack: readonly StackEntry[], transition: TransitionState | null, progress: SharedValue<number> | null): Layer[];
|
package/src/navigator/core.d.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { type SharedValue } from '@sigx/lynx';
|
|
2
|
-
import type { Nav } from '../hooks/use-nav';
|
|
3
|
-
import type { ScreenRegistry } from '../internal/screen-registry';
|
|
4
|
-
import type { RouteMap, StackEntry } from '../types';
|
|
5
|
-
/**
|
|
6
|
-
* The reactive backing state for one navigator instance.
|
|
7
|
-
*
|
|
8
|
-
* Two reactive signals drive the public surface:
|
|
9
|
-
* - `stack` is the entry array (read via `nav.stack` / `nav.current`).
|
|
10
|
-
* - `transition` is non-null only while a push/pop animation is in flight;
|
|
11
|
-
* `<Stack>` reads it to decide whether to render one screen or two.
|
|
12
|
-
*
|
|
13
|
-
* Pop is committed *after* its slide animation completes — `nav.canGoBack`
|
|
14
|
-
* stays true during the slide, then flips when the entry actually leaves the
|
|
15
|
-
* stack. Push commits its stack mutation immediately and animates the new
|
|
16
|
-
* entry in.
|
|
17
|
-
*/
|
|
18
|
-
export interface NavigatorState {
|
|
19
|
-
readonly nav: Nav;
|
|
20
|
-
readonly routes: RouteMap;
|
|
21
|
-
/**
|
|
22
|
-
* Internal: BG-side gesture-back controller used by `<EdgeBackHandle>`.
|
|
23
|
-
* The `progress` SharedValue is wired here so a gesture worklet can write
|
|
24
|
-
* it directly on MT; the begin/commit/cancel methods set the transition
|
|
25
|
-
* state appropriately without driving their own auto-animation (the
|
|
26
|
-
* gesture worklet is in charge of that).
|
|
27
|
-
*/
|
|
28
|
-
readonly _gesture: {
|
|
29
|
-
beginBackGesture(): void;
|
|
30
|
-
commitBackGesture(): void;
|
|
31
|
-
cancelBackGesture(): void;
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* Internal: cross-entry `<Screen>` registry lookup.
|
|
35
|
-
*
|
|
36
|
-
* Each `<EntryScope>` registers its `ScreenRegistry` here on mount and
|
|
37
|
-
* removes it on unmount. The navigator's persistent chrome (HeaderBar /
|
|
38
|
-
* TabBar, shipped in later slices) calls `getScreenRegistry(entry.key)`
|
|
39
|
-
* to read the currently-focused screen's options/slot fills without
|
|
40
|
-
* being itself remounted on each navigation.
|
|
41
|
-
*
|
|
42
|
-
* Returns `undefined` when no screen for that key has mounted yet (or
|
|
43
|
-
* after it has unmounted) — consumers must tolerate this and render
|
|
44
|
-
* defaults.
|
|
45
|
-
*/
|
|
46
|
-
readonly _screens: {
|
|
47
|
-
register(registry: ScreenRegistry): void;
|
|
48
|
-
/** Identity-checked: no-op when a newer registry has taken the slot. */
|
|
49
|
-
unregister(registry: ScreenRegistry): void;
|
|
50
|
-
get(entryKey: string): ScreenRegistry | undefined;
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Internal: set `nav.isLocallyFocused` from outside.
|
|
54
|
-
*
|
|
55
|
-
* `<Stack>` calls this when its host entry's locally-focused state
|
|
56
|
-
* changes (top of parent + parent focused + enclosing tab active). For
|
|
57
|
-
* the root nav this stays `true` for the lifetime of the navigator.
|
|
58
|
-
*/
|
|
59
|
-
readonly _setLocallyFocused: (focused: boolean) => void;
|
|
60
|
-
}
|
|
61
|
-
export interface CreateNavigatorOptions {
|
|
62
|
-
routes: RouteMap;
|
|
63
|
-
initial: StackEntry;
|
|
64
|
-
/**
|
|
65
|
-
* SharedValue driving push/pop transition progress. Created in
|
|
66
|
-
* `<NavigationRoot>` setup via `useSharedValue(0)` so the bridge
|
|
67
|
-
* plumbing is wired (SharedValue is an MT-bridged ref). When undefined,
|
|
68
|
-
* navigations are instant — used by tests against `@sigx/lynx-testing`
|
|
69
|
-
* that don't have an MT runtime.
|
|
70
|
-
*/
|
|
71
|
-
progress?: SharedValue<number>;
|
|
72
|
-
/**
|
|
73
|
-
* Parent navigator. Set when this navigator is nested under another
|
|
74
|
-
* (e.g. a per-tab `<Stack initialRoute>` under root). Drives the
|
|
75
|
-
* `nav.parent` getter and the modal-escalation behaviour of `push`:
|
|
76
|
-
* a push of a route whose resolved presentation is not `'card'`
|
|
77
|
-
* recurses via `parent.push(...)`, walking up the chain until it
|
|
78
|
-
* lands on a navigator with no parent (the root).
|
|
79
|
-
*
|
|
80
|
-
* Leave undefined for the root navigator.
|
|
81
|
-
*/
|
|
82
|
-
parent?: Nav | null;
|
|
83
|
-
/**
|
|
84
|
-
* Whether this navigator is considered "locally focused" at creation
|
|
85
|
-
* time. Defaults to true for the root nav; nested stacks pass `false`
|
|
86
|
-
* here and then flip the flag via `_setLocallyFocused` once their
|
|
87
|
-
* host-entry/tab-active state is computed.
|
|
88
|
-
*/
|
|
89
|
-
initialLocallyFocused?: boolean;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Create a navigator. Returns the public `nav` handle plus the routes map.
|
|
93
|
-
* The transition signal lives on `nav` (via `nav.transition`) so `<Stack>`
|
|
94
|
-
* can subscribe to it.
|
|
95
|
-
*/
|
|
96
|
-
export declare function createNavigatorState(opts: CreateNavigatorOptions): NavigatorState;
|
package/src/register.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { ParamsOf, RouteMap, SearchOf } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Module-augmentation surface for the user's typed route map.
|
|
4
|
-
*
|
|
5
|
-
* Apps register their routes by augmenting this interface — the rest of the
|
|
6
|
-
* library's typed APIs (useNav, useParams, useSearch, <Link>) read from
|
|
7
|
-
* `RegisteredRoutes` so all inference is global.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```ts
|
|
11
|
-
* // In your app's main.ts (or a routes.ts that's imported early):
|
|
12
|
-
* import type { routes } from './routes';
|
|
13
|
-
*
|
|
14
|
-
* declare module '@sigx/lynx-navigation' {
|
|
15
|
-
* interface Register { routes: typeof routes }
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* If `Register.routes` is not augmented the library falls back to a permissive
|
|
20
|
-
* `RouteMap` so non-augmented usage still type-checks (just without precise
|
|
21
|
-
* inference). The recommended pattern is always to augment.
|
|
22
|
-
*/
|
|
23
|
-
export interface Register {
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* The user's registered route map, or a permissive fallback when not
|
|
27
|
-
* augmented. All higher-level types derive from this.
|
|
28
|
-
*/
|
|
29
|
-
export type RegisteredRoutes = Register extends {
|
|
30
|
-
routes: infer R;
|
|
31
|
-
} ? R : RouteMap;
|
|
32
|
-
/** Union of registered route names (string literal union when registered). */
|
|
33
|
-
export type RouteId = keyof RegisteredRoutes & string;
|
|
34
|
-
/** Params type for a registered route name. */
|
|
35
|
-
export type RouteParams<K extends RouteId> = ParamsOf<RegisteredRoutes[K]>;
|
|
36
|
-
/** Search type for a registered route name. */
|
|
37
|
-
export type RouteSearch<K extends RouteId> = SearchOf<RegisteredRoutes[K]>;
|