@symbiote-native/navigation 2.0.3 → 2.2.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 +42 -12
- package/build/angular/drawer/index.js +29 -13
- package/build/angular/index.d.ts +4 -4
- package/build/angular/injectors/inject-navigation.js +1 -1
- package/build/angular/navigation-scope.directive.js +1 -1
- package/build/angular/search-bar-ref.directive.js +1 -1
- package/build/angular/stack/index.d.ts +2 -0
- package/build/angular/stack/index.js +43 -9
- package/build/angular/tabs/index.d.ts +1 -1
- package/build/angular/tabs/index.js +40 -13
- package/build/core/drawer-options/index.js +19 -5
- package/build/core/drawer-router-state/index.js +8 -2
- package/build/core/guards.js +3 -1
- package/build/core/header-bar-buttons.js +14 -4
- package/build/core/index.d.ts +6 -5
- package/build/core/index.js +7 -3
- package/build/core/navigator-state/index.js +12 -4
- package/build/core/render-drawer.js +4 -1
- package/build/core/render-stack.js +13 -4
- package/build/core/screen-options.js +1 -1
- package/build/core/search-bar-commands.js +1 -1
- package/build/core/stack-router-state/index.d.ts +2 -0
- package/build/core/stack-router-state/index.js +44 -0
- package/build/core/state-persistence/index.js +6 -2
- package/build/core/tab-router-state/index.d.ts +1 -0
- package/build/core/tab-router-state/index.js +27 -2
- package/build/react/drawer/index.js +59 -26
- package/build/react/index.d.ts +7 -7
- package/build/react/index.js +2 -2
- package/build/react/stack/index.js +47 -10
- package/build/react/tabs/index.js +36 -12
- package/build/solid/drawer/index.d.ts +22 -0
- package/build/solid/drawer/index.js +394 -0
- package/build/solid/drawer-screen-props.d.ts +13 -0
- package/build/solid/drawer-screen-props.js +2 -0
- package/build/solid/host.d.ts +2 -0
- package/build/solid/host.js +23 -0
- package/build/solid/index.d.ts +19 -0
- package/build/solid/index.js +24 -0
- package/build/solid/linking.d.ts +3 -0
- package/build/solid/linking.js +55 -0
- package/build/solid/navigation-context.d.ts +13 -0
- package/build/solid/navigation-context.js +37 -0
- package/build/solid/primitives/create-focus-effect.d.ts +1 -0
- package/build/solid/primitives/create-focus-effect.js +30 -0
- package/build/solid/primitives/create-is-focused.d.ts +2 -0
- package/build/solid/primitives/create-is-focused.js +31 -0
- package/build/solid/primitives/create-navigation-state.d.ts +3 -0
- package/build/solid/primitives/create-navigation-state.js +30 -0
- package/build/solid/primitives/index.d.ts +12 -0
- package/build/solid/primitives/index.js +8 -0
- package/build/solid/primitives/use-drawer-navigation.d.ts +5 -0
- package/build/solid/primitives/use-drawer-navigation.js +15 -0
- package/build/solid/primitives/use-navigation.d.ts +8 -0
- package/build/solid/primitives/use-navigation.js +23 -0
- package/build/solid/primitives/use-route.d.ts +3 -0
- package/build/solid/primitives/use-route.js +14 -0
- package/build/solid/primitives/use-stack-navigation.d.ts +5 -0
- package/build/solid/primitives/use-stack-navigation.js +19 -0
- package/build/solid/primitives/use-tab-navigation.d.ts +5 -0
- package/build/solid/primitives/use-tab-navigation.js +15 -0
- package/build/solid/screen-props.d.ts +19 -0
- package/build/solid/screen-props.js +9 -0
- package/build/solid/screen-registry.d.ts +31 -0
- package/build/solid/screen-registry.js +86 -0
- package/build/solid/screen.d.ts +6 -0
- package/build/solid/screen.js +69 -0
- package/build/solid/stack/index.d.ts +15 -0
- package/build/solid/stack/index.js +348 -0
- package/build/solid/tab-screen-props.d.ts +13 -0
- package/build/solid/tab-screen-props.js +3 -0
- package/build/solid/tabs/index.d.ts +14 -0
- package/build/solid/tabs/index.js +228 -0
- package/build/svelte/attachments.d.ts +5 -0
- package/build/svelte/attachments.js +61 -0
- package/build/svelte/descriptor-subtree.d.ts +3 -0
- package/build/svelte/descriptor-subtree.js +39 -0
- package/build/svelte/drawer/drawer-props.d.ts +14 -0
- package/build/svelte/drawer/drawer-props.js +3 -0
- package/build/svelte/drawer/index.d.ts +10 -0
- package/build/svelte/drawer/index.js +6 -0
- package/build/svelte/drawer/index.svelte +559 -0
- package/build/svelte/drawer/index.svelte.d.ts +10 -0
- package/build/svelte/drawer-screen-props.d.ts +13 -0
- package/build/svelte/drawer-screen-props.js +4 -0
- package/build/svelte/drawer-screen.svelte +25 -0
- package/build/svelte/drawer-screen.svelte.d.ts +4 -0
- package/build/svelte/index.d.ts +21 -0
- package/build/svelte/index.js +20 -0
- package/build/svelte/linking.svelte.d.ts +2 -0
- package/build/svelte/linking.svelte.js +55 -0
- package/build/svelte/navigation-context.d.ts +14 -0
- package/build/svelte/navigation-context.js +44 -0
- package/build/svelte/navigation-scope.svelte +27 -0
- package/build/svelte/navigation-scope.svelte.d.ts +9 -0
- package/build/svelte/registry-host.d.ts +1 -0
- package/build/svelte/registry-host.js +26 -0
- package/build/svelte/runes/index.d.ts +12 -0
- package/build/svelte/runes/index.js +12 -0
- package/build/svelte/runes/use-drawer-navigation.svelte.d.ts +6 -0
- package/build/svelte/runes/use-drawer-navigation.svelte.js +19 -0
- package/build/svelte/runes/use-focus-effect.svelte.d.ts +1 -0
- package/build/svelte/runes/use-focus-effect.svelte.js +31 -0
- package/build/svelte/runes/use-is-focused.svelte.d.ts +3 -0
- package/build/svelte/runes/use-is-focused.svelte.js +34 -0
- package/build/svelte/runes/use-navigation-state.svelte.d.ts +4 -0
- package/build/svelte/runes/use-navigation-state.svelte.js +39 -0
- package/build/svelte/runes/use-navigation.svelte.d.ts +9 -0
- package/build/svelte/runes/use-navigation.svelte.js +26 -0
- package/build/svelte/runes/use-route.svelte.d.ts +4 -0
- package/build/svelte/runes/use-route.svelte.js +12 -0
- package/build/svelte/runes/use-stack-navigation.svelte.d.ts +6 -0
- package/build/svelte/runes/use-stack-navigation.svelte.js +22 -0
- package/build/svelte/runes/use-tab-navigation.svelte.d.ts +6 -0
- package/build/svelte/runes/use-tab-navigation.svelte.js +19 -0
- package/build/svelte/screen-props.d.ts +21 -0
- package/build/svelte/screen-props.js +6 -0
- package/build/svelte/screen-registry.d.ts +17 -0
- package/build/svelte/screen-registry.js +57 -0
- package/build/svelte/screen.svelte +28 -0
- package/build/svelte/screen.svelte.d.ts +4 -0
- package/build/svelte/stack/index.d.ts +14 -0
- package/build/svelte/stack/index.js +7 -0
- package/build/svelte/stack/index.svelte +261 -0
- package/build/svelte/stack/index.svelte.d.ts +15 -0
- package/build/svelte/stack/stack-props.d.ts +20 -0
- package/build/svelte/stack/stack-props.js +4 -0
- package/build/svelte/stack/stack-screen.svelte +205 -0
- package/build/svelte/stack/stack-screen.svelte.d.ts +4 -0
- package/build/svelte/tab-screen-props.d.ts +13 -0
- package/build/svelte/tab-screen-props.js +4 -0
- package/build/svelte/tab-screen.svelte +26 -0
- package/build/svelte/tab-screen.svelte.d.ts +4 -0
- package/build/svelte/tabs/index.d.ts +8 -0
- package/build/svelte/tabs/index.js +6 -0
- package/build/svelte/tabs/index.svelte +269 -0
- package/build/svelte/tabs/index.svelte.d.ts +8 -0
- package/build/svelte/tabs/tab-props.d.ts +7 -0
- package/build/svelte/tabs/tab-props.js +3 -0
- package/build/vue/composables/use-navigation.js +5 -1
- package/build/vue/drawer/index.js +36 -13
- package/build/vue/index.d.ts +3 -3
- package/build/vue/navigation-context.js +1 -1
- package/build/vue/stack/index.js +43 -18
- package/build/vue/tabs/index.js +65 -39
- package/build-ngc/angular/drawer/index.js +40 -18
- package/build-ngc/angular/drawer/index.js.map +1 -1
- package/build-ngc/angular/drawer-screen.directive.js +3 -3
- package/build-ngc/angular/index.d.ts +4 -4
- package/build-ngc/angular/index.js.map +1 -1
- package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -1
- package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -1
- package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -1
- package/build-ngc/angular/injectors/inject-navigation.js +1 -1
- package/build-ngc/angular/injectors/inject-navigation.js.map +1 -1
- package/build-ngc/angular/linking.js.map +1 -1
- package/build-ngc/angular/navigation-context.service.js +3 -3
- package/build-ngc/angular/navigation-context.service.js.map +1 -1
- package/build-ngc/angular/navigation-scope.directive.js +4 -4
- package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
- package/build-ngc/angular/screen.directive.js +3 -3
- package/build-ngc/angular/screen.directive.js.map +1 -1
- package/build-ngc/angular/search-bar-ref.directive.js +4 -4
- package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
- package/build-ngc/angular/stack/index.d.ts +2 -0
- package/build-ngc/angular/stack/index.js +52 -14
- package/build-ngc/angular/stack/index.js.map +1 -1
- package/build-ngc/angular/tab-screen.directive.js +3 -3
- package/build-ngc/angular/tab-screen.directive.js.map +1 -1
- package/build-ngc/angular/tabs/index.d.ts +1 -1
- package/build-ngc/angular/tabs/index.js +43 -16
- package/build-ngc/angular/tabs/index.js.map +1 -1
- package/build-ngc/core/constants.js.map +1 -1
- package/build-ngc/core/drawer-options/index.js +19 -5
- package/build-ngc/core/drawer-options/index.js.map +1 -1
- package/build-ngc/core/drawer-router-state/index.js +8 -2
- package/build-ngc/core/drawer-router-state/index.js.map +1 -1
- package/build-ngc/core/guards.js +3 -1
- package/build-ngc/core/guards.js.map +1 -1
- package/build-ngc/core/header-bar-buttons.js +14 -4
- package/build-ngc/core/header-bar-buttons.js.map +1 -1
- package/build-ngc/core/index.d.ts +6 -5
- package/build-ngc/core/index.js +7 -3
- package/build-ngc/core/index.js.map +1 -1
- package/build-ngc/core/linking-config/index.js.map +1 -1
- package/build-ngc/core/navigation-events/index.js.map +1 -1
- package/build-ngc/core/navigator-handles/index.js.map +1 -1
- package/build-ngc/core/navigator-state/index.js +12 -4
- package/build-ngc/core/navigator-state/index.js.map +1 -1
- package/build-ngc/core/render-drawer.js +4 -1
- package/build-ngc/core/render-drawer.js.map +1 -1
- package/build-ngc/core/render-stack.js +13 -4
- package/build-ngc/core/render-stack.js.map +1 -1
- package/build-ngc/core/render-tabs.js.map +1 -1
- package/build-ngc/core/screen-options.js +1 -1
- package/build-ngc/core/screen-options.js.map +1 -1
- package/build-ngc/core/search-bar-commands.js +1 -1
- package/build-ngc/core/search-bar-commands.js.map +1 -1
- package/build-ngc/core/stack-router-state/index.d.ts +2 -0
- package/build-ngc/core/stack-router-state/index.js +45 -0
- package/build-ngc/core/stack-router-state/index.js.map +1 -0
- package/build-ngc/core/state-persistence/index.js +6 -2
- package/build-ngc/core/state-persistence/index.js.map +1 -1
- package/build-ngc/core/tab-router-state/index.d.ts +1 -0
- package/build-ngc/core/tab-router-state/index.js +27 -2
- package/build-ngc/core/tab-router-state/index.js.map +1 -1
- package/package.json +44 -16
- package/src/angular/drawer/index.ts +75 -29
- package/src/angular/index.ts +20 -4
- package/src/angular/injectors/inject-focus-effect.ts +8 -2
- package/src/angular/injectors/inject-is-focused.ts +6 -4
- package/src/angular/injectors/inject-navigation-state.ts +7 -4
- package/src/angular/injectors/inject-navigation.ts +12 -3
- package/src/angular/linking.ts +4 -1
- package/src/angular/navigation-context.service.ts +5 -2
- package/src/angular/navigation-scope.directive.ts +6 -2
- package/src/angular/screen.directive.ts +13 -3
- package/src/angular/search-bar-ref.directive.ts +10 -2
- package/src/angular/stack/index.ts +91 -24
- package/src/angular/tab-screen.directive.ts +3 -1
- package/src/angular/tabs/index.ts +54 -16
- package/src/core/constants.ts +6 -3
- package/src/core/drawer-options/index.ts +40 -13
- package/src/core/drawer-router-state/index.ts +11 -3
- package/src/core/guards.ts +3 -1
- package/src/core/header-bar-buttons.ts +41 -12
- package/src/core/index.ts +29 -5
- package/src/core/linking-config/index.ts +31 -10
- package/src/core/navigation-events/index.ts +8 -2
- package/src/core/navigator-handles/index.ts +8 -3
- package/src/core/navigator-props.ts +13 -4
- package/src/core/navigator-state/index.ts +24 -7
- package/src/core/render-drawer.ts +24 -9
- package/src/core/render-stack.ts +52 -13
- package/src/core/render-tabs.ts +24 -6
- package/src/core/screen-options.ts +15 -5
- package/src/core/search-bar-commands.ts +12 -3
- package/src/core/stack-router-state/index.ts +52 -0
- package/src/core/state-persistence/index.ts +13 -3
- package/src/core/tab-router-state/index.ts +35 -3
- package/src/react/drawer/index.ts +409 -330
- package/src/react/drawer-screen.ts +8 -2
- package/src/react/hooks/use-focus-effect.ts +8 -2
- package/src/react/hooks/use-is-focused.ts +6 -2
- package/src/react/hooks/use-navigation.ts +8 -2
- package/src/react/index.ts +37 -7
- package/src/react/linking.ts +4 -1
- package/src/react/navigation-context.ts +6 -2
- package/src/react/screen.ts +12 -3
- package/src/react/stack/index.ts +297 -220
- package/src/react/tab-screen.ts +3 -1
- package/src/react/tabs/index.ts +202 -139
- package/src/solid/drawer/index.ts +570 -0
- package/src/solid/drawer-screen-props.ts +24 -0
- package/src/solid/host.ts +29 -0
- package/src/solid/index.ts +87 -0
- package/src/solid/linking.ts +74 -0
- package/src/solid/navigation-context.ts +56 -0
- package/src/solid/primitives/create-focus-effect.ts +41 -0
- package/src/solid/primitives/create-is-focused.ts +41 -0
- package/src/solid/primitives/create-navigation-state.ts +44 -0
- package/src/solid/primitives/index.ts +12 -0
- package/src/solid/primitives/use-drawer-navigation.ts +25 -0
- package/src/solid/primitives/use-navigation.ts +44 -0
- package/src/solid/primitives/use-route.ts +18 -0
- package/src/solid/primitives/use-stack-navigation.ts +29 -0
- package/src/solid/primitives/use-tab-navigation.ts +25 -0
- package/src/solid/screen-props.ts +51 -0
- package/src/solid/screen-registry.ts +159 -0
- package/src/solid/screen.ts +80 -0
- package/src/solid/stack/index.ts +528 -0
- package/src/solid/tab-screen-props.ts +21 -0
- package/src/solid/tabs/index.ts +327 -0
- package/src/svelte/attachments.ts +70 -0
- package/src/svelte/descriptor-subtree.ts +51 -0
- package/src/svelte/drawer/drawer-props.ts +28 -0
- package/src/svelte/drawer/index.svelte +559 -0
- package/src/svelte/drawer/index.ts +10 -0
- package/src/svelte/drawer-screen-props.ts +26 -0
- package/src/svelte/drawer-screen.svelte +25 -0
- package/src/svelte/fabric-tree.test-helper.ts +95 -0
- package/src/svelte/index.ts +83 -0
- package/src/svelte/linking.svelte.ts +72 -0
- package/src/svelte/navigation-context.ts +62 -0
- package/src/svelte/navigation-scope.svelte +27 -0
- package/src/svelte/registry-host.ts +26 -0
- package/src/svelte/runes/index.ts +17 -0
- package/src/svelte/runes/use-drawer-navigation.svelte.ts +31 -0
- package/src/svelte/runes/use-focus-effect.svelte.ts +41 -0
- package/src/svelte/runes/use-is-focused.svelte.ts +38 -0
- package/src/svelte/runes/use-navigation-state.svelte.ts +48 -0
- package/src/svelte/runes/use-navigation.svelte.ts +49 -0
- package/src/svelte/runes/use-route.svelte.ts +16 -0
- package/src/svelte/runes/use-stack-navigation.svelte.ts +34 -0
- package/src/svelte/runes/use-tab-navigation.svelte.ts +29 -0
- package/src/svelte/screen-props.ts +50 -0
- package/src/svelte/screen-registry.ts +98 -0
- package/src/svelte/screen.svelte +28 -0
- package/src/svelte/stack/index.svelte +261 -0
- package/src/svelte/stack/index.ts +11 -0
- package/src/svelte/stack/stack-props.ts +31 -0
- package/src/svelte/stack/stack-screen.svelte +205 -0
- package/src/svelte/svelte-ambient.d.ts +6 -0
- package/src/svelte/svelte-compile.test-helper.ts +147 -0
- package/src/svelte/tab-screen-props.ts +22 -0
- package/src/svelte/tab-screen.svelte +26 -0
- package/src/svelte/tabs/index.svelte +269 -0
- package/src/svelte/tabs/index.ts +10 -0
- package/src/svelte/tabs/tab-props.ts +13 -0
- package/src/vue/composables/use-navigation-state.ts +7 -4
- package/src/vue/composables/use-navigation.ts +13 -3
- package/src/vue/drawer/index.ts +128 -41
- package/src/vue/drawer-screen.ts +12 -5
- package/src/vue/index.ts +15 -3
- package/src/vue/linking.ts +7 -2
- package/src/vue/navigation-context.ts +17 -5
- package/src/vue/screen.ts +7 -2
- package/src/vue/stack/index.ts +108 -43
- package/src/vue/tab-screen.ts +3 -1
- package/src/vue/tabs/index.ts +109 -68
package/src/core/render-tabs.ts
CHANGED
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
import { el, txt } from '@symbiote-native/components';
|
|
11
11
|
import type { IDescriptor } from '@symbiote-native/components';
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
IColorValue,
|
|
14
|
+
IViewStyle,
|
|
15
|
+
ITextStyle,
|
|
16
|
+
IStyleProp,
|
|
17
|
+
} from '@symbiote-native/engine';
|
|
13
18
|
import type { ITabBarIcon } from './tab-options';
|
|
14
19
|
|
|
15
20
|
// react-navigation's own bottom-tabs default to the surrounding theme's primary/text colors;
|
|
@@ -96,14 +101,19 @@ function resolveTintColor(item: ITabBarItemView): IColorValue {
|
|
|
96
101
|
// for a vector-icon-font label); an IDescriptor icon (an <Image>/vector-icon element the adapter
|
|
97
102
|
// already resolved) is spliced in verbatim, exactly like renderHeaderConfig treats a pre-built
|
|
98
103
|
// Descriptor child.
|
|
99
|
-
function renderIcon(
|
|
104
|
+
function renderIcon(
|
|
105
|
+
icon: ITabBarIcon | undefined,
|
|
106
|
+
color: IColorValue,
|
|
107
|
+
): IDescriptor | undefined {
|
|
100
108
|
if (icon === undefined) return undefined;
|
|
101
109
|
if (typeof icon === 'string')
|
|
102
110
|
return txt({ style: { color, fontSize: TAB_ICON_FONT_SIZE } }, [icon]);
|
|
103
111
|
return icon;
|
|
104
112
|
}
|
|
105
113
|
|
|
106
|
-
function renderBadge(
|
|
114
|
+
function renderBadge(
|
|
115
|
+
badge: string | number | undefined,
|
|
116
|
+
): IDescriptor | undefined {
|
|
107
117
|
if (badge === undefined) return undefined;
|
|
108
118
|
return el('symbiote-view', { style: BADGE_STYLE }, [
|
|
109
119
|
txt({ style: BADGE_TEXT_STYLE }, [String(badge)]),
|
|
@@ -121,8 +131,12 @@ export function renderTabBarItem(item: ITabBarItemView): IDescriptor {
|
|
|
121
131
|
|
|
122
132
|
const children: IDescriptor[] = [];
|
|
123
133
|
if (iconChildren.length > 0)
|
|
124
|
-
children.push(
|
|
125
|
-
|
|
134
|
+
children.push(
|
|
135
|
+
el('symbiote-view', { style: ICON_WRAPPER_STYLE }, iconChildren),
|
|
136
|
+
);
|
|
137
|
+
children.push(
|
|
138
|
+
txt({ style: { color, fontSize: TAB_LABEL_FONT_SIZE } }, [item.label]),
|
|
139
|
+
);
|
|
126
140
|
|
|
127
141
|
return el(
|
|
128
142
|
'symbiote-view',
|
|
@@ -134,5 +148,9 @@ export function renderTabBarItem(item: ITabBarItemView): IDescriptor {
|
|
|
134
148
|
|
|
135
149
|
export function renderTabBar(view: ITabBarViewProps): IDescriptor {
|
|
136
150
|
const items = view.items.map(renderTabBarItem);
|
|
137
|
-
return el(
|
|
151
|
+
return el(
|
|
152
|
+
'symbiote-view',
|
|
153
|
+
{ ...view.passthrough, style: [TAB_BAR_STYLE, view.style] },
|
|
154
|
+
items,
|
|
155
|
+
);
|
|
138
156
|
}
|
|
@@ -20,7 +20,10 @@ import type {
|
|
|
20
20
|
ISheetInitialDetent,
|
|
21
21
|
ISheetLargestUndimmedDetent,
|
|
22
22
|
} from './navigator-props';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
buildHeaderBarButtonDispatch,
|
|
25
|
+
prepareHeaderBarButtonItems,
|
|
26
|
+
} from './header-bar-buttons';
|
|
24
27
|
|
|
25
28
|
// These sentinels must be kept in sync with react-native-screens' native side - they are RNS's
|
|
26
29
|
// own compat values for the 'fitToContents'/'large'/'medium'/'all' legacy presets, replicated
|
|
@@ -31,7 +34,9 @@ const SHEET_COMPAT_MEDIUM: number[] = [0.5];
|
|
|
31
34
|
const SHEET_COMPAT_ALL: number[] = [0.5, 1.0];
|
|
32
35
|
const SHEET_DIMMED_ALWAYS = -1;
|
|
33
36
|
|
|
34
|
-
function resolveSheetAllowedDetents(
|
|
37
|
+
function resolveSheetAllowedDetents(
|
|
38
|
+
compat: ISheetAllowedDetents | undefined,
|
|
39
|
+
): number[] {
|
|
35
40
|
if (compat === undefined) return SHEET_COMPAT_LARGE;
|
|
36
41
|
if (Array.isArray(compat)) return compat;
|
|
37
42
|
switch (compat) {
|
|
@@ -74,7 +79,9 @@ function resolveSheetInitialDetent(
|
|
|
74
79
|
return compat;
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
function toOptionalBooleanNativeProp(
|
|
82
|
+
function toOptionalBooleanNativeProp(
|
|
83
|
+
value: boolean | undefined,
|
|
84
|
+
): IOptionalBooleanNativeProp {
|
|
78
85
|
if (value === undefined) return 'undefined';
|
|
79
86
|
return value ? 'true' : 'false';
|
|
80
87
|
}
|
|
@@ -119,7 +126,9 @@ export function resolveScreenView(
|
|
|
119
126
|
options: IScreenOptions | undefined,
|
|
120
127
|
passthrough: Record<string, unknown> = {},
|
|
121
128
|
): IScreenViewProps {
|
|
122
|
-
const sheetAllowedDetents = resolveSheetAllowedDetents(
|
|
129
|
+
const sheetAllowedDetents = resolveSheetAllowedDetents(
|
|
130
|
+
options?.sheetAllowedDetents,
|
|
131
|
+
);
|
|
123
132
|
const lastDetentIndex = sheetAllowedDetents.length - 1;
|
|
124
133
|
return {
|
|
125
134
|
screenId,
|
|
@@ -142,7 +151,8 @@ export function resolveScreenView(
|
|
|
142
151
|
sheetExpandsWhenScrolledToEdge: options?.sheetExpandsWhenScrolledToEdge,
|
|
143
152
|
sheetElevation: options?.sheetElevation,
|
|
144
153
|
sheetShouldOverflowTopInset: options?.sheetShouldOverflowTopInset,
|
|
145
|
-
sheetDefaultResizeAnimationEnabled:
|
|
154
|
+
sheetDefaultResizeAnimationEnabled:
|
|
155
|
+
options?.sheetDefaultResizeAnimationEnabled,
|
|
146
156
|
statusBarStyle: options?.statusBarStyle,
|
|
147
157
|
statusBarHidden: options?.statusBarHidden,
|
|
148
158
|
statusBarAnimation: options?.statusBarAnimation,
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
// buildScrollViewHandle exactly (same lazy-getter shape); the adapter supplies the node getter
|
|
6
6
|
// and its own framework-specific ref field (see react/screen.ts's IReactSearchBarOptions - the
|
|
7
7
|
// ref itself is per-adapter, same split as IPressableProps).
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
dispatchViewCommand,
|
|
10
|
+
dlog,
|
|
11
|
+
type ISymbioteNode,
|
|
12
|
+
} from '@symbiote-native/engine';
|
|
9
13
|
|
|
10
14
|
export interface ISearchBarCommands {
|
|
11
15
|
focus(): void;
|
|
@@ -21,7 +25,10 @@ export interface ISearchBarCommands {
|
|
|
21
25
|
// stale handle outlived its screen) was the one unlogged gap, silently indistinguishable from
|
|
22
26
|
// "the command fired but did nothing". Investigation instrumentation (HeaderOptionsScreen
|
|
23
27
|
// unresponsive-buttons bug); kept behind DEBUG per <keep_logs_gate_behind_DEBUG>, never removed.
|
|
24
|
-
function warnIfDetached(
|
|
28
|
+
function warnIfDetached(
|
|
29
|
+
command: string,
|
|
30
|
+
node: ISymbioteNode | null,
|
|
31
|
+
): node is ISymbioteNode {
|
|
25
32
|
if (node !== null) return true;
|
|
26
33
|
dlog(
|
|
27
34
|
`SearchBarCommands.${command}: skipped, node is null (ref never attached) at t=${Date.now()}`,
|
|
@@ -45,7 +52,9 @@ function makeCommand(
|
|
|
45
52
|
|
|
46
53
|
// `getNode` is a LAZY getter, read on every call - see buildScrollViewHandle's comment for why
|
|
47
54
|
// an eager capture would freeze `null`.
|
|
48
|
-
export function buildSearchBarHandle(
|
|
55
|
+
export function buildSearchBarHandle(
|
|
56
|
+
getNode: () => ISymbioteNode | null,
|
|
57
|
+
): ISearchBarCommands {
|
|
49
58
|
return {
|
|
50
59
|
focus: makeCommand(getNode, 'focus'),
|
|
51
60
|
blur: makeCommand(getNode, 'blur'),
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// StackRouter: the registry-reconciliation half (framework-agnostic, zero render). A Stack's route
|
|
2
|
+
// list is navigation HISTORY, not a projection of the registered `<Stack.Screen>` markers the way a
|
|
3
|
+
// Tab's is (tab-router-state) - it seeds exactly one route and grows only through push/replace. So
|
|
4
|
+
// a marker that unregisters while its route still sits in the history (a marker behind an `{#if}`,
|
|
5
|
+
// a data-driven screen list) leaves behind an entry nothing can render: the route stays, the
|
|
6
|
+
// adapter's componentFor() finds no screen, and the user is parked on a blank RNSScreen with no
|
|
7
|
+
// way to tell what happened. Mirrors @react-navigation/routers' StackRouter.getStateForRouteNames-
|
|
8
|
+
// Change, which filters those routes out of the history and pulls the focused index back into
|
|
9
|
+
// range.
|
|
10
|
+
//
|
|
11
|
+
// Deliberately NOT a navigatorReducer action: this is not something a caller dispatches, it is a
|
|
12
|
+
// reaction to the registry changing underneath an unchanged history, and each adapter observes
|
|
13
|
+
// that change through its own lifecycle. Keeping it a separate pure function lets every adapter
|
|
14
|
+
// wire it its own way without teaching the reducer about a registry it has never seen.
|
|
15
|
+
|
|
16
|
+
import type { INavigatorState } from '../navigator-state';
|
|
17
|
+
|
|
18
|
+
// The contract, and the two places it deliberately parts from upstream:
|
|
19
|
+
//
|
|
20
|
+
// - SURVIVORS KEEP THEIR IDENTITY. A stack route's key is COUNTER-derived (every adapter's
|
|
21
|
+
// createRoute increments a per-navigator sequence), not name-derived like a tab route's, so
|
|
22
|
+
// re-deriving the list from the registry would hand every survivor a brand-new key and remount
|
|
23
|
+
// live screens. Only the phantom entries go; every other route object passes through by
|
|
24
|
+
// reference, params included.
|
|
25
|
+
//
|
|
26
|
+
// - THE FOCUSED ROUTE IS THE TOP ONE. This state carries no `index` field: the focused route is
|
|
27
|
+
// always the last one (see computeActivityState's comment for why no route can outrank it), so
|
|
28
|
+
// upstream's `index: Math.min(state.index, routes.length - 1)` degenerates here to "the last
|
|
29
|
+
// survivor". Dropping the FOCUSED route therefore lands the user on the nearest still-registered
|
|
30
|
+
// route beneath it - where a pop() would have left them - rather than on nothing.
|
|
31
|
+
//
|
|
32
|
+
// - THE ROUTE LIST IS NEVER EMPTIED. `routes.length - 1` IS the focused index, so an empty list
|
|
33
|
+
// means no focused route at all - the blank screen this function exists to prevent. When nothing
|
|
34
|
+
// in the history survives (every marker gone, or the whole screen set swapped for new names) the
|
|
35
|
+
// state is returned UNCHANGED. Upstream instead pushes a freshly nanoid()-keyed route for
|
|
36
|
+
// initialRouteName; we cannot, because minting a route key belongs to the caller here
|
|
37
|
+
// (navigator-state.ts's header) and a derivation that mints one would allocate a new key on every
|
|
38
|
+
// re-run. Unchanged is also the right answer for the usual cause of a momentarily empty registry
|
|
39
|
+
// - markers unregistering and re-registering across a re-render - since the next run reconciles
|
|
40
|
+
// for real.
|
|
41
|
+
export function reconcileStackRoutes(
|
|
42
|
+
state: INavigatorState,
|
|
43
|
+
registeredNames: readonly string[],
|
|
44
|
+
): INavigatorState {
|
|
45
|
+
const routes = state.routes.filter(route =>
|
|
46
|
+
registeredNames.includes(route.name),
|
|
47
|
+
);
|
|
48
|
+
// filter preserves order, so an unchanged length means nothing was dropped.
|
|
49
|
+
if (routes.length === state.routes.length || routes.length === 0)
|
|
50
|
+
return state;
|
|
51
|
+
return { routes };
|
|
52
|
+
}
|
|
@@ -11,11 +11,19 @@ import { isRecord } from '../guards';
|
|
|
11
11
|
// params: undefined}`, and JSON.stringify drops undefined-valued keys - a JSON round trip of a
|
|
12
12
|
// perfectly valid route legitimately arrives here without a `params` key at all.
|
|
13
13
|
function isRoute(value: unknown): value is IRoute<unknown> {
|
|
14
|
-
return
|
|
14
|
+
return (
|
|
15
|
+
isRecord(value) &&
|
|
16
|
+
typeof value.key === 'string' &&
|
|
17
|
+
typeof value.name === 'string'
|
|
18
|
+
);
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
function isNavigatorState(value: unknown): value is INavigatorState {
|
|
18
|
-
return
|
|
22
|
+
return (
|
|
23
|
+
isRecord(value) &&
|
|
24
|
+
Array.isArray(value.routes) &&
|
|
25
|
+
value.routes.every(isRoute)
|
|
26
|
+
);
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
export function serializeNavigatorState(state: INavigatorState): unknown {
|
|
@@ -24,7 +32,9 @@ export function serializeNavigatorState(state: INavigatorState): unknown {
|
|
|
24
32
|
|
|
25
33
|
export function deserializeNavigatorState(raw: unknown): INavigatorState {
|
|
26
34
|
if (!isNavigatorState(raw)) {
|
|
27
|
-
throw new Error(
|
|
35
|
+
throw new Error(
|
|
36
|
+
'deserializeNavigatorState: persisted value is not a valid navigator state',
|
|
37
|
+
);
|
|
28
38
|
}
|
|
29
39
|
return raw;
|
|
30
40
|
}
|
|
@@ -29,11 +29,37 @@ export function createInitialTabState(
|
|
|
29
29
|
routes: readonly IRouteEntry[],
|
|
30
30
|
initialRouteName?: string,
|
|
31
31
|
): ITabRouterState {
|
|
32
|
-
if (initialRouteName === undefined)
|
|
32
|
+
if (initialRouteName === undefined)
|
|
33
|
+
return { routes, index: INITIAL_FOCUSED_INDEX };
|
|
33
34
|
const index = routes.findIndex(route => route.name === initialRouteName);
|
|
34
35
|
return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index };
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
// A screen marker can appear or disappear after mount (a marker behind an `{#if}`, a data-driven
|
|
39
|
+
// screen list), so a navigator's route list has to follow its registry instead of staying frozen
|
|
40
|
+
// at whatever createInitialTabState saw first. Mirrors TabRouter.getStateForRouteNamesChange:
|
|
41
|
+
// membership and order come from `nextRoutes`, but a route that survives keeps its IDENTITY (its
|
|
42
|
+
// key) and everything jumpTo/setParams accumulated onto its params - only genuinely new names
|
|
43
|
+
// take their entry from `nextRoutes`. Focus follows the previously focused route's NAME, so an
|
|
44
|
+
// unrelated screen disappearing never moves the user; when the focused route is the one that
|
|
45
|
+
// disappeared, focus falls back to the first route, the same landing spot every unresolvable
|
|
46
|
+
// focus gets here (createInitialTabState's own fallback).
|
|
47
|
+
export function reconcileTabRoutes(
|
|
48
|
+
state: ITabRouterState,
|
|
49
|
+
nextRoutes: readonly IRouteEntry[],
|
|
50
|
+
): ITabRouterState {
|
|
51
|
+
const routes = nextRoutes.map(
|
|
52
|
+
next => state.routes.find(route => route.name === next.name) ?? next,
|
|
53
|
+
);
|
|
54
|
+
const isUnchanged =
|
|
55
|
+
routes.length === state.routes.length &&
|
|
56
|
+
routes.every((route, at) => route === state.routes[at]);
|
|
57
|
+
if (isUnchanged) return state;
|
|
58
|
+
const focusedName = state.routes[state.index]?.name;
|
|
59
|
+
const index = routes.findIndex(route => route.name === focusedName);
|
|
60
|
+
return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index };
|
|
61
|
+
}
|
|
62
|
+
|
|
37
63
|
// jumpTo moves the focused index to an existing route by name and optionally merges params
|
|
38
64
|
// (navigation.jumpTo(name, params) - the tab-actions doc's own signature); it never adds,
|
|
39
65
|
// removes, or reorders routes (mirrors TabRouter: JUMP_TO is a no-op when the target name isn't
|
|
@@ -52,7 +78,10 @@ export function tabRouterReducer(
|
|
|
52
78
|
}
|
|
53
79
|
const target = state.routes[index];
|
|
54
80
|
const routes = state.routes.slice();
|
|
55
|
-
routes[index] = {
|
|
81
|
+
routes[index] = {
|
|
82
|
+
...target,
|
|
83
|
+
params: mergeParams(target.params, action.params),
|
|
84
|
+
};
|
|
56
85
|
return { ...state, index, routes };
|
|
57
86
|
}
|
|
58
87
|
|
|
@@ -61,7 +90,10 @@ export function tabRouterReducer(
|
|
|
61
90
|
if (index === -1) return state;
|
|
62
91
|
const target = state.routes[index];
|
|
63
92
|
const routes = state.routes.slice();
|
|
64
|
-
routes[index] = {
|
|
93
|
+
routes[index] = {
|
|
94
|
+
...target,
|
|
95
|
+
params: mergeParams(target.params, action.params),
|
|
96
|
+
};
|
|
65
97
|
return { ...state, routes };
|
|
66
98
|
}
|
|
67
99
|
|