@ankhorage/contracts 10.0.0 → 11.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +1 -1
  3. package/dist/appManifest/icon.d.ts +3 -0
  4. package/dist/appManifest/icon.d.ts.map +1 -0
  5. package/dist/appManifest/icon.js +20 -0
  6. package/dist/appManifest/icon.js.map +1 -0
  7. package/dist/appManifest/infra.d.ts.map +1 -1
  8. package/dist/appManifest/infra.js +1 -9
  9. package/dist/appManifest/infra.js.map +1 -1
  10. package/dist/appManifest/navigator.d.ts +3 -0
  11. package/dist/appManifest/navigator.d.ts.map +1 -0
  12. package/dist/appManifest/navigator.js +142 -0
  13. package/dist/appManifest/navigator.js.map +1 -0
  14. package/dist/appManifest/navigatorOptions.d.ts +13 -0
  15. package/dist/appManifest/navigatorOptions.d.ts.map +1 -0
  16. package/dist/appManifest/navigatorOptions.js +226 -0
  17. package/dist/appManifest/navigatorOptions.js.map +1 -0
  18. package/dist/appManifest/screens.d.ts +1 -2
  19. package/dist/appManifest/screens.d.ts.map +1 -1
  20. package/dist/appManifest/screens.js +2 -124
  21. package/dist/appManifest/screens.js.map +1 -1
  22. package/dist/navigator.d.ts +101 -14
  23. package/dist/navigator.d.ts.map +1 -1
  24. package/dist/navigator.js +23 -1
  25. package/dist/navigator.js.map +1 -1
  26. package/dist/types.d.ts +14 -4
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/types.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/appManifest/icon.ts +26 -0
  31. package/src/appManifest/infra.ts +1 -12
  32. package/src/appManifest/navigator.ts +179 -0
  33. package/src/appManifest/navigatorOptions.ts +292 -0
  34. package/src/appManifest/screens.ts +3 -181
  35. package/src/contracts.test.ts +1 -1
  36. package/src/navigator-validation.test.ts +153 -0
  37. package/src/navigator.test.ts +176 -10
  38. package/src/navigator.ts +149 -13
  39. package/src/types.ts +16 -4
package/src/navigator.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { IconSpec } from './types';
1
+ import type { IconSpec, ManifestValue } from './types';
2
2
 
3
- export const NAVIGATOR_TYPES = ['stack', 'tabs', 'drawer'] as const;
3
+ export const NAVIGATOR_TYPES = ['slot', 'stack', 'tabs', 'drawer', 'split-view', 'custom'] as const;
4
4
  export type NavigatorType = (typeof NAVIGATOR_TYPES)[number];
5
5
 
