@sigx/lynx-navigation 0.1.3 → 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.
Files changed (196) hide show
  1. package/README.md +189 -7
  2. package/dist/components/EntryScope.d.ts +1 -1
  3. package/dist/components/EntryScope.d.ts.map +1 -1
  4. package/dist/components/Layer.d.ts +34 -0
  5. package/dist/components/Layer.d.ts.map +1 -0
  6. package/dist/components/Link.d.ts +2 -2
  7. package/dist/components/Link.d.ts.map +1 -1
  8. package/dist/components/NavigationRoot.d.ts +2 -2
  9. package/dist/components/NavigationRoot.d.ts.map +1 -1
  10. package/dist/components/Screen.d.ts +6 -6
  11. package/dist/components/Screen.d.ts.map +1 -1
  12. package/dist/components/Stack.d.ts +83 -13
  13. package/dist/components/Stack.d.ts.map +1 -1
  14. package/dist/components/TabBar.d.ts +19 -20
  15. package/dist/components/TabBar.d.ts.map +1 -1
  16. package/dist/components/Tabs.d.ts +30 -21
  17. package/dist/components/Tabs.d.ts.map +1 -1
  18. package/dist/define-routes.d.ts +1 -1
  19. package/dist/define-routes.d.ts.map +1 -1
  20. package/dist/hooks/use-focus.d.ts.map +1 -1
  21. package/dist/hooks/use-hardware-back.d.ts +9 -2
  22. package/dist/hooks/use-hardware-back.d.ts.map +1 -1
  23. package/dist/hooks/use-linking-nav.d.ts +3 -3
  24. package/dist/hooks/use-linking-nav.d.ts.map +1 -1
  25. package/dist/hooks/use-nav-internal.d.ts +21 -3
  26. package/dist/hooks/use-nav-internal.d.ts.map +1 -1
  27. package/dist/hooks/use-nav-serializer.d.ts +1 -1
  28. package/dist/hooks/use-nav-serializer.d.ts.map +1 -1
  29. package/dist/hooks/use-nav.d.ts +38 -3
  30. package/dist/hooks/use-nav.d.ts.map +1 -1
  31. package/dist/hooks/use-params.d.ts +1 -1
  32. package/dist/hooks/use-params.d.ts.map +1 -1
  33. package/dist/hooks/use-screen-chrome.d.ts +19 -0
  34. package/dist/hooks/use-screen-chrome.d.ts.map +1 -0
  35. package/dist/hooks/use-screen-options.d.ts +1 -1
  36. package/dist/hooks/use-screen-options.d.ts.map +1 -1
  37. package/dist/hooks/use-search.d.ts +1 -1
  38. package/dist/hooks/use-search.d.ts.map +1 -1
  39. package/dist/href.d.ts +2 -2
  40. package/dist/href.d.ts.map +1 -1
  41. package/dist/index.d.ts +33 -31
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +1160 -29
  44. package/dist/index.js.map +1 -1
  45. package/dist/internal/layer-plan.d.ts +69 -0
  46. package/dist/internal/layer-plan.d.ts.map +1 -0
  47. package/dist/internal/screen-registry.d.ts +1 -1
  48. package/dist/internal/screen-registry.d.ts.map +1 -1
  49. package/dist/internal/screen-width.d.ts +9 -7
  50. package/dist/internal/screen-width.d.ts.map +1 -1
  51. package/dist/navigator/core.d.ts +31 -4
  52. package/dist/navigator/core.d.ts.map +1 -1
  53. package/dist/register.d.ts +1 -1
  54. package/dist/register.d.ts.map +1 -1
  55. package/dist/url/index.d.ts +6 -6
  56. package/dist/url/index.d.ts.map +1 -1
  57. package/dist/url/parse.d.ts +1 -1
  58. package/dist/url/parse.d.ts.map +1 -1
  59. package/dist/url/registry.d.ts +2 -2
  60. package/dist/url/registry.d.ts.map +1 -1
  61. package/dist/url/validate.d.ts +1 -1
  62. package/dist/url/validate.d.ts.map +1 -1
  63. package/package.json +11 -10
  64. package/src/components/Drawer.d.ts +55 -0
  65. package/src/components/EdgeBackHandle.d.ts +1 -0
  66. package/src/components/EdgeBackHandle.tsx +2 -2
  67. package/{dist/components/EntryScope.js → src/components/EntryScope.d.ts} +7 -15
  68. package/src/components/EntryScope.tsx +15 -4
  69. package/src/components/Header.d.ts +6 -0
  70. package/src/components/Header.tsx +3 -3
  71. package/src/components/Layer.d.ts +33 -0
  72. package/src/components/Layer.tsx +96 -0
  73. package/src/components/Link.d.ts +60 -0
  74. package/src/components/Link.tsx +4 -4
  75. package/src/components/NavigationRoot.d.ts +36 -0
  76. package/src/components/NavigationRoot.tsx +6 -6
  77. package/src/components/Screen.d.ts +97 -0
  78. package/src/components/Screen.tsx +13 -11
  79. package/src/components/Stack.d.ts +90 -0
  80. package/src/components/Stack.tsx +333 -92
  81. package/src/components/TabBar.d.ts +38 -0
  82. package/src/components/TabBar.tsx +22 -22
  83. package/src/components/Tabs.d.ts +109 -0
  84. package/src/components/Tabs.tsx +54 -22
  85. package/{dist/define-routes.js → src/define-routes.d.ts} +2 -4
  86. package/src/define-routes.ts +1 -1
  87. package/{dist/hooks/use-focus.js → src/hooks/use-focus.d.ts} +3 -39
  88. package/src/hooks/use-focus.ts +9 -3
  89. package/src/hooks/use-hardware-back.d.ts +37 -0
  90. package/src/hooks/use-hardware-back.ts +43 -9
  91. package/src/hooks/use-linking-nav.d.ts +91 -0
  92. package/src/hooks/use-linking-nav.ts +4 -4
  93. package/src/hooks/use-nav-internal.d.ts +91 -0
  94. package/src/hooks/use-nav-internal.ts +24 -3
  95. package/src/hooks/use-nav-serializer.d.ts +82 -0
  96. package/src/hooks/use-nav-serializer.ts +3 -3
  97. package/src/hooks/use-nav.d.ts +111 -0
  98. package/src/hooks/use-nav.ts +40 -3
  99. package/{dist/hooks/use-params.js → src/hooks/use-params.d.ts} +2 -6
  100. package/src/hooks/use-params.ts +2 -2
  101. package/src/hooks/use-screen-chrome.d.ts +18 -0
  102. package/src/hooks/use-screen-chrome.ts +122 -0
  103. package/src/hooks/use-screen-options.d.ts +2 -0
  104. package/src/hooks/use-screen-options.ts +3 -3
  105. package/{dist/hooks/use-search.js → src/hooks/use-search.d.ts} +2 -6
  106. package/src/hooks/use-search.ts +2 -2
  107. package/src/href.d.ts +54 -0
  108. package/src/href.ts +6 -6
  109. package/src/index.d.ts +39 -0
  110. package/src/index.ts +33 -31
  111. package/src/internal/layer-plan.d.ts +68 -0
  112. package/src/internal/layer-plan.ts +187 -0
  113. package/{dist/internal/screen-registry.js → src/internal/screen-registry.d.ts} +21 -32
  114. package/src/internal/screen-registry.ts +1 -1
  115. package/src/internal/screen-width.d.ts +17 -0
  116. package/src/internal/screen-width.ts +22 -14
  117. package/src/navigator/core.d.ts +96 -0
  118. package/src/navigator/core.ts +90 -10
  119. package/src/register.d.ts +37 -0
  120. package/src/register.ts +1 -1
  121. package/src/types.d.ts +217 -0
  122. package/src/url/build.d.ts +15 -0
  123. package/src/url/build.ts +2 -2
  124. package/src/url/compile.d.ts +34 -0
  125. package/src/url/format.d.ts +28 -0
  126. package/src/url/index.ts +6 -6
  127. package/src/url/parse.d.ts +20 -0
  128. package/src/url/parse.ts +6 -6
  129. package/{dist/url/registry.js → src/url/registry.d.ts} +12 -28
  130. package/src/url/registry.ts +3 -3
  131. package/src/url/validate.d.ts +23 -0
  132. package/src/url/validate.ts +1 -1
  133. package/dist/components/Drawer.js +0 -74
  134. package/dist/components/Drawer.js.map +0 -1
  135. package/dist/components/EdgeBackHandle.js +0 -144
  136. package/dist/components/EdgeBackHandle.js.map +0 -1
  137. package/dist/components/EntryScope.js.map +0 -1
  138. package/dist/components/Header.js +0 -103
  139. package/dist/components/Header.js.map +0 -1
  140. package/dist/components/Link.js +0 -51
  141. package/dist/components/Link.js.map +0 -1
  142. package/dist/components/NavigationRoot.js +0 -67
  143. package/dist/components/NavigationRoot.js.map +0 -1
  144. package/dist/components/Screen.js +0 -94
  145. package/dist/components/Screen.js.map +0 -1
  146. package/dist/components/ScreenContainer.d.ts +0 -18
  147. package/dist/components/ScreenContainer.d.ts.map +0 -1
  148. package/dist/components/ScreenContainer.js +0 -77
  149. package/dist/components/ScreenContainer.js.map +0 -1
  150. package/dist/components/Stack.js +0 -75
  151. package/dist/components/Stack.js.map +0 -1
  152. package/dist/components/TabBar.js +0 -63
  153. package/dist/components/TabBar.js.map +0 -1
  154. package/dist/components/Tabs.js +0 -140
  155. package/dist/components/Tabs.js.map +0 -1
  156. package/dist/define-routes.js.map +0 -1
  157. package/dist/hooks/use-focus.js.map +0 -1
  158. package/dist/hooks/use-hardware-back.js +0 -50
  159. package/dist/hooks/use-hardware-back.js.map +0 -1
  160. package/dist/hooks/use-linking-nav.js +0 -109
  161. package/dist/hooks/use-linking-nav.js.map +0 -1
  162. package/dist/hooks/use-nav-internal.js +0 -44
  163. package/dist/hooks/use-nav-internal.js.map +0 -1
  164. package/dist/hooks/use-nav-serializer.js +0 -181
  165. package/dist/hooks/use-nav-serializer.js.map +0 -1
  166. package/dist/hooks/use-nav.js +0 -11
  167. package/dist/hooks/use-nav.js.map +0 -1
  168. package/dist/hooks/use-params.js.map +0 -1
  169. package/dist/hooks/use-screen-options.js +0 -43
  170. package/dist/hooks/use-screen-options.js.map +0 -1
  171. package/dist/hooks/use-search.js.map +0 -1
  172. package/dist/href.js +0 -57
  173. package/dist/href.js.map +0 -1
  174. package/dist/internal/screen-registry.js.map +0 -1
  175. package/dist/internal/screen-width.js +0 -30
  176. package/dist/internal/screen-width.js.map +0 -1
  177. package/dist/navigator/core.js +0 -344
  178. package/dist/navigator/core.js.map +0 -1
  179. package/dist/register.js +0 -2
  180. package/dist/register.js.map +0 -1
  181. package/dist/types.js +0 -9
  182. package/dist/types.js.map +0 -1
  183. package/dist/url/build.js +0 -30
  184. package/dist/url/build.js.map +0 -1
  185. package/dist/url/compile.js +0 -83
  186. package/dist/url/compile.js.map +0 -1
  187. package/dist/url/format.js +0 -102
  188. package/dist/url/format.js.map +0 -1
  189. package/dist/url/index.js +0 -13
  190. package/dist/url/index.js.map +0 -1
  191. package/dist/url/parse.js +0 -94
  192. package/dist/url/parse.js.map +0 -1
  193. package/dist/url/registry.js.map +0 -1
  194. package/dist/url/validate.js +0 -37
  195. package/dist/url/validate.js.map +0 -1
  196. package/src/components/ScreenContainer.tsx +0 -114
