@sigx/lynx-navigation 0.2.0 → 0.4.0
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/README.md +128 -8
- package/dist/components/EntryScope.d.ts +1 -1
- package/dist/components/EntryScope.d.ts.map +1 -1
- package/dist/components/Layer.d.ts +34 -0
- package/dist/components/Layer.d.ts.map +1 -0
- package/dist/components/Link.d.ts +2 -2
- package/dist/components/Link.d.ts.map +1 -1
- package/dist/components/NavigationRoot.d.ts +2 -2
- package/dist/components/NavigationRoot.d.ts.map +1 -1
- package/dist/components/Screen.d.ts +6 -6
- package/dist/components/Screen.d.ts.map +1 -1
- package/dist/components/Stack.d.ts +41 -16
- package/dist/components/Stack.d.ts.map +1 -1
- package/dist/components/TabBar.d.ts +19 -20
- package/dist/components/TabBar.d.ts.map +1 -1
- package/dist/components/Tabs.d.ts.map +1 -1
- package/dist/define-routes.d.ts +1 -1
- package/dist/define-routes.d.ts.map +1 -1
- 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-nav-internal.d.ts +21 -3
- package/dist/hooks/use-nav-internal.d.ts.map +1 -1
- 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.d.ts +2 -2
- package/dist/hooks/use-nav.d.ts.map +1 -1
- package/dist/hooks/use-params.d.ts +1 -1
- package/dist/hooks/use-params.d.ts.map +1 -1
- package/dist/hooks/use-screen-chrome.d.ts +19 -0
- package/dist/hooks/use-screen-chrome.d.ts.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-search.d.ts +1 -1
- package/dist/hooks/use-search.d.ts.map +1 -1
- package/dist/href.d.ts +2 -2
- package/dist/href.d.ts.map +1 -1
- package/dist/index.d.ts +33 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1160 -29
- package/dist/index.js.map +1 -1
- package/dist/internal/layer-plan.d.ts +69 -0
- package/dist/internal/layer-plan.d.ts.map +1 -0
- package/dist/internal/screen-registry.d.ts +1 -1
- package/dist/internal/screen-registry.d.ts.map +1 -1
- package/dist/internal/screen-width.d.ts +9 -7
- package/dist/internal/screen-width.d.ts.map +1 -1
- package/dist/navigator/core.d.ts +5 -4
- package/dist/navigator/core.d.ts.map +1 -1
- package/dist/register.d.ts +1 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/url/index.d.ts +6 -6
- package/dist/url/index.d.ts.map +1 -1
- package/dist/url/parse.d.ts +1 -1
- package/dist/url/parse.d.ts.map +1 -1
- package/dist/url/registry.d.ts +2 -2
- package/dist/url/registry.d.ts.map +1 -1
- package/dist/url/validate.d.ts +1 -1
- package/dist/url/validate.d.ts.map +1 -1
- package/package.json +11 -10
- package/src/components/Drawer.d.ts +55 -0
- package/src/components/EdgeBackHandle.d.ts +1 -0
- package/src/components/EdgeBackHandle.tsx +2 -2
- package/{dist/components/EntryScope.js → src/components/EntryScope.d.ts} +7 -15
- package/src/components/EntryScope.tsx +15 -4
- package/src/components/Header.d.ts +6 -0
- package/src/components/Header.tsx +3 -3
- package/src/components/Layer.d.ts +33 -0
- package/src/components/Layer.tsx +96 -0
- package/src/components/Link.d.ts +60 -0
- package/src/components/Link.tsx +4 -4
- package/src/components/NavigationRoot.d.ts +36 -0
- package/src/components/NavigationRoot.tsx +6 -6
- package/src/components/Screen.d.ts +97 -0
- package/src/components/Screen.tsx +13 -11
- package/src/components/Stack.d.ts +90 -0
- package/src/components/Stack.tsx +142 -98
- package/src/components/TabBar.d.ts +38 -0
- package/src/components/TabBar.tsx +22 -22
- package/src/components/Tabs.d.ts +109 -0
- package/src/components/Tabs.tsx +15 -1
- package/{dist/define-routes.js → src/define-routes.d.ts} +2 -4
- package/src/define-routes.ts +1 -1
- package/src/hooks/use-focus.d.ts +45 -0
- package/src/hooks/use-focus.ts +2 -2
- package/src/hooks/use-hardware-back.d.ts +37 -0
- package/src/hooks/use-hardware-back.ts +1 -1
- package/src/hooks/use-linking-nav.d.ts +91 -0
- package/src/hooks/use-linking-nav.ts +4 -4
- package/src/hooks/use-nav-internal.d.ts +91 -0
- package/src/hooks/use-nav-internal.ts +24 -3
- package/src/hooks/use-nav-serializer.d.ts +82 -0
- package/src/hooks/use-nav-serializer.ts +3 -3
- package/src/hooks/use-nav.d.ts +111 -0
- package/src/hooks/use-nav.ts +2 -2
- package/{dist/hooks/use-params.js → src/hooks/use-params.d.ts} +2 -6
- package/src/hooks/use-params.ts +2 -2
- package/src/hooks/use-screen-chrome.d.ts +18 -0
- package/src/hooks/use-screen-chrome.ts +122 -0
- package/src/hooks/use-screen-options.d.ts +2 -0
- package/src/hooks/use-screen-options.ts +3 -3
- package/{dist/hooks/use-search.js → src/hooks/use-search.d.ts} +2 -6
- package/src/hooks/use-search.ts +2 -2
- package/src/href.d.ts +54 -0
- package/src/href.ts +6 -6
- package/src/index.d.ts +39 -0
- package/src/index.ts +33 -31
- package/src/internal/layer-plan.d.ts +68 -0
- package/src/internal/layer-plan.ts +187 -0
- package/{dist/internal/screen-registry.js → src/internal/screen-registry.d.ts} +21 -32
- package/src/internal/screen-registry.ts +1 -1
- package/src/internal/screen-width.d.ts +17 -0
- package/src/internal/screen-width.ts +22 -14
- package/src/navigator/core.d.ts +96 -0
- package/src/navigator/core.ts +17 -6
- package/src/register.d.ts +37 -0
- package/src/register.ts +1 -1
- package/src/types.d.ts +217 -0
- package/src/url/build.d.ts +15 -0
- package/src/url/build.ts +2 -2
- package/src/url/compile.d.ts +34 -0
- package/src/url/format.d.ts +28 -0
- package/src/url/index.ts +6 -6
- package/src/url/parse.d.ts +20 -0
- package/src/url/parse.ts +6 -6
- package/{dist/url/registry.js → src/url/registry.d.ts} +12 -28
- package/src/url/registry.ts +3 -3
- package/src/url/validate.d.ts +23 -0
- package/src/url/validate.ts +1 -1
- package/dist/components/Drawer.js +0 -74
- package/dist/components/Drawer.js.map +0 -1
- package/dist/components/EdgeBackHandle.js +0 -144
- package/dist/components/EdgeBackHandle.js.map +0 -1
- package/dist/components/EntryScope.js.map +0 -1
- package/dist/components/Header.js +0 -103
- package/dist/components/Header.js.map +0 -1
- package/dist/components/Link.js +0 -51
- package/dist/components/Link.js.map +0 -1
- package/dist/components/NavigationRoot.js +0 -67
- package/dist/components/NavigationRoot.js.map +0 -1
- package/dist/components/Screen.js +0 -94
- package/dist/components/Screen.js.map +0 -1
- package/dist/components/ScreenContainer.d.ts +0 -18
- package/dist/components/ScreenContainer.d.ts.map +0 -1
- package/dist/components/ScreenContainer.js +0 -77
- package/dist/components/ScreenContainer.js.map +0 -1
- package/dist/components/Stack.js +0 -221
- package/dist/components/Stack.js.map +0 -1
- package/dist/components/TabBar.js +0 -63
- package/dist/components/TabBar.js.map +0 -1
- package/dist/components/Tabs.js +0 -154
- package/dist/components/Tabs.js.map +0 -1
- package/dist/define-routes.js.map +0 -1
- package/dist/hooks/use-focus.js +0 -87
- package/dist/hooks/use-focus.js.map +0 -1
- package/dist/hooks/use-hardware-back.js +0 -84
- package/dist/hooks/use-hardware-back.js.map +0 -1
- package/dist/hooks/use-linking-nav.js +0 -109
- package/dist/hooks/use-linking-nav.js.map +0 -1
- package/dist/hooks/use-nav-internal.js +0 -44
- package/dist/hooks/use-nav-internal.js.map +0 -1
- package/dist/hooks/use-nav-serializer.js +0 -181
- package/dist/hooks/use-nav-serializer.js.map +0 -1
- package/dist/hooks/use-nav.js +0 -11
- package/dist/hooks/use-nav.js.map +0 -1
- package/dist/hooks/use-params.js.map +0 -1
- package/dist/hooks/use-screen-options.js +0 -43
- package/dist/hooks/use-screen-options.js.map +0 -1
- package/dist/hooks/use-search.js.map +0 -1
- package/dist/href.js +0 -57
- package/dist/href.js.map +0 -1
- package/dist/internal/screen-registry.js.map +0 -1
- package/dist/internal/screen-width.js +0 -30
- package/dist/internal/screen-width.js.map +0 -1
- package/dist/navigator/core.js +0 -383
- package/dist/navigator/core.js.map +0 -1
- package/dist/register.js +0 -2
- package/dist/register.js.map +0 -1
- package/dist/types.js +0 -9
- package/dist/types.js.map +0 -1
- package/dist/url/build.js +0 -30
- package/dist/url/build.js.map +0 -1
- package/dist/url/compile.js +0 -83
- package/dist/url/compile.js.map +0 -1
- package/dist/url/format.js +0 -102
- package/dist/url/format.js.map +0 -1
- package/dist/url/index.js +0 -13
- package/dist/url/index.js.map +0 -1
- package/dist/url/parse.js +0 -94
- package/dist/url/parse.js.map +0 -1
- package/dist/url/registry.js.map +0 -1
- package/dist/url/validate.js +0 -37
- package/dist/url/validate.js.map +0 -1
- package/src/components/ScreenContainer.tsx +0 -114
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Logical screen
|
|
3
|
-
* Falls back to
|
|
4
|
-
* load happens BG-side after the bundle initializes, by which time
|
|
5
|
-
* `lynx.SystemInfo` is populated, so the fallback only fires in tests /
|
|
6
|
-
* non-Lynx hosts.
|
|
2
|
+
* Logical screen dimensions (in dp) read from `lynx.SystemInfo` at module
|
|
3
|
+
* load. Falls back to typical phone values if SystemInfo isn't available —
|
|
4
|
+
* module load happens BG-side after the bundle initializes, by which time
|
|
5
|
+
* `lynx.SystemInfo` is populated, so the fallback only fires in tests /
|
|
6
|
+
* SSR / non-Lynx hosts.
|
|
7
7
|
*
|
|
8
8
|
* Used by:
|
|
9
|
-
* - `<ScreenContainer>` for the slide-from-right
|
|
9
|
+
* - `<ScreenContainer>` for the slide-from-right (translateX) and
|
|
10
|
+
* slide-from-bottom (translateY, modal) transform output ranges.
|
|
10
11
|
* - `<EdgeBackHandle>` for the gesture commit threshold (`dx / width`).
|
|
11
12
|
*
|
|
12
13
|
* Both must agree, otherwise the commit threshold and the animation
|
|
13
|
-
* geometry won't line up. Single shared
|
|
14
|
+
* geometry won't line up. Single shared module avoids drift.
|
|
14
15
|
*/
|
|
15
16
|
export declare const SCREEN_WIDTH: number;
|
|
17
|
+
export declare const SCREEN_HEIGHT: number;
|
|
16
18
|
//# sourceMappingURL=screen-width.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen-width.d.ts","sourceRoot":"","sources":["../../src/internal/screen-width.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"screen-width.d.ts","sourceRoot":"","sources":["../../src/internal/screen-width.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA0BH,eAAO,MAAM,YAAY,QAA4B,CAAC;AACtD,eAAO,MAAM,aAAa,QAA6B,CAAC"}
|
package/dist/navigator/core.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
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
|
|
2
|
+
import type { Nav } from '../hooks/use-nav';
|
|
3
|
+
import type { ScreenRegistry } from '../internal/screen-registry';
|
|
4
|
+
import type { RouteMap, StackEntry } from '../types';
|
|
5
5
|
/**
|
|
6
6
|
* The reactive backing state for one navigator instance.
|
|
7
7
|
*
|
|
@@ -45,7 +45,8 @@ export interface NavigatorState {
|
|
|
45
45
|
*/
|
|
46
46
|
readonly _screens: {
|
|
47
47
|
register(registry: ScreenRegistry): void;
|
|
48
|
-
|
|
48
|
+
/** Identity-checked: no-op when a newer registry has taken the slot. */
|
|
49
|
+
unregister(registry: ScreenRegistry): void;
|
|
49
50
|
get(entryKey: string): ScreenRegistry | undefined;
|
|
50
51
|
};
|
|
51
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/navigator/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,WAAW,EACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/navigator/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,WAAW,EACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAIR,QAAQ,EACR,UAAU,EAEb,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE;QACf,gBAAgB,IAAI,IAAI,CAAC;QACzB,iBAAiB,IAAI,IAAI,CAAC;QAC1B,iBAAiB,IAAI,IAAI,CAAC;KAC7B,CAAC;IACF;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,QAAQ,EAAE;QACf,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;QACzC,wEAAwE;QACxE,UAAU,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;QAC3C,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;KACrD,CAAC;IACF;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3D;AAuED,MAAM,WAAW,sBAAsB;IACnC,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACpB;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,sBAAsB,GAAG,cAAc,CA0TjF"}
|
package/dist/register.d.ts
CHANGED
package/dist/register.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,QAAQ;CAExB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,QAAQ,CAAC;AAEnF,8EAA8E;AAC9E,MAAM,MAAM,OAAO,GAAG,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,IAAI,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3E,+CAA+C;AAC/C,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,OAAO,IAAI,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/url/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* Not re-exported from the package root. Public surface is `hrefFor` /
|
|
5
5
|
* `parseHref` in ../href.ts plus `_setRouteRegistry` for tests/bootstrap.
|
|
6
6
|
*/
|
|
7
|
-
export { compilePath, type CompiledPath } from './compile
|
|
8
|
-
export { buildUrl } from './build
|
|
9
|
-
export { parseHrefImpl } from './parse
|
|
10
|
-
export { formatSearch, parseSearch } from './format
|
|
11
|
-
export { _setRouteRegistry, _clearRouteRegistry, getRouteRegistry, getCompiledPath, } from './registry
|
|
12
|
-
export { validateSync, type ValidateOutcome } from './validate
|
|
7
|
+
export { compilePath, type CompiledPath } from './compile';
|
|
8
|
+
export { buildUrl } from './build';
|
|
9
|
+
export { parseHrefImpl } from './parse';
|
|
10
|
+
export { formatSearch, parseSearch } from './format';
|
|
11
|
+
export { _setRouteRegistry, _clearRouteRegistry, getRouteRegistry, getCompiledPath, } from './registry';
|
|
12
|
+
export { validateSync, type ValidateOutcome } from './validate';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/url/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/url/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/url/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EACH,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/url/parse.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Validation failures return `null` rather than throwing — deep-link handlers
|
|
10
10
|
* fall back to the initial route on a bad URL instead of crashing the app.
|
|
11
11
|
*/
|
|
12
|
-
import type { Href } from '../href
|
|
12
|
+
import type { Href } from '../href';
|
|
13
13
|
/**
|
|
14
14
|
* Parse a URL string against the active route registry.
|
|
15
15
|
*
|
package/dist/url/parse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/url/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/url/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAQpC;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAkCtD"}
|
package/dist/url/registry.d.ts
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* directly. The leading underscore is a convention: not part of the supported
|
|
12
12
|
* public API (test/integration use only).
|
|
13
13
|
*/
|
|
14
|
-
import type { CompiledPath } from './compile
|
|
15
|
-
import type { RouteMap } from '../types
|
|
14
|
+
import type { CompiledPath } from './compile';
|
|
15
|
+
import type { RouteMap } from '../types';
|
|
16
16
|
interface RegistryState {
|
|
17
17
|
readonly routes: RouteMap;
|
|
18
18
|
/** Lazy-compiled paths keyed by route name. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/url/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/url/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,aAAa;IACnB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAChD;AAID;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAExD;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,IAAI,aAAa,CAOhD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAU1F"}
|
package/dist/url/validate.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* resolution) so we restrict to sync validators. Zod/Valibot/ArkType are all
|
|
6
6
|
* sync, which covers the common case. Async validators throw a clear error.
|
|
7
7
|
*/
|
|
8
|
-
import type { StandardSchemaV1 } from '../types
|
|
8
|
+
import type { StandardSchemaV1 } from '../types';
|
|
9
9
|
/** Outcome of a sync validation call — discriminated for explicit handling. */
|
|
10
10
|
export type ValidateOutcome = {
|
|
11
11
|
readonly ok: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/url/validate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/url/validate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAmBjD,+EAA+E;AAC/E,MAAM,MAAM,eAAe,GACrB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC9C;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,YAAY,CACxB,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,KAAK,EAAE,OAAO,GACf,eAAe,CAiBjB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigx/lynx-navigation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Type-first native navigator for sigx-lynx — Stack, Tabs, Drawer, modals, lazy routes, deep links",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"@sigx/lynx": "^0.
|
|
20
|
-
"@sigx/lynx
|
|
21
|
-
"@sigx/lynx-
|
|
19
|
+
"@sigx/lynx-linking": "^0.4.0",
|
|
20
|
+
"@sigx/lynx": "^0.4.0",
|
|
21
|
+
"@sigx/lynx-motion": "^0.4.0"
|
|
22
22
|
},
|
|
23
23
|
"peerDependenciesMeta": {
|
|
24
24
|
"@sigx/lynx-linking": {
|
|
@@ -28,10 +28,11 @@
|
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"typescript": "^6.0.3",
|
|
30
30
|
"vitest": "^4.1.6",
|
|
31
|
-
"@sigx/
|
|
32
|
-
"@sigx/lynx
|
|
33
|
-
"@sigx/lynx-
|
|
34
|
-
"@sigx/lynx-testing": "^0.
|
|
31
|
+
"@sigx/vite": "^0.4.3",
|
|
32
|
+
"@sigx/lynx": "^0.4.0",
|
|
33
|
+
"@sigx/lynx-linking": "^0.4.0",
|
|
34
|
+
"@sigx/lynx-testing": "^0.4.0",
|
|
35
|
+
"@sigx/lynx-motion": "^0.4.0"
|
|
35
36
|
},
|
|
36
37
|
"keywords": [
|
|
37
38
|
"sigx",
|
|
@@ -59,8 +60,8 @@
|
|
|
59
60
|
"access": "public"
|
|
60
61
|
},
|
|
61
62
|
"scripts": {
|
|
62
|
-
"build": "
|
|
63
|
-
"dev": "
|
|
63
|
+
"build": "vite build && tsgo --emitDeclarationOnly",
|
|
64
|
+
"dev": "vite build --watch",
|
|
64
65
|
"test": "vitest run",
|
|
65
66
|
"test:types": "tsc --noEmit",
|
|
66
67
|
"bench": "vitest bench --run"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Drawer>` — minimal off-canvas drawer navigator.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* <NavigationRoot routes={routes}>
|
|
8
|
+
* <Drawer slots={{ sidebar: () => <view><text>Menu</text></view> }}>
|
|
9
|
+
* <Stack />
|
|
10
|
+
* </Drawer>
|
|
11
|
+
* </NavigationRoot>
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* `useDrawer()` from inside any descendant gives `{ isOpen, open(), close(),
|
|
15
|
+
* toggle() }`. The sidebar is laid out absolutely on the left and is
|
|
16
|
+
* visible whenever `isOpen` is true.
|
|
17
|
+
*
|
|
18
|
+
* Scope: this slice ships the state primitive + the bare-bones layout.
|
|
19
|
+
* Gesture-driven open (edge swipe from the left) and MTS slide-in are out
|
|
20
|
+
* of scope — the app shell can wrap its sidebar JSX in its own transition.
|
|
21
|
+
*
|
|
22
|
+
* Design note: the sidebar lives in a named slot (`sidebar`) rather than
|
|
23
|
+
* a render-prop or a `<Drawer.Sidebar>` child. Mixing
|
|
24
|
+
* "register-yourself-as-a-fill" children with the parent's own visible
|
|
25
|
+
* layout creates a feedback loop in sigx's reactive scope (the parent's
|
|
26
|
+
* render reads the fill, child's setup writes it, parent re-renders,
|
|
27
|
+
* child re-mounts, …). A scoped slot avoids that entirely and keeps the
|
|
28
|
+
* call site declarative.
|
|
29
|
+
*
|
|
30
|
+
* `default` slot is the main content (almost always a `<Stack>`).
|
|
31
|
+
*/
|
|
32
|
+
import { type Define } from '@sigx/lynx';
|
|
33
|
+
/** Reactive controller returned by `useDrawer()`. */
|
|
34
|
+
export interface DrawerNav {
|
|
35
|
+
/** True when the drawer is currently visible. Reactive. */
|
|
36
|
+
readonly isOpen: boolean;
|
|
37
|
+
/** Opens the drawer. */
|
|
38
|
+
open(): void;
|
|
39
|
+
/** Closes the drawer. */
|
|
40
|
+
close(): void;
|
|
41
|
+
/** Toggles between open and closed. */
|
|
42
|
+
toggle(): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Access the enclosing Drawer navigator. Throws when called outside
|
|
46
|
+
* `<Drawer>`.
|
|
47
|
+
*/
|
|
48
|
+
export declare const useDrawer: import("@sigx/runtime-core").InjectableFunction<DrawerNav>;
|
|
49
|
+
type DrawerProps = Define.Prop<'initialOpen', boolean> & Define.Slot<'sidebar'> & Define.Slot<'default'>;
|
|
50
|
+
export declare const Drawer: import("@sigx/runtime-core").ComponentFactory<DrawerProps, void, {
|
|
51
|
+
sidebar: () => import("@sigx/runtime-core").JSXElement | import("@sigx/runtime-core").JSXElement[] | null;
|
|
52
|
+
} & {
|
|
53
|
+
default: () => import("@sigx/runtime-core").JSXElement | import("@sigx/runtime-core").JSXElement[] | null;
|
|
54
|
+
}>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const EdgeBackHandle: import("@sigx/runtime-core").ComponentFactory<{}, void, unknown>;
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
type MainThread,
|
|
8
8
|
} from '@sigx/lynx';
|
|
9
9
|
import { withTiming } from '@sigx/lynx-motion';
|
|
10
|
-
import { useNavInternals } from '../hooks/use-nav-internal
|
|
11
|
-
import { SCREEN_WIDTH } from '../internal/screen-width
|
|
10
|
+
import { useNavInternals } from '../hooks/use-nav-internal';
|
|
11
|
+
import { SCREEN_WIDTH } from '../internal/screen-width';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Edge-pan recognizer for iOS-style swipe-back. Mounts as an absolutely-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { type Define } from '@sigx/lynx';
|
|
2
|
+
import type { StackEntry } from '../types';
|
|
3
|
+
type EntryScopeProps = Define.Prop<'entry', StackEntry, true> & Define.Slot<'default'>;
|
|
4
4
|
/**
|
|
5
5
|
* Provider wrapper for a single screen mount.
|
|
6
6
|
*
|
|
@@ -19,15 +19,7 @@ import { createScreenRegistry } from '../internal/screen-registry.js';
|
|
|
19
19
|
* Renders the default slot directly; no extra layout element is inserted,
|
|
20
20
|
* so this is layout-neutral for the screen it wraps.
|
|
21
21
|
*/
|
|
22
|
-
export const EntryScope
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
onUnmounted(() => {
|
|
27
|
-
internals.screens.unregister(props.entry.key);
|
|
28
|
-
});
|
|
29
|
-
defineProvide(useCurrentEntry, () => props.entry);
|
|
30
|
-
defineProvide(useScreenRegistry, () => registry);
|
|
31
|
-
return () => slots.default?.();
|
|
32
|
-
});
|
|
33
|
-
//# sourceMappingURL=EntryScope.js.map
|
|
22
|
+
export declare const EntryScope: import("@sigx/runtime-core").ComponentFactory<EntryScopeProps, void, {
|
|
23
|
+
default: () => import("@sigx/runtime-core").JSXElement | import("@sigx/runtime-core").JSXElement[] | null;
|
|
24
|
+
}>;
|
|
25
|
+
export {};
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { component, defineProvide, onUnmounted, type Define } from '@sigx/lynx';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
useCurrentEntry,
|
|
4
|
+
useCurrentEntryOptional,
|
|
5
|
+
useNavInternals,
|
|
6
|
+
useScreenRegistry,
|
|
7
|
+
} from '../hooks/use-nav-internal';
|
|
8
|
+
import { createScreenRegistry } from '../internal/screen-registry';
|
|
9
|
+
import type { StackEntry } from '../types';
|
|
5
10
|
|
|
6
11
|
type EntryScopeProps =
|
|
7
12
|
& Define.Prop<'entry', StackEntry, true>
|
|
@@ -30,9 +35,15 @@ export const EntryScope = component<EntryScopeProps>(({ props, slots }) => {
|
|
|
30
35
|
const registry = createScreenRegistry(props.entry);
|
|
31
36
|
internals.screens.register(registry);
|
|
32
37
|
onUnmounted(() => {
|
|
33
|
-
|
|
38
|
+
// Pass the registry instance — `unregister` is identity-checked,
|
|
39
|
+
// so this is a no-op when a newer EntryScope has already taken
|
|
40
|
+
// over the same entry key (e.g. at the transition→idle handoff
|
|
41
|
+
// where the reconciler mounts the new EntryScope before
|
|
42
|
+
// unmounting the old).
|
|
43
|
+
internals.screens.unregister(registry);
|
|
34
44
|
});
|
|
35
45
|
defineProvide(useCurrentEntry, () => props.entry);
|
|
46
|
+
defineProvide(useCurrentEntryOptional, () => props.entry);
|
|
36
47
|
defineProvide(useScreenRegistry, () => registry);
|
|
37
48
|
return () => slots.default?.();
|
|
38
49
|
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent header chrome. Mount once above `<Stack>`; reactively follows
|
|
3
|
+
* the focused entry. No props in v1 — styling is a host-app concern,
|
|
4
|
+
* arrived at through the slot fills.
|
|
5
|
+
*/
|
|
6
|
+
export declare const Header: import("@sigx/runtime-core").ComponentFactory<{}, void, unknown>;
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
* - making it opt-in keeps `<Stack>`'s contract narrow.
|
|
21
21
|
*/
|
|
22
22
|
import { component, computed } from '@sigx/lynx';
|
|
23
|
-
import { useNav } from '../hooks/use-nav
|
|
24
|
-
import { useNavInternals } from '../hooks/use-nav-internal
|
|
25
|
-
import type { ScreenOptions, ScreenSlotFills, StackEntry } from '../types
|
|
23
|
+
import { useNav } from '../hooks/use-nav';
|
|
24
|
+
import { useNavInternals } from '../hooks/use-nav-internal';
|
|
25
|
+
import type { ScreenOptions, ScreenSlotFills, StackEntry } from '../types';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Resolve a title (string or getter) to a plain string.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Layer>` — one row in `<Stack>`'s layered render. Absolutely-
|
|
3
|
+
* positioned host view that fills the Stack's relative wrapper, with
|
|
4
|
+
* an optional MT-bound `translateX` / `translateY` animation driven
|
|
5
|
+
* by a `SharedValue<number>` from the navigator's transition state.
|
|
6
|
+
*
|
|
7
|
+
* `<Stack>` emits one `<Layer>` per entry returned by
|
|
8
|
+
* `computeLayers(...)`. Layer.key in the parent is
|
|
9
|
+
* `layer-${entry.key}-${animationVariant(animation)}` so that:
|
|
10
|
+
*
|
|
11
|
+
* - The same entry under the same animation state is preserved across
|
|
12
|
+
* renders (modal underneath stays mounted through the modal
|
|
13
|
+
* lifecycle; per-tab Stack state survives).
|
|
14
|
+
* - An entry transitioning between animated and static (e.g. a card
|
|
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.
|
|
19
|
+
*
|
|
20
|
+
* Layouts:
|
|
21
|
+
* - Host view is `position: absolute; top/right/bottom/left: 0;
|
|
22
|
+
* display: flex; flexDirection: column` so descendants that
|
|
23
|
+
* flex-fill (SafeAreaView, daisyui screens) get a sized parent.
|
|
24
|
+
* - No background. Screens own their own surface colour (typically
|
|
25
|
+
* via a daisy `bg-base-*` class on the screen body).
|
|
26
|
+
*/
|
|
27
|
+
import { type ComponentFactory, type Define } from '@sigx/lynx';
|
|
28
|
+
import type { LayerAnimation } from '../internal/layer-plan';
|
|
29
|
+
import type { RouteMap, StackEntry } from '../types';
|
|
30
|
+
export type LayerProps = Define.Prop<'entry', StackEntry, true> & Define.Prop<'routes', RouteMap, true>
|
|
31
|
+
/** When set, the host view animates per the transform spec. */
|
|
32
|
+
& Define.Prop<'animation', LayerAnimation | null, false>;
|
|
33
|
+
export declare const Layer: ComponentFactory<LayerProps, void, {}>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<Layer>` — one row in `<Stack>`'s layered render. Absolutely-
|
|
3
|
+
* positioned host view that fills the Stack's relative wrapper, with
|
|
4
|
+
* an optional MT-bound `translateX` / `translateY` animation driven
|
|
5
|
+
* by a `SharedValue<number>` from the navigator's transition state.
|
|
6
|
+
*
|
|
7
|
+
* `<Stack>` emits one `<Layer>` per entry returned by
|
|
8
|
+
* `computeLayers(...)`. Layer.key in the parent is
|
|
9
|
+
* `layer-${entry.key}-${animationVariant(animation)}` so that:
|
|
10
|
+
*
|
|
11
|
+
* - The same entry under the same animation state is preserved across
|
|
12
|
+
* renders (modal underneath stays mounted through the modal
|
|
13
|
+
* lifecycle; per-tab Stack state survives).
|
|
14
|
+
* - An entry transitioning between animated and static (e.g. a card
|
|
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.
|
|
19
|
+
*
|
|
20
|
+
* Layouts:
|
|
21
|
+
* - Host view is `position: absolute; top/right/bottom/left: 0;
|
|
22
|
+
* display: flex; flexDirection: column` so descendants that
|
|
23
|
+
* flex-fill (SafeAreaView, daisyui screens) get a sized parent.
|
|
24
|
+
* - No background. Screens own their own surface colour (typically
|
|
25
|
+
* via a daisy `bg-base-*` class on the screen body).
|
|
26
|
+
*/
|
|
27
|
+
import {
|
|
28
|
+
component,
|
|
29
|
+
useMainThreadRef,
|
|
30
|
+
useAnimatedStyle,
|
|
31
|
+
type ComponentFactory,
|
|
32
|
+
type Define,
|
|
33
|
+
type MainThread,
|
|
34
|
+
} from '@sigx/lynx';
|
|
35
|
+
import { Suspense, isLazyComponent } from '@sigx/lynx';
|
|
36
|
+
import type { LayerAnimation } from '../internal/layer-plan';
|
|
37
|
+
import type { RouteMap, StackEntry } from '../types';
|
|
38
|
+
import { EntryScope } from './EntryScope';
|
|
39
|
+
|
|
40
|
+
export type LayerProps =
|
|
41
|
+
& Define.Prop<'entry', StackEntry, true>
|
|
42
|
+
& Define.Prop<'routes', RouteMap, true>
|
|
43
|
+
/** When set, the host view animates per the transform spec. */
|
|
44
|
+
& Define.Prop<'animation', LayerAnimation | null, false>;
|
|
45
|
+
|
|
46
|
+
export const Layer = component<LayerProps>(({ props }) => {
|
|
47
|
+
const ref = useMainThreadRef<MainThread.Element | null>(null);
|
|
48
|
+
// `useAnimatedStyle` binds once at setup. Calling it conditionally
|
|
49
|
+
// is safe because setup runs once per mount and props.animation
|
|
50
|
+
// never changes for a given Layer instance — animation changes
|
|
51
|
+
// re-key the Layer at the parent, forcing a fresh mount.
|
|
52
|
+
if (props.animation) {
|
|
53
|
+
const a = props.animation;
|
|
54
|
+
useAnimatedStyle(ref, a.progress, a.axis, {
|
|
55
|
+
inputRange: [a.inputRange[0], a.inputRange[1]],
|
|
56
|
+
outputRange: [a.outputRange[0], a.outputRange[1]],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return () => {
|
|
61
|
+
const route = props.routes[props.entry.route];
|
|
62
|
+
if (!route) return null;
|
|
63
|
+
const Comp = route.component as unknown as ComponentFactory<
|
|
64
|
+
Record<string, unknown>,
|
|
65
|
+
unknown,
|
|
66
|
+
unknown
|
|
67
|
+
>;
|
|
68
|
+
if (typeof Comp !== 'function') return null;
|
|
69
|
+
const entryParams = props.entry.params as Record<string, unknown>;
|
|
70
|
+
const body = isLazyComponent(Comp) && route.fallback
|
|
71
|
+
? (
|
|
72
|
+
<Suspense fallback={route.fallback as never}>
|
|
73
|
+
<Comp {...entryParams} />
|
|
74
|
+
</Suspense>
|
|
75
|
+
)
|
|
76
|
+
: <Comp {...entryParams} />;
|
|
77
|
+
return (
|
|
78
|
+
<view
|
|
79
|
+
main-thread:ref={ref}
|
|
80
|
+
style={{
|
|
81
|
+
position: 'absolute',
|
|
82
|
+
top: '0',
|
|
83
|
+
left: '0',
|
|
84
|
+
right: '0',
|
|
85
|
+
bottom: '0',
|
|
86
|
+
display: 'flex',
|
|
87
|
+
flexDirection: 'column',
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
<EntryScope key={props.entry.key} entry={props.entry}>
|
|
91
|
+
{body}
|
|
92
|
+
</EntryScope>
|
|
93
|
+
</view>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { RouteId, RouteParams, RouteSearch } from '../register';
|
|
2
|
+
import type { RoutesWithParams } from '../hooks/use-nav';
|
|
3
|
+
/**
|
|
4
|
+
* Per-route conditional props for `<Link>`.
|
|
5
|
+
*
|
|
6
|
+
* Mapped over `RouteId`, then indexed by `RouteId` to flatten into a union.
|
|
7
|
+
* Each branch enforces the `params`-required-iff-route-has-schema rule:
|
|
8
|
+
*
|
|
9
|
+
* - `<Link to="profile" />` → TS error (profile requires params)
|
|
10
|
+
* - `<Link to="profile" params={...} />` → ok
|
|
11
|
+
* - `<Link to="home" />` → ok (home has no params)
|
|
12
|
+
* - `<Link to="home" params={...} />` → TS error (home accepts no params)
|
|
13
|
+
*
|
|
14
|
+
* Same per-route discrimination as `nav.push`, expressed as a JSX-friendly
|
|
15
|
+
* union rather than overloads.
|
|
16
|
+
*/
|
|
17
|
+
type LinkPropsByRoute = {
|
|
18
|
+
[K in RouteId]: K extends RoutesWithParams ? {
|
|
19
|
+
to: K;
|
|
20
|
+
params: RouteParams<K>;
|
|
21
|
+
search?: RouteSearch<K>;
|
|
22
|
+
} : {
|
|
23
|
+
to: K;
|
|
24
|
+
params?: undefined;
|
|
25
|
+
search?: RouteSearch<K>;
|
|
26
|
+
};
|
|
27
|
+
}[RouteId];
|
|
28
|
+
/**
|
|
29
|
+
* Public type for `<Link>`'s props. The conditional `LinkPropsByRoute` carries
|
|
30
|
+
* the typed `to`/`params`/`search` triple; the rest are simple optionals.
|
|
31
|
+
*
|
|
32
|
+
* `children` is declared explicitly because the public type is exposed via a
|
|
33
|
+
* type-cast (so JSX sees a function-shaped signature). The cast strips sigx's
|
|
34
|
+
* built-in `Define.Slot<'default'>` → JSX-children wiring, so we add a
|
|
35
|
+
* permissive `children?` slot ourselves.
|
|
36
|
+
*/
|
|
37
|
+
export type LinkProps = LinkPropsByRoute & {
|
|
38
|
+
/** Use `replace` instead of `push` (no new history entry). */
|
|
39
|
+
replace?: boolean;
|
|
40
|
+
/** Link content rendered inside the tappable container. */
|
|
41
|
+
children?: unknown;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Declarative navigation. Same typing as `nav.push` — pass `params` only when
|
|
45
|
+
* the route declares a schema. Wraps a `<view>` that fires `nav.push` (or
|
|
46
|
+
* `nav.replace` if `replace` is set) on tap.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <Link to="home">Home</Link>
|
|
51
|
+
* <Link to="profile" params={{ id: '42' }}>View profile</Link>
|
|
52
|
+
* <Link to="profile" params={{ id: '42' }} search={{ tab: 'about' }}>About</Link>
|
|
53
|
+
* <Link to="settings" replace>Settings (no back)</Link>
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* The cast widens the inferred prop type from the loose impl to the strict
|
|
57
|
+
* `LinkProps` so JSX usage gets per-route discrimination. Runtime is identical.
|
|
58
|
+
*/
|
|
59
|
+
export declare const Link: (props: LinkProps) => unknown;
|
|
60
|
+
export {};
|
package/src/components/Link.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { component, type Define } from '@sigx/lynx';
|
|
2
|
-
import { useNav } from '../hooks/use-nav
|
|
3
|
-
import { useNavRoutes } from '../hooks/use-nav-internal
|
|
4
|
-
import type { RouteId, RouteParams, RouteSearch } from '../register
|
|
5
|
-
import type { RoutesWithParams } from '../hooks/use-nav
|
|
2
|
+
import { useNav } from '../hooks/use-nav';
|
|
3
|
+
import { useNavRoutes } from '../hooks/use-nav-internal';
|
|
4
|
+
import type { RouteId, RouteParams, RouteSearch } from '../register';
|
|
5
|
+
import type { RoutesWithParams } from '../hooks/use-nav';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Per-route conditional props for `<Link>`.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Define } from '@sigx/lynx';
|
|
2
|
+
import type { RouteId } from '../register';
|
|
3
|
+
import type { RouteMap } from '../types';
|
|
4
|
+
type NavigationRootProps = Define.Prop<'routes', RouteMap, true> & Define.Prop<'initialRoute', RouteId> & Define.Prop<'initialParams', Record<string, unknown>> & Define.Prop<'initialSearch', Record<string, unknown>>
|
|
5
|
+
/**
|
|
6
|
+
* Enable slide-from-right transitions on push/pop. Defaults to true.
|
|
7
|
+
* Tests against `@sigx/lynx-testing` (which doesn't have an MT runtime)
|
|
8
|
+
* should pass `animated={false}` so navigations commit synchronously.
|
|
9
|
+
*/
|
|
10
|
+
& Define.Prop<'animated', boolean>
|
|
11
|
+
/**
|
|
12
|
+
* Enable the iOS-style edge-swipe-back gesture. Defaults to true. Set
|
|
13
|
+
* to false if it conflicts with screen content on the leftmost 20px,
|
|
14
|
+
* or while debugging gesture issues.
|
|
15
|
+
*/
|
|
16
|
+
& Define.Prop<'edgeSwipeEnabled', boolean> & Define.Slot<'default'>;
|
|
17
|
+
/**
|
|
18
|
+
* Root of a navigator subtree.
|
|
19
|
+
*
|
|
20
|
+
* Creates a fresh `NavigatorState` from `routes` and provides it via
|
|
21
|
+
* `defineProvide`, so descendant `<Stack>` / `<Screen>` components and any
|
|
22
|
+
* `useNav()` / `useParams()` calls resolve through this instance.
|
|
23
|
+
*
|
|
24
|
+
* The bottom-of-stack entry is built from `initialRoute` (defaults to the
|
|
25
|
+
* first key in `routes`). For routes that declare a params schema, you must
|
|
26
|
+
* pass `initialParams` matching that schema.
|
|
27
|
+
*
|
|
28
|
+
* Mirrors the install pattern of `@sigx/router` (see
|
|
29
|
+
* `packages/router/src/router.ts:519-528`), but at component scope rather than
|
|
30
|
+
* `app.use(router)` — no app-wide singleton, so multi-navigator apps and
|
|
31
|
+
* tests get isolated state for free.
|
|
32
|
+
*/
|
|
33
|
+
export declare const NavigationRoot: import("@sigx/runtime-core").ComponentFactory<NavigationRootProps, void, {
|
|
34
|
+
default: () => import("@sigx/runtime-core").JSXElement | import("@sigx/runtime-core").JSXElement[] | null;
|
|
35
|
+
}>;
|
|
36
|
+
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { component, defineProvide, useSharedValue, type Define } from '@sigx/lynx';
|
|
2
|
-
import { createNavigatorState } from '../navigator/core
|
|
3
|
-
import { useNav } from '../hooks/use-nav
|
|
4
|
-
import { useNavInternals, useNavRoutes } from '../hooks/use-nav-internal
|
|
5
|
-
import type { RouteId } from '../register
|
|
6
|
-
import type { Presentation, RouteMap, StackEntry } from '../types
|
|
7
|
-
import { _setRouteRegistry } from '../url/registry
|
|
2
|
+
import { createNavigatorState } from '../navigator/core';
|
|
3
|
+
import { useNav } from '../hooks/use-nav';
|
|
4
|
+
import { useNavInternals, useNavRoutes } from '../hooks/use-nav-internal';
|
|
5
|
+
import type { RouteId } from '../register';
|
|
6
|
+
import type { Presentation, RouteMap, StackEntry } from '../types';
|
|
7
|
+
import { _setRouteRegistry } from '../url/registry';
|
|
8
8
|
|
|
9
9
|
type NavigationRootProps =
|
|
10
10
|
& Define.Prop<'routes', RouteMap, true>
|