6
6
  export const NAVIGATOR_PRESETS = [
7
+ 'slot',
7
8
  'stack',
8
9
  'tabs',
9
10
  'tabs-stack',
@@ -17,9 +18,82 @@ export const NAVIGATOR_PRESETS = [
17
18
  'root-stack-drawer-stack',
18
19
  'root-stack-drawer-tabs',
19
20
  'root-stack-drawer-tabs-stack',
21
+ 'split-view',
22
+ 'custom',
20
23
  ] as const;
21
24
  export type NavigatorPreset = (typeof NAVIGATOR_PRESETS)[number];
22
25
 
26
+ export const STACK_IMPLEMENTATIONS = ['native', 'javascript', 'experimental'] as const;
27
+ export type StackImplementation = (typeof STACK_IMPLEMENTATIONS)[number];
28
+
29
+ export const STACK_PRESENTATIONS = [
30
+ 'card',
31
+ 'modal',
32
+ 'transparentModal',
33
+ 'containedModal',
34
+ 'containedTransparentModal',
35
+ 'fullScreenModal',
36
+ 'formSheet',
37
+ ] as const;
38
+ export type StackPresentation = (typeof STACK_PRESENTATIONS)[number];
39
+
40
+ export const JAVASCRIPT_STACK_PRESENTATIONS = ['card', 'modal', 'transparentModal'] as const;
41
+ export type JavaScriptStackPresentation = (typeof JAVASCRIPT_STACK_PRESENTATIONS)[number];
42
+
43
+ export interface StackHeaderOptions {
44
+ title?: string;
45
+ headerShown?: boolean;
46
+ headerTransparent?: boolean;
47
+ headerBackVisible?: boolean;
48
+ }
49
+
50
+ export type StackScreenOptions = StackHeaderOptions &
51
+ (
52
+ | {
53
+ presentation?: Exclude<StackPresentation, 'formSheet'>;
54
+ sheetAllowedDetents?: never;
55
+ sheetGrabberVisible?: never;
56
+ }
57
+ | {
58
+ presentation: 'formSheet';
59
+ sheetAllowedDetents?: 'fitToContents' | number[];
60
+ sheetGrabberVisible?: boolean;
61
+ }
62
+ );
63
+
64
+ export type JavaScriptStackScreenOptions = StackHeaderOptions & {
65
+ presentation?: JavaScriptStackPresentation;
66
+ };
67
+
68
+ export type StackImplementationConfig =
69
+ | {
70
+ /** Omission selects the stable native stack implementation. */
71
+ implementation?: 'native';
72
+ options?: StackScreenOptions;
73
+ }
74
+ | {
75
+ implementation: 'javascript';
76
+ options?: JavaScriptStackScreenOptions;
77
+ }
78
+ | {
79
+ /** Expo Router Experimental Stack is alpha, native-only, and available from SDK 56. */
80
+ implementation: 'experimental';
81
+ options?: StackHeaderOptions;
82
+ };
83
+
84
+ export const DRAWER_POSITIONS = ['left', 'right'] as const;
85
+ export type DrawerPosition = (typeof DRAWER_POSITIONS)[number];
86
+
87
+ export const DRAWER_TYPES = ['front', 'back', 'slide', 'permanent'] as const;
88
+ export type DrawerType = (typeof DRAWER_TYPES)[number];
89
+
90
+ export interface DrawerNavigatorOptions {
91
+ drawerPosition?: DrawerPosition;
92
+ drawerType?: DrawerType;
93
+ swipeEnabled?: boolean;
94
+ headerShown?: boolean;
95
+ }
96
+
23
97
  export const FIXED_CUSTOM_TABS_PRESENTATIONS = ['bottom', 'top', 'rail', 'sidebar'] as const;
24
98
  export type FixedCustomTabsPresentation = (typeof FIXED_CUSTOM_TABS_PRESENTATIONS)[number];
25
99
 
@@ -33,22 +107,54 @@ export type CustomTabsPresentation = (typeof CUSTOM_TABS_PRESENTATIONS)[number];
33
107
  export const JAVASCRIPT_TABS_PRESENTATIONS = ['bottom', 'top'] as const;
34
108
  export type JavaScriptTabsPresentation = (typeof JAVASCRIPT_TABS_PRESENTATIONS)[number];
35
109
 
110
+ export const NATIVE_TABS_MINIMIZE_BEHAVIORS = [
111
+ 'automatic',
112
+ 'never',
113
+ 'onScrollDown',
114
+ 'onScrollUp',
115
+ ] as const;
116
+ export type NativeTabsMinimizeBehavior = (typeof NATIVE_TABS_MINIMIZE_BEHAVIORS)[number];
117
+
36
118
  export interface ResponsiveTabsPresentation {
37
119
  compact: FixedCustomTabsPresentation;
38
120
  medium?: FixedCustomTabsPresentation;
39
121
  expanded: FixedCustomTabsPresentation;
40
122
  }
41
123
 
42
- export interface CustomTabsConfig {
124
+ export type CustomTabsPresentationConfig =
125
+ | {
126
+ presentation: FixedCustomTabsPresentation;
127
+ responsive?: never;
128
+ customPresentationId?: never;
129
+ }
130
+ | {
131
+ presentation: 'responsive';
132
+ responsive: ResponsiveTabsPresentation;
133
+ customPresentationId?: never;
134
+ }
135
+ | {
136
+ presentation: 'custom';
137
+ responsive?: never;
138
+ /** Serializable registered presentation id. */
139
+ customPresentationId: string;
140
+ };
141
+
142
+ export type CustomTabsConfig = {
43
143
  implementation: 'custom';
44
- presentation: CustomTabsPresentation;
45
- responsive?: ResponsiveTabsPresentation;
46
- /** Serializable registered presentation id used when `presentation` is `custom`. */
47
- customPresentationId?: string;
144
+ } & CustomTabsPresentationConfig;
145
+
146
+ export type CustomTabsWebConfig = CustomTabsPresentationConfig;
147
+
148
+ export interface NavigatorScreenReference {
149
+ screenId: string;
48
150
  }
49
151
 
50
152
  export interface NativeTabsConfig {
51
153
  implementation: 'native';
154
+ /** Expo Router Native Tabs is alpha; minimizing is available on iOS 26+ from SDK 55. */
155
+ minimizeBehavior?: NativeTabsMinimizeBehavior;
156
+ /** Registered screen rendered through NativeTabs.BottomAccessory, available from SDK 55. */
157
+ bottomAccessory?: NavigatorScreenReference;
52
158
  }
53
159
 
54
160
  export interface JavaScriptTabsConfig {
@@ -62,7 +168,7 @@ export interface AdaptiveTabsConfig {
62
168
  /** Android/iOS branch. Expo Router may expose this implementation as unstable. */
63
169
  native?: NativeTabsConfig;
64
170
  /** Web branch rendered through headless custom tabs. */
65
- web?: Omit<CustomTabsConfig, 'implementation'>;
171
+ web?: CustomTabsWebConfig;
66
172
  }
67
173
 
68
174
  export type TabsImplementationConfig =
@@ -71,16 +177,19 @@ export type TabsImplementationConfig =
71
177
  interface NavigatorNodeBase {
72
178
  initialRouteName?: string;
73
179
  routes: RouteDefinition[];
74
- /** Typed upstream options can be layered by the owning Navigator package. */
75
- options?: Record<string, unknown>;
76
180
  }
77
181
 
78
- export interface StackNavigatorNode extends NavigatorNodeBase {
79
- type: 'stack';
182
+ export interface SlotNavigatorNode extends NavigatorNodeBase {
183
+ type: 'slot';
80
184
  }
81
185
 
186
+ export type StackNavigatorNode = NavigatorNodeBase & {
187
+ type: 'stack';
188
+ } & StackImplementationConfig;
189
+
82
190
  export interface DrawerNavigatorNode extends NavigatorNodeBase {
83
191
  type: 'drawer';
192
+ options?: DrawerNavigatorOptions;
84
193
  }
85
194
 
86
195
  export type TabsNavigatorConfig = {
@@ -89,7 +198,30 @@ export type TabsNavigatorConfig = {
89
198
 
90
199
  export type TabsNavigatorNode = NavigatorNodeBase & TabsNavigatorConfig;
91
200
 
92
- export type NavigatorNode = DrawerNavigatorNode | StackNavigatorNode | TabsNavigatorNode;
201
+ export interface SplitViewNavigatorNode extends NavigatorNodeBase {
202
+ type: 'split-view';
203
+ columns: {
204
+ primary: NavigatorScreenReference;
205
+ supplementary?: NavigatorScreenReference;
206
+ };
207
+ inspector?: NavigatorScreenReference;
208
+ /** Split View is alpha and iOS-only; other platforms fall back to Slot. */
209
+ topColumnForCollapsing?: 'primary' | 'supplementary' | 'secondary';
210
+ }
211
+
212
+ export interface CustomNavigatorNode extends NavigatorNodeBase {
213
+ type: 'custom';
214
+ navigatorId: string;
215
+ config?: Readonly<Record<string, ManifestValue>>;
216
+ }
217
+
218
+ export type NavigatorNode =
219
+ | CustomNavigatorNode
220
+ | DrawerNavigatorNode
221
+ | SlotNavigatorNode
222
+ | SplitViewNavigatorNode
223
+ | StackNavigatorNode
224
+ | TabsNavigatorNode;
93
225
 
94
226
  export interface RouteDefinition {
95
227
  name: string;
@@ -100,6 +232,8 @@ export interface RouteDefinition {
100
232
  showInPrimaryNavigation?: boolean;
101
233
  guards?: string[];
102
234
  screenId?: string;
235
+ /** Presentation applied by the resolved parent stack implementation. */
236
+ stackOptions?: StackScreenOptions;
103
237
  navigator?: NavigatorNode;
104
238
  }
105
239
 
@@ -110,10 +244,12 @@ export interface NavigatorFlows {
110
244
 
111
245
  export interface NavigatorDefaults {
112
246
  tabs?: TabsImplementationConfig;
247
+ stack?: StackImplementationConfig;
113
248
  }
114
249
 
115
250
  export interface NavigatorPlatformConfig {
116
251
  tabs?: TabsImplementationConfig;
252
+ stack?: StackImplementationConfig;
117
253
  }
118
254
 
119
255
  export interface NavigatorPlatforms {
package/src/types.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  } from './bindings';
9
9
  import type { ApiDefinitionList, DataSourceRegistry } from './data';
10
10
  import type { AppDeployManifest } from './deploy';
11
- import type { MediaManifest } from './media';
11
+ import type { MediaAssetReference, MediaManifest } from './media';
12
12
  import type { AppNavigatorManifest } from './navigator';
13
13
  import type { RepositoryManifest } from './repository';
14
14
  import type { ScreenRequirements } from './requirements';
@@ -222,13 +222,25 @@ export type AuthProfileCreateStrategy = (typeof AUTH_PROFILE_CREATE_STRATEGIES)[
222
222
  export const AUTH_PROFILE_UPDATE_STRATEGIES = ['api', 'app'] as const;
223
223
  export type AuthProfileUpdateStrategy = (typeof AUTH_PROFILE_UPDATE_STRATEGIES)[number];
224
224
 
225
- export interface IconSpec {
226
- name: string;
227
- provider?: string;
225
+ interface IconPresentationSpec {
228
226
  size?: number | string;
229
227
  color?: string;
230
228
  }
231
229
 
230
+ export interface NamedIconSpec extends IconPresentationSpec {
231
+ name: string;
232
+ provider?: string;
233
+ source?: never;
234
+ }
235
+
236
+ export interface SvgIconSpec extends IconPresentationSpec {
237
+ source: MediaAssetReference;
238
+ name?: never;
239
+ provider?: never;
240
+ }
241
+
242
+ export type IconSpec = NamedIconSpec | SvgIconSpec;
243
+
232
244
  export interface UiNodeRepeatSpec {
233
245
  source: BindingValueSource;
234
246
  itemAlias?: string;