@@ -1,77 +0,0 @@
1
- import { jsx as _jsx } from "@sigx/lynx/jsx-runtime";
2
- import { component, useMainThreadRef, useAnimatedStyle, } from '@sigx/lynx';
3
- import { Suspense, isLazyComponent } from '@sigx/lynx';
4
- import { SCREEN_WIDTH } from '../internal/screen-width.js';
5
- import { EntryScope } from './EntryScope.js';
6
- /**
7
- * Slide-from-right transition geometry. `SCREEN_WIDTH` is read from
8
- * `lynx.SystemInfo` at module load so the animation lands the screen at
9
- * exactly translateX=0 (centered) at progress=1, rather than overshooting
10
- * into the parent's clip region. `<EdgeBackHandle>` reads the same
11
- * constant — they have to agree, otherwise the gesture commit threshold
12
- * and the animation geometry don't line up.
13
- */
14
- const PARALLAX_FACTOR = 0.3;
15
- /**
16
- * Compute the `translateX` range for a given (role, kind) pair. Progress
17
- * always runs 0 → 1; the role and kind decide what visual state each end of
18
- * the progress represents.
19
- *
20
- * Slide-from-right semantics:
21
- * - PUSH: new top slides in from the right; old top parallaxes left.
22
- * - POP: current top slides out to the right; underneath returns from the
23
- * parallax-left position.
24
- */
25
- function getRangeParams(role, kind) {
26
- if (kind === 'push') {
27
- if (role === 'top') {
28
- return { inputRange: [0, 1], outputRange: [SCREEN_WIDTH, 0] };
29
- }
30
- return { inputRange: [0, 1], outputRange: [0, -PARALLAX_FACTOR * SCREEN_WIDTH] };
31
- }
32
- // pop
33
- if (role === 'top') {
34
- return { inputRange: [0, 1], outputRange: [0, SCREEN_WIDTH] };
35
- }
36
- return { inputRange: [0, 1], outputRange: [-PARALLAX_FACTOR * SCREEN_WIDTH, 0] };
37
- }
38
- /**
39
- * Animated screen slot — absolutely positioned, MT-bound translateX driven by
40
- * the navigator's progress SharedValue. Used during transitions to render the
41
- * top + underneath entries together.
42
- *
43
- * Each instance is keyed by `${entry.key}-${role}-${kind}` in the parent so a
44
- * role/kind change forces a fresh mount with a fresh `useAnimatedStyle`
45
- * binding (the binding is set at setup and can't be re-keyed mid-life). State
46
- * loss across transition boundaries is accepted in v0.2; persistent screen
47
- * state (scroll position, input fields surviving navigations) is a polish
48
- * item for Phase 0.5+.
49
- */
50
- export const ScreenContainer = component(({ props }) => {
51
- const ref = useMainThreadRef(null);
52
- const params = getRangeParams(props.role, props.kind);
53
- useAnimatedStyle(ref, props.progress, 'translateX', params);
54
- return () => {
55
- const route = props.routes[props.entry.route];
56
- if (!route)
57
- return null;
58
- const Comp = route.component;
59
- if (typeof Comp !== 'function')
60
- return null;
61
- const entryParams = props.entry.params;
62
- // Wrap lazy screens that declare a fallback in Suspense — see Stack.tsx
63
- // for rationale.
64
- const body = isLazyComponent(Comp) && route.fallback
65
- ? (_jsx(Suspense, { fallback: route.fallback, children: _jsx(Comp, { ...entryParams }) }))
66
- : _jsx(Comp, { ...entryParams });
67
- return (_jsx("view", { "main-thread:ref": ref, style: {
68
- position: 'absolute',
69
- top: '0',
70
- left: '0',
71
- right: '0',
72
- bottom: '0',
73
- backgroundColor: '#0f172a',
74
- }, children: _jsx(EntryScope, { entry: props.entry, children: body }, props.entry.key) }));
75
- };
76
- });
77
- //# sourceMappingURL=ScreenContainer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ScreenContainer.js","sourceRoot":"","sources":["../../src/components/ScreenContainer.tsx"],"names":[],"mappings":"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"}
@@ -1,75 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "@sigx/lynx/jsx-runtime";
2
- import { component } from '@sigx/lynx';
3
- import { Suspense, isLazyComponent } from '@sigx/lynx';
4
- import { useNav } from '../hooks/use-nav.js';
5
- import { useNavInternals, useNavRoutes } from '../hooks/use-nav-internal.js';
6
- import { ScreenContainer } from './ScreenContainer.js';
7
- import { EdgeBackHandle } from './EdgeBackHandle.js';
8
- import { EntryScope } from './EntryScope.js';
9
- /**
10
- * Stack navigator — renders the topmost stack entry's component at rest, or
11
- * the top + underneath entries during a transition.
12
- *
13
- * **Idle**: just the top entry, full-bleed, no transform. The screen
14
- * component mounts directly so it can use its own layout (no extra absolute
15
- * positioning that would break percentage heights).
16
- *
17
- * **Transitioning**: two `<ScreenContainer>` instances stacked absolutely,
18
- * each with an MT-driven `translateX` that reads from the navigator's
19
- * progress `SharedValue`. The host's BG thread doesn't tick per frame —
20
- * `useAnimatedStyle` runs the interpolation entirely on MT.
21
- *
22
- * `key={top.key}` keeps the idle render's component instance stable across
23
- * unrelated re-renders. During transitions, composite keys
24
- * (`${entry.key}-${role}-${kind}`) ensure a fresh mount per role/kind pair so
25
- * the `useAnimatedStyle` binding is set with the right input/output ranges.
26
- */
27
- export const Stack = component(() => {
28
- const nav = useNav();
29
- const routes = useNavRoutes();
30
- const internals = useNavInternals();
31
- return () => {
32
- const transition = nav.transition;
33
- const top = nav.current;
34
- if (!transition) {
35
- const route = routes[top.route];
36
- if (!route)
37
- return null;
38
- const Comp = route.component;
39
- if (typeof Comp !== 'function')
40
- return null;
41
- const params = top.params;
42
- // Wrap lazy routes that declare a `fallback` in <Suspense> so the
43
- // chunk-load shows the user-provided spinner instead of throwing
44
- // up to the nearest outer boundary (which may be wrong layer or
45
- // missing entirely).
46
- const body = isLazyComponent(Comp) && route.fallback
47
- ? (_jsx(Suspense, { fallback: route.fallback, children: _jsx(Comp, { ...params }) }))
48
- : _jsx(Comp, { ...params });
49
- // When canGoBack and edge-swipe is enabled, overlay the gesture
50
- // handle so the user can pan from the left edge to start a back
51
- // transition. `position: absolute` doesn't disturb the screen's
52
- // own layout — the handle only intercepts touches in the leftmost
53
- // 20px, and only when they pan rightward past `MIN_DISTANCE`.
54
- if (nav.canGoBack && internals.edgeSwipeEnabled) {
55
- return (_jsxs("view", { style: {
56
- position: 'relative',
57
- width: '100%',
58
- height: '100%',
59
- }, children: [_jsx(EntryScope, { entry: top, children: body }, top.key), _jsx(EdgeBackHandle, {}, "edge-back")] }));
60
- }
61
- return (_jsx(EntryScope, { entry: top, children: body }, top.key));
62
- }
63
- // Cast progress: TransitionState carries it as `unknown` to avoid
64
- // pinning the contract to `@sigx/lynx`'s SharedValue at the type
65
- // level; here at the runtime boundary we know it's a SharedValue<number>.
66
- const progress = transition.progress;
67
- return (_jsxs("view", { style: {
68
- position: 'relative',
69
- width: '100%',
70
- height: '100%',
71
- overflow: 'hidden',
72
- }, children: [_jsx(ScreenContainer, { entry: transition.underneathEntry, routes: routes, role: "underneath", kind: transition.kind, progress: progress }, `${transition.underneathEntry.key}-underneath-${transition.kind}`), _jsx(ScreenContainer, { entry: transition.topEntry, routes: routes, role: "top", kind: transition.kind, progress: progress }, `${transition.topEntry.key}-top-${transition.kind}`)] }));
73
- };
74
- });
75
- //# sourceMappingURL=Stack.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Stack.js","sourceRoot":"","sources":["../../src/components/Stack.tsx"],"names":[],"mappings":"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"}
@@ -1,63 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "@sigx/lynx/jsx-runtime";
2
- /**
3
- * `<TabBar>` — default chrome for `<Tabs>`.
4
- *
5
- * Renders a row of tab buttons reading from the enclosing `useTabs()`
6
- * navigator. Active tab is highlighted via the `active` prop on each
7
- * default button (consumers can re-style via `renderTab`).
8
- *
9
- * Customization knobs:
10
- * - `renderTab`: a function `(info, ctx) => JSX` that fully replaces the
11
- * default button rendering for each tab. `ctx.active` tells the
12
- * consumer whether this tab is currently focused; `ctx.onPress`
13
- * activates the tab.
14
- *
15
- * Accessibility:
16
- * - Each default button gets `accessibility-label` from
17
- * `info.accessibilityLabel ?? info.label ?? info.name`.
18
- * - Each default button gets `accessibility-element="true"` so screen
19
- * readers see the whole pill, not just the inner `<text>`.
20
- * - Each default button gets `accessibility-trait="button"` and a
21
- * `selected` flag on the active one so VoiceOver/TalkBack announces
22
- * focus state on tab switch.
23
- *
24
- * Placement: mount inside `<Tabs>` alongside the `<Tabs.Screen>`s. Order
25
- * matters visually (place above or below the screen bodies depending on
26
- * the layout), and `<Tabs.Screen>` bodies all stack with `display:flex` so
27
- * the TabBar should be at a deterministic position in the JSX.
28
- */
29
- import { component, } from '@sigx/lynx';
30
- import { useTabs } from './Tabs.js';
31
- /**
32
- * Default per-tab button. Plain `<view>` with a `<text>` inside, an
33
- * `accessibility-*` cluster for screen readers, and a tap handler. No
34
- * styling beyond a minimal active-state marker — consumers that want
35
- * branded chrome pass `renderTab`.
36
- */
37
- const DefaultTabButton = component(({ props }) => {
38
- return () => {
39
- const label = props.info.label ?? props.info.name;
40
- const a11y = props.info.accessibilityLabel ?? label;
41
- return (_jsxs("view", { bindtap: () => props.onPress(), "accessibility-element": true, "accessibility-label": a11y, "accessibility-trait": "button", "accessibility-status": props.active ? 'selected' : undefined, style: { opacity: props.active ? 1 : 0.6 }, children: [props.info.icon ?? null, _jsx("text", { children: label })] }));
42
- };
43
- });
44
- export const TabBar = component(({ props }) => {
45
- const nav = useTabs();
46
- return () => {
47
- // Reading `nav.tabs` and `nav.active` here ties this render to both
48
- // the registration list and the active signal — switching active or
49
- // adding/removing a `<Tabs.Screen>` updates the bar reactively.
50
- const tabs = nav.tabs;
51
- const active = nav.active;
52
- const renderer = props.renderTab;
53
- return (_jsx("view", { "accessibility-element": false, children: tabs.map((info) => {
54
- const isActive = info.name === active;
55
- const onPress = () => nav.setActive(info.name);
56
- if (renderer) {
57
- return renderer(info, { active: isActive, onPress });
58
- }
59
- return (_jsx(DefaultTabButton, { info: info, active: isActive, onPress: onPress }));
60
- }) }));
61
- };
62
- });
63
- //# sourceMappingURL=TabBar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TabBar.js","sourceRoot":"","sources":["../../src/components/TabBar.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EACH,SAAS,GAGZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAalD;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG,SAAS,CAIhC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACZ,OAAO,GAAG,EAAE;QACR,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAClD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,KAAK,CAAC;QACpD,OAAO,CACH,gBACI,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,2BACP,IAAI,yBACN,IAAI,yBACL,QAAQ,0BACN,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAC3D,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,aAEzC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EACxB,yBAAO,KAAK,GAAQ,IACjB,CACV,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,SAAS,CAAc,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;IACvD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,OAAO,GAAG,EAAE;QACR,oEAAoE;QACpE,oEAAoE;QACpE,gEAAgE;QAChE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;QACjC,OAAO,CACH,wCAA6B,KAAK,YAC7B,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACf,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;gBACtC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/C,IAAI,QAAQ,EAAE,CAAC;oBACX,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,CACH,KAAC,gBAAgB,IACb,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,OAAO,GAClB,CACL,CAAC;YACN,CAAC,CAAC,GACC,CACV,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC,CAAC"}
@@ -1,140 +0,0 @@
1
- import { jsx as _jsx } from "@sigx/lynx/jsx-runtime";
2
- /**
3
- * `<Tabs>` — Lynx tab navigator.
4
- *
5
- * Usage:
6
- *
7
- * ```tsx
8
- * <NavigationRoot routes={routes}>
9
- * <Tabs initialTab="feed">
10
- * <Tabs.Screen name="feed" icon={<FeedIcon />} label="Feed">
11
- * <FeedView />
12
- * </Tabs.Screen>
13
- * <Tabs.Screen name="me" icon={<MeIcon />} label="Profile">
14
- * <ProfileView />
15
- * </Tabs.Screen>
16
- * </Tabs>
17
- * </NavigationRoot>
18
- * ```
19
- *
20
- * Scope of this slice (v0.1): pure UI primitive. Each tab's body stays
21
- * mounted for state preservation (the inactive ones render with
22
- * `display: 'none'`). Active tab is reactive via `useTabs()`.
23
- *
24
- * Out of scope (deferred to a nested-navigators slice):
25
- * - Per-tab `<Stack>` with its own navigator state machine
26
- * - `nav.parent` chain into the Tabs nav
27
- * - Named navigators (`useNav('root')`)
28
- *
29
- * Those build on multi-navigator-state plumbing that isn't ready yet.
30
- * For now, the inner content of a `<Tabs.Screen>` shares the same nav as
31
- * its outer `<NavigationRoot>` — usable for shallow tab apps, but full
32
- * nested routing comes later.
33
- */
34
- import { component, compound, defineInjectable, defineProvide, onUnmounted, signal, untrack, } from '@sigx/lynx';
35
- /**
36
- * Access the enclosing Tabs navigator. Throws when called outside `<Tabs>`.
37
- */
38
- export const useTabs = defineInjectable(() => {
39
- throw new Error('[lynx-navigation] useTabs() called outside of a <Tabs> component.');
40
- });
41
- const useTabsRegistrar = defineInjectable(() => {
42
- throw new Error('[lynx-navigation] <Tabs.Screen> rendered outside a <Tabs> component.');
43
- });
44
- const _Tabs = component(({ props, slots }) => {
45
- // Tabs are stored as a deeply-reactive proxy signal so `tabs` consumers
46
- // re-render when registration changes. `activeSignal` uses the wrapped
47
- // `{value}` pattern so we can write a `string | null` without the
48
- // proxy treating the inner string as an object.
49
- const tabs = signal([]);
50
- const activeSignal = signal({
51
- value: props.initialTab ?? null,
52
- });
53
- const registrar = {
54
- register(info) {
55
- // Wrap in untrack so registration writes inside `<Tabs.Screen>`'s
56
- // setup phase don't notify the same setup effect that issued them
57
- // — sigx's setup runs in a tracked scope by default.
58
- untrack(() => {
59
- const idx = tabs.findIndex((t) => t.name === info.name);
60
- if (idx === -1)
61
- tabs.push(info);
62
- else
63
- tabs[idx] = info;
64
- if (activeSignal.value === null) {
65
- activeSignal.value = info.name;
66
- }
67
- });
68
- },
69
- unregister(name) {
70
- untrack(() => {
71
- const idx = tabs.findIndex((t) => t.name === name);
72
- if (idx !== -1)
73
- tabs.splice(idx, 1);
74
- if (activeSignal.value === name) {
75
- activeSignal.value = tabs[0]?.name ?? null;
76
- }
77
- });
78
- },
79
- tabs,
80
- activeSignal,
81
- };
82
- const nav = {
83
- get active() {
84
- // Empty-tabs state is rare in practice (no <Tabs.Screen> yet) but
85
- // possible during initial render; expose '' rather than null so
86
- // consumers can compare strings without narrowing.
87
- return activeSignal.value ?? '';
88
- },
89
- setActive(name) {
90
- // Silently ignore unknown names rather than writing them and
91
- // hiding every tab body. Surfacing as a no-op gives consumers a
92
- // predictable failure mode for typos / dynamic name sources.
93
- if (!tabs.some((t) => t.name === name))
94
- return;
95
- activeSignal.value = name;
96
- },
97
- get tabs() {
98
- return tabs;
99
- },
100
- };
101
- defineProvide(useTabs, () => nav);
102
- defineProvide(useTabsRegistrar, () => registrar);
103
- return () => slots.default?.();
104
- });
105
- const TabsScreen = component(({ props, slots }) => {
106
- const registrar = useTabsRegistrar();
107
- // Capture `name` once at setup. Props is reactive in sigx, but using a
108
- // changing `name` for an already-registered screen would be ambiguous
109
- // (rename vs re-register?) — pin it and require callers to remount on
110
- // identity change. This matches React Navigation's contract.
111
- const name = props.name;
112
- registrar.register({
113
- name,
114
- icon: props.icon,
115
- label: props.label,
116
- accessibilityLabel: props.accessibilityLabel,
117
- });
118
- onUnmounted(() => registrar.unregister(name));
119
- return () => {
120
- // `display: none` keeps the body mounted so per-tab state survives
121
- // tab switches. Read activeSignal here so re-activating triggers a
122
- // re-render with display restored.
123
- const active = registrar.activeSignal.value === name;
124
- return (_jsx("view", { style: {
125
- display: active ? 'flex' : 'none',
126
- width: '100%',
127
- height: '100%',
128
- }, children: slots.default?.() }));
129
- };
130
- });
131
- /**
132
- * Compound export. `Tabs` is the parent component; `Tabs.Screen` registers
133
- * an individual tab. Matches the `Screen` / `Screen.Header` shape used
134
- * elsewhere in this package and the daisyui `Modal` / `Modal.Header`
135
- * convention.
136
- */
137
- export const Tabs = compound(_Tabs, {
138
- Screen: TabsScreen,
139
- });
140
- //# sourceMappingURL=Tabs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../src/components/Tabs.tsx"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"define-routes.js","sourceRoot":"","sources":["../src/define-routes.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,YAAY,CAA2B,MAAS;IAC5D,OAAO,MAAM,CAAC;AAClB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-focus.js","sourceRoot":"","sources":["../../src/hooks/use-focus.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,QAAQ,EACR,MAAM,EACN,WAAW,EACX,OAAO,GAEV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY;IACxB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,mEAAmE;IACnE,wEAAwE;IACxE,oEAAoE;IACpE,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC,GAAG,CAAC;IACpC,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,cAAc,CAAC,EAA6B;IACxD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,OAA4B,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,EAAE;QACvB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC;QAChC,oEAAoE;QACpE,mEAAmE;QACnE,qEAAqE;QACrE,wCAAwC;QACxC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,OAAO,CAAC;YACnB,OAAO,GAAG,SAAS,CAAC;YACpB,EAAE,EAAE,CAAC;QACT,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACV,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAClC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,WAAW,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,OAAO,CAAC;YACnB,OAAO,GAAG,SAAS,CAAC;YACpB,EAAE,EAAE,CAAC;QACT,CAAC;QACD,MAAM,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,50 +0,0 @@
1
- import { onMounted } from '@sigx/lynx';
2
- import { BackHandler } from '@sigx/lynx-linking';
3
- import { useNav } from './use-nav.js';
4
- /**
5
- * Wire the Android hardware back button to the active navigator.
6
- *
7
- * Listens for `hardwareBackPress` events from `@sigx/lynx-linking`'s
8
- * `BackHandler` (which the native side dispatches from
9
- * `MainActivity.onBackPressed`). On press:
10
- *
11
- * - If `nav.canGoBack` → `nav.pop()`.
12
- * - Otherwise → `BackHandler.exitApp()` (Android: `moveTaskToBack(true)`,
13
- * keeps the bundle warm; iOS: rejects, since iOS doesn't permit
14
- * programmatic termination).
15
- *
16
- * Call this once in any component under `<NavigationRoot>` (typically a
17
- * thin wrapper sibling to `<Stack />`). iOS doesn't fire the event so the
18
- * hook is a no-op there.
19
- *
20
- * @example
21
- * ```tsx
22
- * const BackHandlerWiring = component(() => {
23
- * useHardwareBack();
24
- * return () => null;
25
- * });
26
- *
27
- * <NavigationRoot routes={routes}>
28
- * <BackHandlerWiring />
29
- * <Stack />
30
- * </NavigationRoot>
31
- * ```
32
- */
33
- export function useHardwareBack() {
34
- const nav = useNav();
35
- onMounted(() => {
36
- const sub = BackHandler.addEventListener(() => {
37
- if (nav.canGoBack) {
38
- nav.pop();
39
- return true;
40
- }
41
- // At the root — leave the app. Promise is fire-and-forget; we
42
- // don't await because we want the back press to feel instant
43
- // (Android starts the move-to-back transition immediately).
44
- void BackHandler.exitApp();
45
- return true;
46
- });
47
- return () => sub.remove();
48
- });
49
- }
50
- //# sourceMappingURL=use-hardware-back.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-hardware-back.js","sourceRoot":"","sources":["../../src/hooks/use-hardware-back.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,eAAe;IAC3B,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,GAAG,WAAW,CAAC,gBAAgB,CAAC,GAAG,EAAE;YAC1C,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBAChB,GAAG,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,8DAA8D;YAC9D,6DAA6D;YAC7D,4DAA4D;YAC5D,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,109 +0,0 @@
1
- import { onMounted } from '@sigx/lynx';
2
- import { Linking } from '@sigx/lynx-linking';
3
- import { parseHref } from '../href.js';
4
- import { useNav } from './use-nav.js';
5
- import { useNavRoutes } from './use-nav-internal.js';
6
- /**
7
- * Bridge `@sigx/lynx-linking` URL events into a `@sigx/lynx-navigation`
8
- * navigator. Call once inside a `<NavigationRoot>` subtree.
9
- *
10
- * Handles both delivery modes:
11
- * - **cold start** — `Linking.getInitialURL()` is read on mount and, if
12
- * present, dispatched (replacing the initial route by default).
13
- * - **warm start** — `Linking.addEventListener('url', ...)` subscribes for
14
- * URLs delivered while the app is already running; each one is pushed.
15
- *
16
- * URL → route dispatch goes through `parseHref`, which matches the URL's
17
- * pathname against the route registry seeded by `<NavigationRoot>`. Routes
18
- * without a `path` template are never matched by deep links — only typed
19
- * `<Link>` / `nav.push` calls reach them.
20
- *
21
- * @example
22
- * ```tsx
23
- * import { useLinkingNav } from '@sigx/lynx-navigation';
24
- *
25
- * const DeepLinks = component(() => {
26
- * useLinkingNav({
27
- * prefixes: ['myapp://', 'https://myapp.com'],
28
- * onUnmatched: (url) => console.warn('Unknown deep link:', url),
29
- * });
30
- * return () => null;
31
- * });
32
- *
33
- * <NavigationRoot routes={routes}>
34
- * <DeepLinks />
35
- * <Stack />
36
- * </NavigationRoot>
37
- * ```
38
- */
39
- export function useLinkingNav(opts = {}) {
40
- const nav = useNav();
41
- const routes = useNavRoutes();
42
- const dispatch = (url, kind) => {
43
- if (opts.onURL) {
44
- opts.onURL(url, nav);
45
- return;
46
- }
47
- const stripped = _stripPrefix(url, opts.prefixes);
48
- const href = parseHref(stripped);
49
- if (!href) {
50
- opts.onUnmatched?.(url);
51
- return;
52
- }
53
- _navigateToHref(nav, routes, href, kind);
54
- };
55
- onMounted(() => {
56
- const initial = Linking.getInitialURL();
57
- if (initial) {
58
- dispatch(initial, opts.replaceInitial === false ? 'push' : 'replace');
59
- }
60
- const sub = Linking.addEventListener('url', (e) => dispatch(e.url, 'push'));
61
- return () => sub.remove();
62
- });
63
- }
64
- /**
65
- * Strip the first matching prefix from `url`, returning a pathname-like
66
- * string. If no prefixes are provided, or none match, the original URL is
67
- * returned unchanged so `parseHref` can still handle scheme-prefixed forms
68
- * via `@sigx/lynx-linking`'s `parse`.
69
- *
70
- * Exported for unit testing — not part of the package public API.
71
- */
72
- export function _stripPrefix(url, prefixes) {
73
- if (!prefixes || prefixes.length === 0)
74
- return url;
75
- for (const prefix of prefixes) {
76
- if (url.startsWith(prefix)) {
77
- const rest = url.slice(prefix.length);
78
- return rest.startsWith('/') ? rest : `/${rest}`;
79
- }
80
- }
81
- return url;
82
- }
83
- /**
84
- * Call the right `nav.push` / `nav.replace` overload for `href`. The
85
- * overloads differ in positional layout: routes with a params schema take
86
- * `(name, params, search?, options?)`; routes without take `(name, search?,
87
- * options?)`. Calling the wrong shape silently shifts `search` into the
88
- * `options` slot, so we look the route up in the registry and branch.
89
- *
90
- * Exported for unit testing — not part of the package public API.
91
- */
92
- export function _navigateToHref(nav, routes, href, kind) {
93
- const def = routes[href.route];
94
- // Defensive: `parseHref` already validated against the registry, so this
95
- // really shouldn't happen — but if the registry was cleared between
96
- // parse and dispatch (multi-NavigationRoot scenarios), bail rather than
97
- // throw.
98
- if (!def)
99
- return;
100
- const hasParams = !!def.params;
101
- const action = kind === 'replace' ? nav.replace : nav.push;
102
- if (hasParams) {
103
- action(href.route, href.params, href.search);
104
- }
105
- else {
106
- action(href.route, href.search);
107
- }
108
- }
109
- //# sourceMappingURL=use-linking-nav.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-linking-nav.js","sourceRoot":"","sources":["../../src/hooks/use-linking-nav.ts"],"names":[],"mappings":"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"}
@@ -1,44 +0,0 @@
1
- import { defineInjectable } from '@sigx/lynx';
2
- /**
3
- * Internal injectable: the `StackEntry` the calling screen was rendered for.
4
- *
5
- * Provided by `<EntryScope>` which `<Stack>` and `<ScreenContainer>` wrap
6
- * around each screen component mount. Screens use this to derive their own
7
- * focus state (`useIsFocused`, `useFocusEffect`) without having to track
8
- * `entry.key` themselves.
9
- *
10
- * Default throws so calling `useIsFocused()` outside a screen mounted by a
11
- * navigator surfaces a clear error rather than silently returning `false`.
12
- */
13
- export const useCurrentEntry = defineInjectable(() => {
14
- throw new Error('[lynx-navigation] No screen entry in scope. `useIsFocused` / `useFocusEffect` must be called from a component rendered as a route by <Stack>.');
15
- });
16
- /**
17
- * Internal injectable: the route registry passed into `<NavigationRoot>`.
18
- * Components (Stack, Screen) read this to look up route definitions by name.
19
- *
20
- * Not exported from the package barrel — use `useNav()` for navigation, and
21
- * the registry is implicit from `<NavigationRoot routes={...}>`.
22
- */
23
- export const useNavRoutes = defineInjectable(() => {
24
- throw new Error('[lynx-navigation] No <NavigationRoot> found in the component tree.');
25
- });
26
- export const useNavInternals = defineInjectable(() => {
27
- throw new Error('[lynx-navigation] No <NavigationRoot> found in the component tree.');
28
- });
29
- /**
30
- * Internal injectable: the calling screen's `ScreenRegistry`.
31
- *
32
- * Provided by `<EntryScope>` alongside `useCurrentEntry`. The `<Screen>`
33
- * component and its slot-filling sub-components write options and slot
34
- * fills here; the navigator's persistent chrome (HeaderBar, TabBar — later
35
- * slices) reads from this registry via `getScreenRegistry(key)` on the
36
- * navigator state, which keys into a cross-entry map.
37
- *
38
- * Throws when used outside an EntryScope so calling `<Screen>` at the app
39
- * root surfaces a clear error rather than silently no-op'ing.
40
- */
41
- export const useScreenRegistry = defineInjectable(() => {
42
- throw new Error('[lynx-navigation] No screen registry in scope. `<Screen>` (and `<Screen.Header>`, etc.) must be used inside a route component rendered by `<Stack>`.');
43
- });
44
- //# sourceMappingURL=use-nav-internal.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-nav-internal.js","sourceRoot":"","sources":["../../src/hooks/use-nav-internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAIhE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAa,GAAG,EAAE;IAC7D,MAAM,IAAI,KAAK,CACX,+IAA+I,CAClJ,CAAC;AACN,CAAC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAW,GAAG,EAAE;IACxD,MAAM,IAAI,KAAK,CACX,oEAAoE,CACvE,CAAC;AACN,CAAC,CAAC,CAAC;AAuCH,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAe,GAAG,EAAE;IAC/D,MAAM,IAAI,KAAK,CACX,oEAAoE,CACvE,CAAC;AACN,CAAC,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAiB,GAAG,EAAE;IACnE,MAAM,IAAI,KAAK,CACX,sJAAsJ,CACzJ,CAAC;AACN,CAAC,CAAC,CAAC"}