@symbiote-native/navigation 2.1.0 → 3.0.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 +89 -14
- package/build/angular/drawer/index.js +23 -9
- package/build/angular/index.d.ts +4 -4
- package/build/angular/index.js +1 -1
- 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.js +20 -6
- package/build/angular/tabs/index.js +21 -7
- 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 +4 -4
- package/build/core/index.js +2 -2
- 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/state-persistence/index.js +6 -2
- package/build/core/tab-router-state/index.js +8 -2
- package/build/react/drawer/index.js +36 -13
- package/build/react/index.d.ts +7 -7
- package/build/react/index.js +3 -3
- package/build/react/stack/index.js +34 -8
- package/build/react/tabs/index.js +14 -4
- 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/descriptor-subtree.js +3 -1
- package/build/svelte/drawer/index.svelte +163 -25
- package/build/svelte/drawer-screen.svelte +2 -1
- package/build/svelte/index.d.ts +3 -3
- package/build/svelte/index.js +1 -1
- package/build/svelte/navigation-scope.svelte +4 -1
- package/build/svelte/runes/use-navigation.svelte.js +5 -1
- package/build/svelte/stack/index.svelte +43 -6
- package/build/svelte/stack/stack-screen.svelte +66 -9
- package/build/svelte/tabs/index.svelte +42 -20
- package/build/vue/composables/use-navigation.js +5 -1
- package/build/vue/drawer/index.js +30 -8
- package/build/vue/index.d.ts +3 -3
- package/build/vue/index.js +1 -1
- package/build/vue/navigation-context.js +1 -1
- package/build/vue/stack/index.js +17 -6
- package/build/vue/tabs/index.js +18 -5
- package/build-ngc/angular/drawer/index.js +31 -11
- package/build-ngc/angular/drawer/index.js.map +1 -1
- 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.map +1 -1
- package/build-ngc/angular/navigation-scope.directive.js +1 -1
- package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
- package/build-ngc/angular/screen.directive.js.map +1 -1
- package/build-ngc/angular/search-bar-ref.directive.js +1 -1
- package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
- package/build-ngc/angular/stack/index.js +26 -8
- package/build-ngc/angular/stack/index.js.map +1 -1
- package/build-ngc/angular/tab-screen.directive.js.map +1 -1
- package/build-ngc/angular/tabs/index.js +21 -7
- 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 +4 -4
- package/build-ngc/core/index.js +2 -2
- 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.js.map +1 -1
- 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.js +8 -2
- package/build-ngc/core/tab-router-state/index.js.map +1 -1
- package/package.json +40 -15
- package/src/angular/drawer/index.ts +69 -25
- 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 +68 -22
- package/src/angular/tab-screen.directive.ts +3 -1
- package/src/angular/tabs/index.ts +36 -12
- 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 +18 -4
- 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 +5 -2
- package/src/core/state-persistence/index.ts +13 -3
- package/src/core/tab-router-state/index.ts +10 -3
- package/src/react/drawer/index.ts +408 -344
- 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 +294 -231
- package/src/react/tab-screen.ts +3 -1
- package/src/react/tabs/index.ts +188 -158
- 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 +3 -1
- package/src/svelte/descriptor-subtree.ts +3 -1
- package/src/svelte/drawer/index.svelte +163 -25
- package/src/svelte/drawer-screen-props.ts +8 -2
- package/src/svelte/drawer-screen.svelte +2 -1
- package/src/svelte/fabric-tree.test-helper.ts +37 -3
- package/src/svelte/index.ts +15 -3
- package/src/svelte/linking.svelte.ts +11 -5
- package/src/svelte/navigation-scope.svelte +4 -1
- package/src/svelte/runes/use-drawer-navigation.svelte.ts +3 -1
- package/src/svelte/runes/use-focus-effect.svelte.ts +8 -2
- package/src/svelte/runes/use-navigation-state.svelte.ts +3 -1
- package/src/svelte/runes/use-navigation.svelte.ts +13 -3
- package/src/svelte/runes/use-stack-navigation.svelte.ts +3 -1
- package/src/svelte/screen-props.ts +7 -2
- package/src/svelte/screen-registry.ts +9 -3
- package/src/svelte/stack/index.svelte +43 -6
- package/src/svelte/stack/stack-screen.svelte +66 -9
- package/src/svelte/svelte-compile.test-helper.ts +16 -12
- package/src/svelte/tab-screen-props.ts +3 -1
- package/src/svelte/tabs/index.svelte +42 -20
- 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 +122 -36
- 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 +82 -34
- package/src/vue/tab-screen.ts +3 -1
- package/src/vue/tabs/index.ts +51 -13
|
@@ -24,8 +24,17 @@
|
|
|
24
24
|
<script lang="ts">
|
|
25
25
|
import type { Component } from 'svelte';
|
|
26
26
|
import { onDestroy, tick } from 'svelte';
|
|
27
|
-
import {
|
|
28
|
-
|
|
27
|
+
import {
|
|
28
|
+
AnimatedValue,
|
|
29
|
+
Dimensions,
|
|
30
|
+
PanResponder,
|
|
31
|
+
dlog,
|
|
32
|
+
timing,
|
|
33
|
+
} from '@symbiote-native/engine';
|
|
34
|
+
import type {
|
|
35
|
+
IPanResponderGestureState,
|
|
36
|
+
ISymbioteEvent,
|
|
37
|
+
} from '@symbiote-native/engine';
|
|
29
38
|
// The ONLY import from the adapter's main barrel: `Animated.View` is a compiled `.svelte`
|
|
30
39
|
// component, so unlike PanResponder/Dimensions/AnimatedValue (pure engine re-exports, taken
|
|
31
40
|
// from the engine directly here) it has no `.svelte`-free home to import from.
|
|
@@ -63,7 +72,11 @@
|
|
|
63
72
|
import type { INavigationScopeValue } from '../navigation-context';
|
|
64
73
|
import NavigationScope from '../navigation-scope.svelte';
|
|
65
74
|
import { SCREEN_REGISTRY_HOST_PROPS } from '../registry-host';
|
|
66
|
-
import {
|
|
75
|
+
import {
|
|
76
|
+
setScreenCollector,
|
|
77
|
+
toRegistry,
|
|
78
|
+
withoutScreen,
|
|
79
|
+
} from '../screen-registry';
|
|
67
80
|
import type { IRegisteredScreen } from '../screen-registry';
|
|
68
81
|
import type { IDrawerScreenProps } from '../drawer-screen-props';
|
|
69
82
|
import type { IDrawerProps } from './drawer-props';
|
|
@@ -103,7 +116,9 @@
|
|
|
103
116
|
swipeMinVelocity,
|
|
104
117
|
});
|
|
105
118
|
|
|
106
|
-
let screens = $state.raw<IRegisteredScreen<IDrawerScreenProps['options']>[]>(
|
|
119
|
+
let screens = $state.raw<IRegisteredScreen<IDrawerScreenProps['options']>[]>(
|
|
120
|
+
[],
|
|
121
|
+
);
|
|
107
122
|
setScreenCollector<IDrawerScreenProps['options']>({
|
|
108
123
|
kind: 'drawer',
|
|
109
124
|
register: screen => {
|
|
@@ -123,10 +138,16 @@
|
|
|
123
138
|
|
|
124
139
|
function seedState(): IDrawerRouterState {
|
|
125
140
|
if (seededState !== undefined) return seededState;
|
|
126
|
-
const routes: IRoute<unknown>[] = [...registry.entries()].map(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
141
|
+
const routes: IRoute<unknown>[] = [...registry.entries()].map(
|
|
142
|
+
([name, entry]) => {
|
|
143
|
+
routeSequence += 1;
|
|
144
|
+
return {
|
|
145
|
+
key: `${routeIdPrefix}-${name}-${routeSequence}`,
|
|
146
|
+
name,
|
|
147
|
+
params: entry.initialParams,
|
|
148
|
+
};
|
|
149
|
+
},
|
|
150
|
+
);
|
|
130
151
|
if (routes.length === 0) {
|
|
131
152
|
dlog('Drawer: no <Drawer.Screen> children registered');
|
|
132
153
|
// Deliberately not memoized - markers may still be registering.
|
|
@@ -164,17 +185,23 @@
|
|
|
164
185
|
}
|
|
165
186
|
|
|
166
187
|
export function openDrawer(): void {
|
|
167
|
-
dlog(
|
|
188
|
+
dlog(
|
|
189
|
+
`Drawer: openDrawer() called, isOpen=${state.isOpen} at t=${Date.now()}`,
|
|
190
|
+
);
|
|
168
191
|
animateProgressTo(true);
|
|
169
192
|
dispatch({ type: 'openDrawer' });
|
|
170
193
|
}
|
|
171
194
|
export function closeDrawer(): void {
|
|
172
|
-
dlog(
|
|
195
|
+
dlog(
|
|
196
|
+
`Drawer: closeDrawer() called, isOpen=${state.isOpen} at t=${Date.now()}`,
|
|
197
|
+
);
|
|
173
198
|
animateProgressTo(false);
|
|
174
199
|
dispatch({ type: 'closeDrawer' });
|
|
175
200
|
}
|
|
176
201
|
export function toggleDrawer(): void {
|
|
177
|
-
dlog(
|
|
202
|
+
dlog(
|
|
203
|
+
`Drawer: toggleDrawer() called, isOpen=${state.isOpen} at t=${Date.now()}`,
|
|
204
|
+
);
|
|
178
205
|
animateProgressTo(!state.isOpen);
|
|
179
206
|
dispatch({ type: 'toggleDrawer' });
|
|
180
207
|
}
|
|
@@ -189,7 +216,12 @@
|
|
|
189
216
|
if (wasOpen && !state.isOpen) animateProgressTo(false);
|
|
190
217
|
}
|
|
191
218
|
|
|
192
|
-
const handle: IDrawerNavigatorHandle = {
|
|
219
|
+
const handle: IDrawerNavigatorHandle = {
|
|
220
|
+
openDrawer,
|
|
221
|
+
closeDrawer,
|
|
222
|
+
toggleDrawer,
|
|
223
|
+
jumpTo,
|
|
224
|
+
};
|
|
193
225
|
|
|
194
226
|
// The window width is read fresh AT GESTURE TIME rather than through a reactive
|
|
195
227
|
// window-dimensions rune: it is only ever consumed inside these PanResponder callbacks (never
|
|
@@ -224,8 +256,13 @@
|
|
|
224
256
|
dlog('Drawer: gesture grant');
|
|
225
257
|
dragStartProgress = state.isOpen ? 1 : 0;
|
|
226
258
|
},
|
|
227
|
-
onPanResponderMove: (
|
|
228
|
-
|
|
259
|
+
onPanResponderMove: (
|
|
260
|
+
_event: ISymbioteEvent,
|
|
261
|
+
gestureState: IPanResponderGestureState,
|
|
262
|
+
): void => {
|
|
263
|
+
progress.setValue(
|
|
264
|
+
resolveDragProgress(gestureState, dragStartProgress, options),
|
|
265
|
+
);
|
|
229
266
|
},
|
|
230
267
|
onPanResponderRelease: (
|
|
231
268
|
_event: ISymbioteEvent,
|
|
@@ -288,12 +325,16 @@
|
|
|
288
325
|
|
|
289
326
|
const panelTranslateX = $derived(
|
|
290
327
|
animated
|
|
291
|
-
? progress.interpolate(
|
|
328
|
+
? progress.interpolate(
|
|
329
|
+
resolveDrawerSlotInterpolation(geometry, 'panel').translateX,
|
|
330
|
+
)
|
|
292
331
|
: undefined,
|
|
293
332
|
);
|
|
294
333
|
const contentTranslateX = $derived(
|
|
295
334
|
animated
|
|
296
|
-
? progress.interpolate(
|
|
335
|
+
? progress.interpolate(
|
|
336
|
+
resolveDrawerSlotInterpolation(geometry, 'content').translateX,
|
|
337
|
+
)
|
|
297
338
|
: undefined,
|
|
298
339
|
);
|
|
299
340
|
// The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order (see
|
|
@@ -310,14 +351,22 @@
|
|
|
310
351
|
? undefined
|
|
311
352
|
: {
|
|
312
353
|
opacity: progress.interpolate(overlayInterpolation.opacity),
|
|
313
|
-
transform: [
|
|
354
|
+
transform: [
|
|
355
|
+
{
|
|
356
|
+
translateX: progress.interpolate(overlayInterpolation.translateX),
|
|
357
|
+
},
|
|
358
|
+
],
|
|
314
359
|
},
|
|
315
360
|
);
|
|
316
361
|
const contentStyle = $derived(
|
|
317
|
-
contentTranslateX === undefined
|
|
362
|
+
contentTranslateX === undefined
|
|
363
|
+
? undefined
|
|
364
|
+
: { transform: [{ translateX: contentTranslateX }] },
|
|
318
365
|
);
|
|
319
366
|
const panelStyle = $derived(
|
|
320
|
-
panelTranslateX === undefined
|
|
367
|
+
panelTranslateX === undefined
|
|
368
|
+
? undefined
|
|
369
|
+
: { transform: [{ translateX: panelTranslateX }] },
|
|
321
370
|
);
|
|
322
371
|
|
|
323
372
|
const focusedRoute = $derived(state.routes[state.index]);
|
|
@@ -327,7 +376,9 @@
|
|
|
327
376
|
if (focusedRoute === undefined) return undefined;
|
|
328
377
|
const entry = registry.get(focusedRoute.name);
|
|
329
378
|
if (entry === undefined) {
|
|
330
|
-
dlog(
|
|
379
|
+
dlog(
|
|
380
|
+
`Drawer: no screen registered for route name "${focusedRoute.name}"`,
|
|
381
|
+
);
|
|
331
382
|
return undefined;
|
|
332
383
|
}
|
|
333
384
|
return {
|
|
@@ -345,7 +396,8 @@
|
|
|
345
396
|
entry: IRegisteredScreen<IDrawerScreenProps['options']>,
|
|
346
397
|
route: IRoute<unknown>,
|
|
347
398
|
): IDrawerScreenOptions {
|
|
348
|
-
if (typeof entry.options === 'function')
|
|
399
|
+
if (typeof entry.options === 'function')
|
|
400
|
+
return entry.options({ route, navigation: handle });
|
|
349
401
|
return entry.options ?? {};
|
|
350
402
|
}
|
|
351
403
|
|
|
@@ -354,7 +406,10 @@
|
|
|
354
406
|
for (const route of state.routes) {
|
|
355
407
|
const entry = registry.get(route.name);
|
|
356
408
|
if (entry === undefined) continue;
|
|
357
|
-
map[route.key] = {
|
|
409
|
+
map[route.key] = {
|
|
410
|
+
options: resolveDrawerScreenOptions(entry, route),
|
|
411
|
+
navigation: handle,
|
|
412
|
+
};
|
|
358
413
|
}
|
|
359
414
|
return map;
|
|
360
415
|
});
|
|
@@ -385,11 +440,14 @@
|
|
|
385
440
|
|
|
386
441
|
// renderDrawer emits its slots as root children IN `drawerChildOrder`'s order, so the two zip
|
|
387
442
|
// together - the same index-pairing Vue's own render loop does.
|
|
388
|
-
const slotDescriptors = $derived.by<
|
|
443
|
+
const slotDescriptors = $derived.by<
|
|
444
|
+
Partial<Record<IDrawerSlot, IDescriptor>>
|
|
445
|
+
>(() => {
|
|
389
446
|
const map: Partial<Record<IDrawerSlot, IDescriptor>> = {};
|
|
390
447
|
order.forEach((slot, index) => {
|
|
391
448
|
const descriptor = root.children[index];
|
|
392
|
-
if (typeof descriptor !== 'string' && descriptor !== undefined)
|
|
449
|
+
if (typeof descriptor !== 'string' && descriptor !== undefined)
|
|
450
|
+
map[slot] = descriptor;
|
|
393
451
|
});
|
|
394
452
|
return map;
|
|
395
453
|
});
|
|
@@ -400,7 +458,87 @@
|
|
|
400
458
|
});
|
|
401
459
|
</script>
|
|
402
460
|
|
|
403
|
-
{#snippet screenContent()}
|
|
461
|
+
{#snippet screenContent()}
|
|
462
|
+
{#if focusedScreen !== undefined}
|
|
463
|
+
{@const FocusedComponent = focusedScreen.component}
|
|
464
|
+
<NavigationScope value={focusedScreen.scope}>
|
|
465
|
+
<FocusedComponent />
|
|
466
|
+
</NavigationScope>
|
|
467
|
+
{/if}
|
|
468
|
+
{/snippet}
|
|
469
|
+
|
|
470
|
+
{#snippet contentSlot()}
|
|
471
|
+
{@const descriptor = slotDescriptors.content}
|
|
472
|
+
{#if descriptor !== undefined}
|
|
473
|
+
{#if contentStyle !== undefined}
|
|
474
|
+
<Animated.View
|
|
475
|
+
{...descriptor.props}
|
|
476
|
+
style={[descriptor.props.style, contentStyle]}
|
|
477
|
+
>
|
|
478
|
+
{@render screenContent()}
|
|
479
|
+
</Animated.View>
|
|
480
|
+
{:else}
|
|
481
|
+
<symbiote-view p={descriptor.props}>
|
|
482
|
+
{@render screenContent()}
|
|
483
|
+
</symbiote-view>
|
|
484
|
+
{/if}
|
|
485
|
+
{/if}
|
|
486
|
+
{/snippet}
|
|
487
|
+
|
|
488
|
+
{#snippet overlaySlot()}
|
|
489
|
+
{@const descriptor = slotDescriptors.overlay}
|
|
490
|
+
{#if descriptor !== undefined}
|
|
491
|
+
{#if overlayStyle !== undefined}
|
|
492
|
+
<Animated.View
|
|
493
|
+
{...descriptor.props}
|
|
494
|
+
style={[descriptor.props.style, overlayStyle]}
|
|
495
|
+
/>
|
|
496
|
+
{:else}
|
|
497
|
+
<symbiote-view p={descriptor.props} />
|
|
498
|
+
{/if}
|
|
499
|
+
{/if}
|
|
500
|
+
{/snippet}
|
|
501
|
+
|
|
502
|
+
{#snippet panelSlot()}
|
|
503
|
+
{@const descriptor = slotDescriptors.panel}
|
|
504
|
+
{#if descriptor !== undefined}
|
|
505
|
+
{#if panelStyle !== undefined}
|
|
506
|
+
<Animated.View
|
|
507
|
+
{...descriptor.props}
|
|
508
|
+
style={[descriptor.props.style, panelStyle]}
|
|
509
|
+
>
|
|
510
|
+
{@render drawerContent?.({
|
|
511
|
+
state,
|
|
512
|
+
descriptors,
|
|
513
|
+
navigation: handle,
|
|
514
|
+
})}
|
|
515
|
+
</Animated.View>
|
|
516
|
+
{:else}
|
|
517
|
+
<symbiote-view p={descriptor.props}>
|
|
518
|
+
{@render drawerContent?.({
|
|
519
|
+
state,
|
|
520
|
+
descriptors,
|
|
521
|
+
navigation: handle,
|
|
522
|
+
})}
|
|
523
|
+
</symbiote-view>
|
|
524
|
+
{/if}
|
|
525
|
+
{/if}
|
|
526
|
+
{/snippet}
|
|
527
|
+
|
|
528
|
+
<symbiote-view p={rootProps}>
|
|
529
|
+
<symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
|
|
530
|
+
{@render children?.()}
|
|
531
|
+
</symbiote-text>
|
|
532
|
+
{#each order as slot (slot)}
|
|
533
|
+
{#if slot === 'content'}
|
|
534
|
+
{@render contentSlot()}
|
|
535
|
+
{:else if slot === 'overlay'}
|
|
536
|
+
{@render overlaySlot()}
|
|
537
|
+
{:else}
|
|
538
|
+
{@render panelSlot()}
|
|
539
|
+
{/if}
|
|
540
|
+
{/each}
|
|
541
|
+
</symbiote-view>
|
|
404
542
|
|
|
405
543
|
<!-- --- Explicit gap list vs the real react-native-gesture-handler + react-native-reanimated
|
|
406
544
|
@react-navigation/drawer (confirmed against its current docs, mirrored verbatim from the
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
import { collectScreen } from './screen-registry';
|
|
6
6
|
import type { IDrawerScreenProps } from './drawer-screen-props';
|
|
7
7
|
|
|
8
|
-
let { name, component, options, initialParams }: IDrawerScreenProps =
|
|
8
|
+
let { name, component, options, initialParams }: IDrawerScreenProps =
|
|
9
|
+
$props();
|
|
9
10
|
|
|
10
11
|
collectScreen('drawer', {
|
|
11
12
|
get name(): IDrawerScreenProps['name'] {
|
package/build/svelte/index.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ export { Stack } from './stack';
|
|
|
3
3
|
export type { INavigatorHandle, IStackProps } from './stack';
|
|
4
4
|
export { default as Screen } from './screen.svelte';
|
|
5
5
|
export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps, ISvelteScreenOptions, ISvelteSearchBarOptions, } from './screen-props';
|
|
6
|
-
export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
|
|
6
|
+
export type { IScreenOptions, IStackAnimation, IStackPresentation, } from '../core';
|
|
7
7
|
export { useNavigation, useStackNavigation, useTabNavigation, useDrawerNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './runes';
|
|
8
8
|
export type { INavigationHandle, IStackNavigationHandle, ITabNavigationHandle, IDrawerNavigationHandle, } from './runes';
|
|
9
|
-
export type { INavigationScopeValue, IAnyNavigatorHandle } from './navigation-context';
|
|
9
|
+
export type { INavigationScopeValue, IAnyNavigatorHandle, } from './navigation-context';
|
|
10
10
|
export { useLinkingIntegration } from './linking.svelte';
|
|
11
11
|
export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
|
|
12
12
|
export { Tab } from './tabs';
|
|
@@ -18,4 +18,4 @@ export { Drawer } from './drawer';
|
|
|
18
18
|
export type { IDrawerContentSlotProps, IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap, } from './drawer';
|
|
19
19
|
export { default as DrawerScreen } from './drawer-screen.svelte';
|
|
20
20
|
export type { IDrawerScreenOptionsArgs, IDrawerScreenOptionsResolver, IDrawerScreenProps, } from './drawer-screen-props';
|
|
21
|
-
export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';
|
|
21
|
+
export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition, } from '../core';
|
package/build/svelte/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// views' ViewConfigs (../register, a side-effect import of the codegen specs - never
|
|
4
4
|
// react-native-screens' own React components), then exposes Stack (with Stack.Screen attached)
|
|
5
5
|
// and the navigator handle. Mirrors vue/index.ts's barrel shape.
|
|
6
|
-
import '../register';
|
|
6
|
+
import '../register.js';
|
|
7
7
|
export { Stack } from './stack/index.js';
|
|
8
8
|
export { default as Screen } from './screen.svelte';
|
|
9
9
|
export { useNavigation, useStackNavigation, useTabNavigation, useDrawerNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './runes/index.js';
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
import { setNavigationScope } from './navigation-context';
|
|
13
13
|
import type { INavigationScopeValue } from './navigation-context';
|
|
14
14
|
|
|
15
|
-
let {
|
|
15
|
+
let {
|
|
16
|
+
value,
|
|
17
|
+
children,
|
|
18
|
+
}: { value: INavigationScopeValue; children?: Snippet } = $props();
|
|
16
19
|
|
|
17
20
|
setNavigationScope({
|
|
18
21
|
get current(): INavigationScopeValue {
|
|
@@ -12,7 +12,11 @@ export function useNavigation() {
|
|
|
12
12
|
const scope = requireNavigationScope('useNavigation');
|
|
13
13
|
const handle = $derived.by(() => {
|
|
14
14
|
const { navigation, emitter, parent } = scope.current;
|
|
15
|
-
return {
|
|
15
|
+
return {
|
|
16
|
+
...navigation,
|
|
17
|
+
addListener: emitter.addListener,
|
|
18
|
+
getParent: () => parent?.navigation,
|
|
19
|
+
};
|
|
16
20
|
});
|
|
17
21
|
return {
|
|
18
22
|
get current() {
|
|
@@ -48,7 +48,11 @@
|
|
|
48
48
|
import { hostProps } from '../attachments';
|
|
49
49
|
import { getNavigationScope } from '../navigation-context';
|
|
50
50
|
import { SCREEN_REGISTRY_HOST_PROPS } from '../registry-host';
|
|
51
|
-
import {
|
|
51
|
+
import {
|
|
52
|
+
setScreenCollector,
|
|
53
|
+
toRegistry,
|
|
54
|
+
withoutScreen,
|
|
55
|
+
} from '../screen-registry';
|
|
52
56
|
import type { IRegisteredScreen } from '../screen-registry';
|
|
53
57
|
import type { IScreenProps, ISvelteScreenOptions } from '../screen-props';
|
|
54
58
|
import StackScreen from './stack-screen.svelte';
|
|
@@ -100,7 +104,11 @@
|
|
|
100
104
|
dlog('Stack: no <Stack.Screen> children registered');
|
|
101
105
|
// Deliberately NOT memoized: markers may still be registering, and the next derivation run
|
|
102
106
|
// should get a real initial route rather than being stuck on this placeholder.
|
|
103
|
-
return createInitialNavigatorState({
|
|
107
|
+
return createInitialNavigatorState({
|
|
108
|
+
key: routeIdPrefix,
|
|
109
|
+
name: '',
|
|
110
|
+
params: undefined,
|
|
111
|
+
});
|
|
104
112
|
}
|
|
105
113
|
seededState = createInitialNavigatorState(
|
|
106
114
|
createRoute(startRouteName, registry.get(startRouteName)?.initialParams),
|
|
@@ -114,7 +122,9 @@
|
|
|
114
122
|
// derivation because it is PURE - it hands back the same state reference when nothing changed, so
|
|
115
123
|
// it writes no state and cannot re-trigger itself; `dispatch` below then persists the pruned
|
|
116
124
|
// history, since it reduces over this value rather than over `pushedState`.
|
|
117
|
-
const state = $derived(
|
|
125
|
+
const state = $derived(
|
|
126
|
+
reconcileStackRoutes(pushedState ?? seedState(), [...registry.keys()]),
|
|
127
|
+
);
|
|
118
128
|
|
|
119
129
|
function dispatch(action: INavigatorAction): void {
|
|
120
130
|
pushedState = navigatorReducer(state, action);
|
|
@@ -185,7 +195,8 @@
|
|
|
185
195
|
emitterFor(route.key).emit(NAVIGATION_EVENT_STATE, current);
|
|
186
196
|
}
|
|
187
197
|
for (const routeKey of [...emitters.keys()]) {
|
|
188
|
-
if (!current.routes.some(route => route.key === routeKey))
|
|
198
|
+
if (!current.routes.some(route => route.key === routeKey))
|
|
199
|
+
emitters.delete(routeKey);
|
|
189
200
|
}
|
|
190
201
|
});
|
|
191
202
|
|
|
@@ -196,7 +207,8 @@
|
|
|
196
207
|
// never removed.
|
|
197
208
|
const stackProps = resolveStackProps({
|
|
198
209
|
passthrough: {
|
|
199
|
-
[STACK_ON_FINISH_TRANSITIONING]: () =>
|
|
210
|
+
[STACK_ON_FINISH_TRANSITIONING]: () =>
|
|
211
|
+
dlog(`Stack: onFinishTransitioning at t=${Date.now()}`),
|
|
200
212
|
},
|
|
201
213
|
});
|
|
202
214
|
|
|
@@ -221,4 +233,29 @@
|
|
|
221
233
|
}
|
|
222
234
|
</script>
|
|
223
235
|
|
|
224
|
-
<symbiote-view p={STACK_ROOT_PROPS}
|
|
236
|
+
<symbiote-view p={STACK_ROOT_PROPS}>
|
|
237
|
+
<symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
|
|
238
|
+
{@render children?.()}
|
|
239
|
+
</symbiote-text>
|
|
240
|
+
<svelte:element
|
|
241
|
+
this={RNS_SCREEN_STACK_VIEW_NAME}
|
|
242
|
+
{@attach hostProps(stackProps)}
|
|
243
|
+
>
|
|
244
|
+
{#each state.routes as route, index (route.key)}
|
|
245
|
+
{@const screenComponent = componentFor(route)}
|
|
246
|
+
{#if screenComponent !== undefined}
|
|
247
|
+
<StackScreen
|
|
248
|
+
{route}
|
|
249
|
+
{index}
|
|
250
|
+
routeCount={state.routes.length}
|
|
251
|
+
options={optionsFor(route)}
|
|
252
|
+
navigation={handle}
|
|
253
|
+
emitter={emitterFor(route.key)}
|
|
254
|
+
parentScope={parentScope?.current}
|
|
255
|
+
component={screenComponent}
|
|
256
|
+
onPopRequested={popOne}
|
|
257
|
+
/>
|
|
258
|
+
{/if}
|
|
259
|
+
{/each}
|
|
260
|
+
</svelte:element>
|
|
261
|
+
</symbiote-view>
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
// (CT.WithDefault<boolean, 'true'>) - no ios/android divergence in v1 scope, so a single
|
|
6
6
|
// constant stands in for the per-platform injection point ISliderPlatform-style adapters use
|
|
7
7
|
// elsewhere.
|
|
8
|
-
const NAVIGATOR_PLATFORM: INavigatorPlatform = {
|
|
8
|
+
const NAVIGATOR_PLATFORM: INavigatorPlatform = {
|
|
9
|
+
defaultHeaderBackTitleVisible: true,
|
|
10
|
+
};
|
|
9
11
|
|
|
10
12
|
// react-native-screens' RNSScreenStackHeaderConfig.mm requires every header child to be an
|
|
11
13
|
// RNSScreenStackHeaderSubview; `type: 'searchBar'` is how it knows which slot this one fills.
|
|
@@ -24,9 +26,9 @@
|
|
|
24
26
|
// compiles through Svelte's generic setAttribute path and never the custom-element property-SET
|
|
25
27
|
// path the object bag depends on - see ../attachments.ts for the full reasoning.
|
|
26
28
|
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
// of a react-native-screens view.
|
|
29
|
+
// Whitespace between sibling tags in the per-route tree is inert: the shim drops a
|
|
30
|
+
// whitespace-only text node whose parent takes no raw text, so it never becomes an RCTRawText
|
|
31
|
+
// child of a react-native-screens view (dom-shim/text.ts, svelte-adapter-dom-shim skill §16b).
|
|
30
32
|
import { Platform, dlog } from '@symbiote-native/engine';
|
|
31
33
|
import {
|
|
32
34
|
NAVIGATION_EVENT_BLUR,
|
|
@@ -86,13 +88,19 @@
|
|
|
86
88
|
[SCREEN_ON_WILL_APPEAR]: () =>
|
|
87
89
|
dlog(`Stack: route "${route.name}" will appear at t=${Date.now()}`),
|
|
88
90
|
[SCREEN_ON_APPEAR]: () => {
|
|
89
|
-
dlog(
|
|
91
|
+
dlog(
|
|
92
|
+
`Stack: route "${route.name}" appeared (focus) at t=${Date.now()}`,
|
|
93
|
+
);
|
|
90
94
|
emitter.emit(NAVIGATION_EVENT_FOCUS);
|
|
91
95
|
},
|
|
92
96
|
[SCREEN_ON_WILL_DISAPPEAR]: () =>
|
|
93
|
-
dlog(
|
|
97
|
+
dlog(
|
|
98
|
+
`Stack: route "${route.name}" will disappear at t=${Date.now()}`,
|
|
99
|
+
),
|
|
94
100
|
[SCREEN_ON_DISAPPEAR]: () => {
|
|
95
|
-
dlog(
|
|
101
|
+
dlog(
|
|
102
|
+
`Stack: route "${route.name}" disappeared (blur) at t=${Date.now()}`,
|
|
103
|
+
);
|
|
96
104
|
emitter.emit(NAVIGATION_EVENT_BLUR);
|
|
97
105
|
},
|
|
98
106
|
},
|
|
@@ -131,7 +139,9 @@
|
|
|
131
139
|
// controller to attach to, so the header silently never renders. activityState mirrors the
|
|
132
140
|
// outer screen's own value - RNSScreen.mm treats an unset/inactive nested screen as not yet
|
|
133
141
|
// pushed, leaving it parked at its pre-push transition position.
|
|
134
|
-
const innerStackProps = $derived<Record<string, unknown>>({
|
|
142
|
+
const innerStackProps = $derived<Record<string, unknown>>({
|
|
143
|
+
style: plan.innerStackStyle,
|
|
144
|
+
});
|
|
135
145
|
const innerScreenProps = $derived<Record<string, unknown>>({
|
|
136
146
|
style: plan.innerScreenStyle,
|
|
137
147
|
activityState: plan.activityState,
|
|
@@ -145,4 +155,51 @@
|
|
|
145
155
|
});
|
|
146
156
|
</script>
|
|
147
157
|
|
|
148
|
-
{#snippet chrome()}
|
|
158
|
+
{#snippet chrome()}
|
|
159
|
+
<svelte:element
|
|
160
|
+
this={RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME}
|
|
161
|
+
{@attach hostProps(plan.headerConfig.props)}
|
|
162
|
+
>
|
|
163
|
+
{#if plan.searchBarProps !== undefined}
|
|
164
|
+
<svelte:element
|
|
165
|
+
this={RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME}
|
|
166
|
+
{@attach hostProps(HEADER_SUBVIEW_PROPS)}
|
|
167
|
+
>
|
|
168
|
+
<svelte:element
|
|
169
|
+
this={RNS_SEARCH_BAR_VIEW_NAME}
|
|
170
|
+
{@attach hostProps(plan.searchBarProps)}
|
|
171
|
+
{@attach searchBarRef(searchBarOptions?.ref)}
|
|
172
|
+
/>
|
|
173
|
+
</svelte:element>
|
|
174
|
+
{/if}
|
|
175
|
+
</svelte:element>
|
|
176
|
+
<svelte:element
|
|
177
|
+
this={RNS_SCREEN_CONTENT_WRAPPER_VIEW_NAME}
|
|
178
|
+
{@attach hostProps(plan.contentWrapperProps)}
|
|
179
|
+
>
|
|
180
|
+
<NavigationScope value={scopeValue}>
|
|
181
|
+
<ScreenComponent />
|
|
182
|
+
</NavigationScope>
|
|
183
|
+
</svelte:element>
|
|
184
|
+
{/snippet}
|
|
185
|
+
|
|
186
|
+
<svelte:element
|
|
187
|
+
this={plan.screenViewName}
|
|
188
|
+
{@attach hostProps(plan.screenProps)}
|
|
189
|
+
>
|
|
190
|
+
{#if plan.inModal}
|
|
191
|
+
<svelte:element
|
|
192
|
+
this={RNS_SCREEN_STACK_VIEW_NAME}
|
|
193
|
+
{@attach hostProps(innerStackProps)}
|
|
194
|
+
>
|
|
195
|
+
<svelte:element
|
|
196
|
+
this={RNS_SCREEN_VIEW_NAME}
|
|
197
|
+
{@attach hostProps(innerScreenProps)}
|
|
198
|
+
>
|
|
199
|
+
{@render chrome()}
|
|
200
|
+
</svelte:element>
|
|
201
|
+
</svelte:element>
|
|
202
|
+
{:else}
|
|
203
|
+
{@render chrome()}
|
|
204
|
+
{/if}
|
|
205
|
+
</svelte:element>
|
|
@@ -48,7 +48,11 @@
|
|
|
48
48
|
import type { INavigationScopeValue } from '../navigation-context';
|
|
49
49
|
import NavigationScope from '../navigation-scope.svelte';
|
|
50
50
|
import { SCREEN_REGISTRY_HOST_PROPS } from '../registry-host';
|
|
51
|
-
import {
|
|
51
|
+
import {
|
|
52
|
+
setScreenCollector,
|
|
53
|
+
toRegistry,
|
|
54
|
+
withoutScreen,
|
|
55
|
+
} from '../screen-registry';
|
|
52
56
|
import type { IRegisteredScreen } from '../screen-registry';
|
|
53
57
|
import type { ITabScreenProps } from '../tab-screen-props';
|
|
54
58
|
import type { ITabProps } from './tab-props';
|
|
@@ -94,7 +98,8 @@
|
|
|
94
98
|
let dispatchedState = $state.raw<ITabRouterState | null>(null);
|
|
95
99
|
|
|
96
100
|
const state = $derived.by<ITabRouterState>(() => {
|
|
97
|
-
if (registeredRoutes.length === 0)
|
|
101
|
+
if (registeredRoutes.length === 0)
|
|
102
|
+
dlog('Tab: no <Tab.Screen> children registered');
|
|
98
103
|
const dispatched = dispatchedState;
|
|
99
104
|
return dispatched === null
|
|
100
105
|
? createInitialTabState(registeredRoutes, initialRouteName)
|
|
@@ -207,29 +212,33 @@
|
|
|
207
212
|
);
|
|
208
213
|
|
|
209
214
|
const tabBar = $derived.by<IDescriptor>(() =>
|
|
210
|
-
renderTabBar({
|
|
215
|
+
renderTabBar({
|
|
216
|
+
items,
|
|
217
|
+
style: focusedOptions?.tabBarStyle,
|
|
218
|
+
passthrough: {},
|
|
219
|
+
}),
|
|
211
220
|
);
|
|
212
221
|
|
|
213
222
|
// Only the focused route's screen is ever mounted (unlike Stack, which keeps every pushed route
|
|
214
223
|
// alive), so a fresh NavigationScope per focus change is sufficient - the previous screen's
|
|
215
224
|
// whole subtree (and any listeners it registered) is torn down by an ordinary unmount when
|
|
216
225
|
// focus moves on.
|
|
217
|
-
const focusedScreen = $derived.by<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
);
|
|
226
|
+
const focusedScreen = $derived.by<
|
|
227
|
+
{ scope: INavigationScopeValue; component: Component } | undefined
|
|
228
|
+
>(() => {
|
|
229
|
+
if (focusedRoute === undefined) return undefined;
|
|
230
|
+
const entry = registry.get(focusedRoute.name);
|
|
231
|
+
if (entry === undefined) return undefined;
|
|
232
|
+
return {
|
|
233
|
+
component: entry.component,
|
|
234
|
+
scope: {
|
|
235
|
+
route: focusedRoute,
|
|
236
|
+
navigation: handle,
|
|
237
|
+
emitter: emitterFor(focusedRoute.key),
|
|
238
|
+
parent: parentScope?.current,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
});
|
|
233
242
|
|
|
234
243
|
// The bar's ROOT stays a literal template tag (so `bind:this` has a statically known tag) and
|
|
235
244
|
// only its children go through the Descriptor bridge - the uniform shape every Svelte component
|
|
@@ -244,4 +253,17 @@
|
|
|
244
253
|
});
|
|
245
254
|
</script>
|
|
246
255
|
|
|
247
|
-
<symbiote-view p={TAB_ROOT_PROPS}
|
|
256
|
+
<symbiote-view p={TAB_ROOT_PROPS}>
|
|
257
|
+
<symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
|
|
258
|
+
{@render children?.()}
|
|
259
|
+
</symbiote-text>
|
|
260
|
+
<symbiote-view p={TAB_CONTENT_PROPS}>
|
|
261
|
+
{#if focusedScreen !== undefined}
|
|
262
|
+
{@const FocusedComponent = focusedScreen.component}
|
|
263
|
+
<NavigationScope value={focusedScreen.scope}>
|
|
264
|
+
<FocusedComponent />
|
|
265
|
+
</NavigationScope>
|
|
266
|
+
{/if}
|
|
267
|
+
</symbiote-view>
|
|
268
|
+
<symbiote-view p={tabBar.props} bind:this={tabBarHost} />
|
|
269
|
+
</symbiote-view>
|