@ankhorage/contracts 11.1.0 → 12.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +1 -1
- package/dist/appManifest/navigator.d.ts +2 -1
- package/dist/appManifest/navigator.d.ts.map +1 -1
- package/dist/appManifest/navigator.js +11 -11
- package/dist/appManifest/navigator.js.map +1 -1
- package/dist/appManifest/navigatorOptions.d.ts.map +1 -1
- package/dist/appManifest/navigatorOptions.js +27 -29
- package/dist/appManifest/navigatorOptions.js.map +1 -1
- package/dist/navigator/catalog.d.ts +42 -0
- package/dist/navigator/catalog.d.ts.map +1 -0
- package/dist/navigator/catalog.js +2 -0
- package/dist/navigator/catalog.js.map +1 -0
- package/dist/navigator/generation.d.ts +14 -4
- package/dist/navigator/generation.d.ts.map +1 -1
- package/dist/navigator/generation.js.map +1 -1
- package/dist/navigator/planning.d.ts +9 -9
- package/dist/navigator/planning.d.ts.map +1 -1
- package/dist/navigator/planning.js.map +1 -1
- package/dist/navigator.d.ts +21 -24
- package/dist/navigator.d.ts.map +1 -1
- package/dist/navigator.js +10 -9
- package/dist/navigator.js.map +1 -1
- package/package.json +2 -2
- package/src/appManifest/navigator.ts +15 -17
- package/src/appManifest/navigatorOptions.ts +29 -31
- package/src/navigator/catalog.ts +79 -0
- package/src/navigator/generation.ts +22 -4
- package/src/navigator/planning.ts +10 -9
- package/src/navigator-runtime-contracts.test.ts +54 -3
- package/src/navigator-validation.test.ts +31 -4
- package/src/navigator.test.ts +49 -17
- package/src/navigator.ts +41 -30
|
@@ -7,13 +7,14 @@ import type {
|
|
|
7
7
|
StackScreenOptions,
|
|
8
8
|
} from '../navigator';
|
|
9
9
|
import type { CustomNavigatorRegistry } from './extensions';
|
|
10
|
+
import type { NavigatorDependencyRequirement } from './generation';
|
|
10
11
|
|
|
11
|
-
export interface
|
|
12
|
+
export interface ResolvedHeadlessTabsPresentation {
|
|
12
13
|
presentation: ResolvedTabsPresentation;
|
|
13
14
|
customPresentationId?: string;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
export type ResolvedTabsImplementation = '
|
|
17
|
+
export type ResolvedTabsImplementation = 'headless' | 'javascript' | 'native';
|
|
17
18
|
|
|
18
19
|
export type ResolvedTabsPresentation = 'bottom' | 'top' | 'rail' | 'sidebar' | 'custom';
|
|
19
20
|
|
|
@@ -60,7 +61,7 @@ export type NavigatorAdapterId =
|
|
|
60
61
|
| 'drawer'
|
|
61
62
|
| 'tabs.native'
|
|
62
63
|
| 'tabs.javascript'
|
|
63
|
-
| 'tabs.
|
|
64
|
+
| 'tabs.headless'
|
|
64
65
|
| 'split-view'
|
|
65
66
|
| 'custom';
|
|
66
67
|
|
|
@@ -76,6 +77,8 @@ export interface NavigatorAdapterPlan {
|
|
|
76
77
|
|
|
77
78
|
export type NavigatorApiStability = 'stable' | 'alpha';
|
|
78
79
|
|
|
80
|
+
export type NavigatorCapabilityId = string;
|
|
81
|
+
|
|
79
82
|
export interface NavigatorDiagnostic {
|
|
80
83
|
code: string;
|
|
81
84
|
severity: 'error' | 'warning';
|
|
@@ -115,11 +118,9 @@ export interface NavigatorPlan {
|
|
|
115
118
|
context: NavigatorValidationContext;
|
|
116
119
|
root: NavigatorNodePlan;
|
|
117
120
|
diagnostics: readonly NavigatorDiagnostic[];
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
authentication: boolean;
|
|
122
|
-
};
|
|
121
|
+
support: NavigatorSupportStatus;
|
|
122
|
+
capabilityIds: readonly NavigatorCapabilityId[];
|
|
123
|
+
dependencies: readonly NavigatorDependencyRequirement[];
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
export type NavigatorResponsiveSize = 'compact' | 'medium' | 'expanded';
|
|
@@ -138,7 +139,7 @@ export interface NavigatorRoutePlan {
|
|
|
138
139
|
|
|
139
140
|
export type NavigatorRuntimePlatform = 'android' | 'ios' | 'web';
|
|
140
141
|
|
|
141
|
-
export type NavigatorSupportStatus = 'supported' | '
|
|
142
|
+
export type NavigatorSupportStatus = 'supported' | 'testing-only' | 'unsupported';
|
|
142
143
|
|
|
143
144
|
export interface NavigatorValidationContext {
|
|
144
145
|
platform: NavigatorRuntimePlatform;
|
|
@@ -2,8 +2,10 @@ import { expect, test } from 'bun:test';
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
CustomNavigatorRegistration,
|
|
5
|
+
NavigatorCatalog,
|
|
5
6
|
NavigatorGeneratedFile,
|
|
6
7
|
NavigatorGenerationBindings,
|
|
8
|
+
NavigatorGenerationResult,
|
|
7
9
|
NavigatorPlan,
|
|
8
10
|
} from './navigator';
|
|
9
11
|
|
|
@@ -32,10 +34,59 @@ test('keeps generation bindings and plan output portable across package boundari
|
|
|
32
34
|
routes: [],
|
|
33
35
|
},
|
|
34
36
|
diagnostics: [],
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
support: 'supported',
|
|
38
|
+
capabilityIds: ['slot'],
|
|
39
|
+
dependencies: [],
|
|
37
40
|
};
|
|
38
|
-
|
|
41
|
+
const result: NavigatorGenerationResult = {
|
|
42
|
+
support: plan.support,
|
|
43
|
+
capabilityIds: plan.capabilityIds,
|
|
44
|
+
dependencies: plan.dependencies,
|
|
45
|
+
diagnostics: plan.diagnostics,
|
|
46
|
+
plan,
|
|
47
|
+
files: [file],
|
|
48
|
+
};
|
|
49
|
+
expect(JSON.parse(JSON.stringify({ bindings, result }))).toEqual({ bindings, result });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('separates capability taxonomy, target support, stability, and verification', () => {
|
|
53
|
+
const catalog: NavigatorCatalog = {
|
|
54
|
+
capabilities: [
|
|
55
|
+
{
|
|
56
|
+
id: 'tabs.headless.sidebar',
|
|
57
|
+
topology: 'tabs',
|
|
58
|
+
implementation: 'headless',
|
|
59
|
+
presentation: 'sidebar',
|
|
60
|
+
stability: 'stable',
|
|
61
|
+
targets: [
|
|
62
|
+
{
|
|
63
|
+
platform: 'web',
|
|
64
|
+
support: 'supported',
|
|
65
|
+
verification: [{ kind: 'browser', status: 'verified' }],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
platform: 'ios',
|
|
69
|
+
support: 'testing-only',
|
|
70
|
+
verification: [{ kind: 'device', status: 'unverified' }],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
dependencies: [],
|
|
74
|
+
requirements: [],
|
|
75
|
+
incompatibilities: [],
|
|
76
|
+
limitations: [],
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
presets: [
|
|
80
|
+
{
|
|
81
|
+
id: 'drawer',
|
|
82
|
+
description: 'Drawer as the root navigator with direct routes.',
|
|
83
|
+
topology: ['drawer'],
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
expect(catalog.capabilities[0]?.targets[1]?.support).toBe('testing-only');
|
|
89
|
+
expect(catalog.presets[0]?.topology).toEqual(['drawer']);
|
|
39
90
|
});
|
|
40
91
|
|
|
41
92
|
test('describes a custom extension without importing Navigator or a UI runtime', () => {
|
|
@@ -6,7 +6,7 @@ import { describe, expect, it } from 'bun:test';
|
|
|
6
6
|
import { isAppNavigatorManifest } from './appManifest/screens';
|
|
7
7
|
import type {
|
|
8
8
|
CustomNavigatorNode,
|
|
9
|
-
|
|
9
|
+
HeadlessTabsConfig,
|
|
10
10
|
NavigatorNode,
|
|
11
11
|
StackImplementationConfig,
|
|
12
12
|
} from './navigator';
|
|
@@ -20,9 +20,9 @@ describe('app navigator manifest type discrimination', () => {
|
|
|
20
20
|
implementation: 'experimental',
|
|
21
21
|
options: { presentation: 'modal' },
|
|
22
22
|
};
|
|
23
|
-
// @ts-expect-error Fixed
|
|
24
|
-
const tabs:
|
|
25
|
-
implementation: '
|
|
23
|
+
// @ts-expect-error Fixed headless tabs do not accept a registered custom presentation id.
|
|
24
|
+
const tabs: HeadlessTabsConfig = {
|
|
25
|
+
implementation: 'headless',
|
|
26
26
|
presentation: 'sidebar',
|
|
27
27
|
customPresentationId: 'workspace-tabs',
|
|
28
28
|
};
|
|
@@ -70,6 +70,33 @@ describe('app navigator manifest stack validation', () => {
|
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
describe('app navigator manifest removed fields', () => {
|
|
74
|
+
it('rejects flow metadata and the superseded custom Tabs implementation', () => {
|
|
75
|
+
expect(
|
|
76
|
+
isAppNavigatorManifest({
|
|
77
|
+
type: 'stack',
|
|
78
|
+
flows: { onboarding: true },
|
|
79
|
+
routes: [],
|
|
80
|
+
}),
|
|
81
|
+
).toBe(false);
|
|
82
|
+
expect(
|
|
83
|
+
isAppNavigatorManifest({
|
|
84
|
+
type: 'tabs',
|
|
85
|
+
implementation: 'custom',
|
|
86
|
+
presentation: 'bottom',
|
|
87
|
+
routes: [],
|
|
88
|
+
}),
|
|
89
|
+
).toBe(false);
|
|
90
|
+
expect(
|
|
91
|
+
isAppNavigatorManifest({
|
|
92
|
+
type: 'stack',
|
|
93
|
+
preset: 'root-stack-tabs',
|
|
94
|
+
routes: [],
|
|
95
|
+
}),
|
|
96
|
+
).toBe(false);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
73
100
|
describe('app navigator manifest sheet validation', () => {
|
|
74
101
|
it('validates native form-sheet detents and their presentation discriminant', () => {
|
|
75
102
|
for (const sheetAllowedDetents of [[], [0.8, 0.4], [0.4, 0.4], [0], [1.1], [Number.NaN]]) {
|
package/src/navigator.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { describe, expect, it } from 'bun:test';
|
|
2
2
|
|
|
3
|
-
import { isAppNavigatorManifest } from './appManifest/screens';
|
|
4
3
|
import {
|
|
5
4
|
type AppNavigatorManifest,
|
|
5
|
+
isAppNavigatorManifest,
|
|
6
6
|
NAVIGATOR_PRESETS,
|
|
7
7
|
NAVIGATOR_TYPES,
|
|
8
8
|
type NavigatorNode,
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
type TabsNavigatorConfig,
|
|
11
11
|
} from './navigator';
|
|
12
12
|
|
|
13
|
+
function parseNavigator(value: unknown): AppNavigatorManifest {
|
|
14
|
+
if (!isAppNavigatorManifest(value)) throw new Error('Expected a navigator manifest.');
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
function createAdaptiveTabs(): AppNavigatorManifest {
|
|
14
19
|
return {
|
|
15
20
|
type: 'tabs',
|
|
@@ -23,7 +28,6 @@ function createAdaptiveTabs(): AppNavigatorManifest {
|
|
|
23
28
|
expanded: 'sidebar',
|
|
24
29
|
},
|
|
25
30
|
},
|
|
26
|
-
flows: { onboarding: true },
|
|
27
31
|
routes: [{ name: 'home', path: '/', screenId: 'home' }],
|
|
28
32
|
};
|
|
29
33
|
}
|
|
@@ -82,14 +86,33 @@ const VALID_NAVIGATOR_NODES = [
|
|
|
82
86
|
},
|
|
83
87
|
] as const satisfies readonly NavigatorNode[];
|
|
84
88
|
|
|
89
|
+
it('narrows unknown input through the public navigator boundary', () => {
|
|
90
|
+
const manifest = parseNavigator({ type: 'drawer', routes: [] });
|
|
91
|
+
|
|
92
|
+
expect(manifest.type).toBe('drawer');
|
|
93
|
+
});
|
|
94
|
+
|
|
85
95
|
describe('app navigator manifest topology', () => {
|
|
86
96
|
it('keeps canonical topology presets finite and authorable', () => {
|
|
87
97
|
expect(NAVIGATOR_TYPES).toEqual(['slot', 'stack', 'tabs', 'drawer', 'split-view', 'custom']);
|
|
88
|
-
expect(NAVIGATOR_PRESETS).
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
expect(NAVIGATOR_PRESETS).toEqual([
|
|
99
|
+
'slot',
|
|
100
|
+
'stack',
|
|
101
|
+
'tabs',
|
|
102
|
+
'tabs-stack',
|
|
103
|
+
'stack-tabs',
|
|
104
|
+
'stack-tabs-stack',
|
|
105
|
+
'drawer',
|
|
106
|
+
'drawer-stack',
|
|
107
|
+
'stack-drawer',
|
|
108
|
+
'stack-drawer-stack',
|
|
109
|
+
'drawer-tabs',
|
|
110
|
+
'drawer-tabs-stack',
|
|
111
|
+
'stack-drawer-tabs',
|
|
112
|
+
'stack-drawer-tabs-stack',
|
|
113
|
+
'split-view',
|
|
114
|
+
'custom',
|
|
115
|
+
]);
|
|
93
116
|
});
|
|
94
117
|
|
|
95
118
|
it('accepts adaptive native/Web tabs with responsive custom presentation', () => {
|
|
@@ -152,12 +175,12 @@ describe('app navigator manifest node variants', () => {
|
|
|
152
175
|
});
|
|
153
176
|
});
|
|
154
177
|
|
|
155
|
-
describe('app navigator manifest
|
|
178
|
+
describe('app navigator manifest headless presentation', () => {
|
|
156
179
|
it('accepts fixed and registered custom Web presentations', () => {
|
|
157
180
|
expect(
|
|
158
181
|
isAppNavigatorManifest({
|
|
159
182
|
type: 'tabs',
|
|
160
|
-
implementation: '
|
|
183
|
+
implementation: 'headless',
|
|
161
184
|
presentation: 'sidebar',
|
|
162
185
|
routes: [],
|
|
163
186
|
}),
|
|
@@ -166,7 +189,7 @@ describe('app navigator manifest custom presentation', () => {
|
|
|
166
189
|
expect(
|
|
167
190
|
isAppNavigatorManifest({
|
|
168
191
|
type: 'tabs',
|
|
169
|
-
implementation: '
|
|
192
|
+
implementation: 'headless',
|
|
170
193
|
presentation: 'custom',
|
|
171
194
|
customPresentationId: 'workspace-tabs',
|
|
172
195
|
routes: [],
|
|
@@ -178,7 +201,7 @@ describe('app navigator manifest custom presentation', () => {
|
|
|
178
201
|
expect(
|
|
179
202
|
isAppNavigatorManifest({
|
|
180
203
|
type: 'tabs',
|
|
181
|
-
implementation: '
|
|
204
|
+
implementation: 'headless',
|
|
182
205
|
presentation: 'responsive',
|
|
183
206
|
routes: [],
|
|
184
207
|
}),
|
|
@@ -187,7 +210,7 @@ describe('app navigator manifest custom presentation', () => {
|
|
|
187
210
|
expect(
|
|
188
211
|
isAppNavigatorManifest({
|
|
189
212
|
type: 'tabs',
|
|
190
|
-
implementation: '
|
|
213
|
+
implementation: 'headless',
|
|
191
214
|
presentation: 'custom',
|
|
192
215
|
routes: [],
|
|
193
216
|
}),
|
|
@@ -219,7 +242,7 @@ describe('app navigator manifest tabs branch validation', () => {
|
|
|
219
242
|
expect(
|
|
220
243
|
isAppNavigatorManifest({
|
|
221
244
|
type: 'tabs',
|
|
222
|
-
implementation: '
|
|
245
|
+
implementation: 'headless',
|
|
223
246
|
presentation: 'sidebar',
|
|
224
247
|
customPresentationId: 'must-not-apply',
|
|
225
248
|
routes: [],
|
|
@@ -229,7 +252,7 @@ describe('app navigator manifest tabs branch validation', () => {
|
|
|
229
252
|
expect(
|
|
230
253
|
isAppNavigatorManifest({
|
|
231
254
|
type: 'tabs',
|
|
232
|
-
implementation: '
|
|
255
|
+
implementation: 'headless',
|
|
233
256
|
presentation: 'custom',
|
|
234
257
|
customPresentationId: 'workspace-tabs',
|
|
235
258
|
responsive: { compact: 'bottom', expanded: 'sidebar' },
|
|
@@ -240,14 +263,21 @@ describe('app navigator manifest tabs branch validation', () => {
|
|
|
240
263
|
});
|
|
241
264
|
|
|
242
265
|
describe('app navigator manifest composition', () => {
|
|
243
|
-
it('
|
|
266
|
+
it('expresses app-owned sequences as ordinary guarded navigator branches', () => {
|
|
244
267
|
expect(
|
|
245
268
|
isAppNavigatorManifest({
|
|
246
269
|
type: 'stack',
|
|
247
|
-
flows: { authentication: true },
|
|
248
270
|
routes: [
|
|
249
271
|
{
|
|
250
|
-
name: '
|
|
272
|
+
name: 'entry',
|
|
273
|
+
navigator: {
|
|
274
|
+
type: 'stack',
|
|
275
|
+
routes: [{ name: 'step', screenId: 'step' }],
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: 'main',
|
|
280
|
+
guards: ['entry-complete'],
|
|
251
281
|
navigator: {
|
|
252
282
|
type: 'tabs',
|
|
253
283
|
routes: [{ name: 'home', screenId: 'home' }],
|
|
@@ -257,7 +287,9 @@ describe('app navigator manifest composition', () => {
|
|
|
257
287
|
}),
|
|
258
288
|
).toBe(true);
|
|
259
289
|
});
|
|
290
|
+
});
|
|
260
291
|
|
|
292
|
+
describe('app navigator manifest route metadata', () => {
|
|
261
293
|
it('preserves authored route names, labels, paths, guards, and visibility without inference', () => {
|
|
262
294
|
const navigator = {
|
|
263
295
|
type: 'stack',
|
package/src/navigator.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { IconSpec, ManifestValue } from './types';
|
|
2
2
|
|
|
3
|
+
export { isAppNavigatorManifest } from './appManifest/navigator';
|
|
4
|
+
|
|
3
5
|
export const NAVIGATOR_TYPES = ['slot', 'stack', 'tabs', 'drawer', 'split-view', 'custom'] as const;
|
|
4
6
|
export type NavigatorType = (typeof NAVIGATOR_TYPES)[number];
|
|
5
7
|
|
|
@@ -8,16 +10,16 @@ export const NAVIGATOR_PRESETS = [
|
|
|
8
10
|
'stack',
|
|
9
11
|
'tabs',
|
|
10
12
|
'tabs-stack',
|
|
13
|
+
'stack-tabs',
|
|
14
|
+
'stack-tabs-stack',
|
|
11
15
|
'drawer',
|
|
12
16
|
'drawer-stack',
|
|
17
|
+
'stack-drawer',
|
|
18
|
+
'stack-drawer-stack',
|
|
13
19
|
'drawer-tabs',
|
|
14
20
|
'drawer-tabs-stack',
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'root-stack-drawer',
|
|
18
|
-
'root-stack-drawer-stack',
|
|
19
|
-
'root-stack-drawer-tabs',
|
|
20
|
-
'root-stack-drawer-tabs-stack',
|
|
21
|
+
'stack-drawer-tabs',
|
|
22
|
+
'stack-drawer-tabs-stack',
|
|
21
23
|
'split-view',
|
|
22
24
|
'custom',
|
|
23
25
|
] as const;
|
|
@@ -94,15 +96,15 @@ export interface DrawerNavigatorOptions {
|
|
|
94
96
|
headerShown?: boolean;
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
export const
|
|
98
|
-
export type
|
|
99
|
+
export const FIXED_HEADLESS_TABS_PRESENTATIONS = ['bottom', 'top', 'rail', 'sidebar'] as const;
|
|
100
|
+
export type FixedHeadlessTabsPresentation = (typeof FIXED_HEADLESS_TABS_PRESENTATIONS)[number];
|
|
99
101
|
|
|
100
|
-
export const
|
|
101
|
-
...
|
|
102
|
+
export const HEADLESS_TABS_PRESENTATIONS = [
|
|
103
|
+
...FIXED_HEADLESS_TABS_PRESENTATIONS,
|
|
102
104
|
'responsive',
|
|
103
105
|
'custom',
|
|
104
106
|
] as const;
|
|
105
|
-
export type
|
|
107
|
+
export type HeadlessTabsPresentation = (typeof HEADLESS_TABS_PRESENTATIONS)[number];
|
|
106
108
|
|
|
107
109
|
export const JAVASCRIPT_TABS_PRESENTATIONS = ['bottom', 'top'] as const;
|
|
108
110
|
export type JavaScriptTabsPresentation = (typeof JAVASCRIPT_TABS_PRESENTATIONS)[number];
|
|
@@ -116,14 +118,14 @@ export const NATIVE_TABS_MINIMIZE_BEHAVIORS = [
|
|
|
116
118
|
export type NativeTabsMinimizeBehavior = (typeof NATIVE_TABS_MINIMIZE_BEHAVIORS)[number];
|
|
117
119
|
|
|
118
120
|
export interface ResponsiveTabsPresentation {
|
|
119
|
-
compact:
|
|
120
|
-
medium?:
|
|
121
|
-
expanded:
|
|
121
|
+
compact: FixedHeadlessTabsPresentation;
|
|
122
|
+
medium?: FixedHeadlessTabsPresentation;
|
|
123
|
+
expanded: FixedHeadlessTabsPresentation;
|
|
122
124
|
}
|
|
123
125
|
|
|
124
|
-
export type
|
|
126
|
+
export type HeadlessTabsPresentationConfig =
|
|
125
127
|
| {
|
|
126
|
-
presentation:
|
|
128
|
+
presentation: FixedHeadlessTabsPresentation;
|
|
127
129
|
responsive?: never;
|
|
128
130
|
customPresentationId?: never;
|
|
129
131
|
}
|
|
@@ -139,11 +141,11 @@ export type CustomTabsPresentationConfig =
|
|
|
139
141
|
customPresentationId: string;
|
|
140
142
|
};
|
|
141
143
|
|
|
142
|
-
export type
|
|
143
|
-
implementation: '
|
|
144
|
-
} &
|
|
144
|
+
export type HeadlessTabsConfig = {
|
|
145
|
+
implementation: 'headless';
|
|
146
|
+
} & HeadlessTabsPresentationConfig;
|
|
145
147
|
|
|
146
|
-
export type
|
|
148
|
+
export type HeadlessTabsWebConfig = HeadlessTabsPresentationConfig;
|
|
147
149
|
|
|
148
150
|
export interface NavigatorScreenReference {
|
|
149
151
|
screenId: string;
|
|
@@ -167,12 +169,12 @@ export interface AdaptiveTabsConfig {
|
|
|
167
169
|
implementation?: 'adaptive';
|
|
168
170
|
/** Android/iOS branch. Expo Router may expose this implementation as unstable. */
|
|
169
171
|
native?: NativeTabsConfig;
|
|
170
|
-
/** Web branch rendered through headless
|
|
171
|
-
web?:
|
|
172
|
+
/** Web branch rendered through headless tabs. */
|
|
173
|
+
web?: HeadlessTabsWebConfig;
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
export type TabsImplementationConfig =
|
|
175
|
-
AdaptiveTabsConfig |
|
|
177
|
+
AdaptiveTabsConfig | HeadlessTabsConfig | JavaScriptTabsConfig | NativeTabsConfig;
|
|
176
178
|
|
|
177
179
|
interface NavigatorNodeBase {
|
|
178
180
|
initialRouteName?: string;
|
|
@@ -237,11 +239,6 @@ export interface RouteDefinition {
|
|
|
237
239
|
navigator?: NavigatorNode;
|
|
238
240
|
}
|
|
239
241
|
|
|
240
|
-
export interface NavigatorFlows {
|
|
241
|
-
onboarding?: boolean;
|
|
242
|
-
authentication?: boolean;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
242
|
export interface NavigatorDefaults {
|
|
246
243
|
tabs?: TabsImplementationConfig;
|
|
247
244
|
stack?: StackImplementationConfig;
|
|
@@ -266,20 +263,33 @@ export interface NavigatorPlatforms {
|
|
|
266
263
|
*/
|
|
267
264
|
export type AppNavigatorManifest = NavigatorNode & {
|
|
268
265
|
preset?: NavigatorPreset;
|
|
269
|
-
flows?: NavigatorFlows;
|
|
270
266
|
defaults?: NavigatorDefaults;
|
|
271
267
|
platforms?: NavigatorPlatforms;
|
|
272
268
|
};
|
|
273
269
|
|
|
270
|
+
export type {
|
|
271
|
+
NavigatorCapabilityDescriptor,
|
|
272
|
+
NavigatorCapabilityRequirement,
|
|
273
|
+
NavigatorCapabilityTarget,
|
|
274
|
+
NavigatorCapabilityVerification,
|
|
275
|
+
NavigatorCatalog,
|
|
276
|
+
NavigatorImplementation,
|
|
277
|
+
NavigatorPresentation,
|
|
278
|
+
NavigatorPresetDescriptor,
|
|
279
|
+
NavigatorVerificationKind,
|
|
280
|
+
NavigatorVerificationStatus,
|
|
281
|
+
} from './navigator/catalog';
|
|
274
282
|
export type {
|
|
275
283
|
CustomNavigatorConfigIssue,
|
|
276
284
|
CustomNavigatorRegistration,
|
|
277
285
|
CustomNavigatorRegistry,
|
|
278
286
|
} from './navigator/extensions';
|
|
279
287
|
export type {
|
|
288
|
+
NavigatorDependencyRequirement,
|
|
280
289
|
NavigatorGeneratedFile,
|
|
281
290
|
NavigatorGenerationBindings,
|
|
282
291
|
NavigatorGenerationOptions,
|
|
292
|
+
NavigatorGenerationResult,
|
|
283
293
|
NavigatorScreenModule,
|
|
284
294
|
} from './navigator/generation';
|
|
285
295
|
export type {
|
|
@@ -288,6 +298,7 @@ export type {
|
|
|
288
298
|
NavigatorAdapterId,
|
|
289
299
|
NavigatorAdapterPlan,
|
|
290
300
|
NavigatorApiStability,
|
|
301
|
+
NavigatorCapabilityId,
|
|
291
302
|
NavigatorDiagnostic,
|
|
292
303
|
NavigatorNodePlan,
|
|
293
304
|
NavigatorPlan,
|
|
@@ -296,7 +307,7 @@ export type {
|
|
|
296
307
|
NavigatorRuntimePlatform,
|
|
297
308
|
NavigatorSupportStatus,
|
|
298
309
|
NavigatorValidationContext,
|
|
299
|
-
|
|
310
|
+
ResolvedHeadlessTabsPresentation,
|
|
300
311
|
ResolvedTabsImplementation,
|
|
301
312
|
ResolvedTabsPresentation,
|
|
302
313
|
TabsNavigatorPlan,
|