@symbiote-native/angular 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/babel-register-composed.cjs +2 -0
  2. package/build/angular/accessibility-inputs.d.ts +2 -1
  3. package/build/angular/accessibility-inputs.js +4 -1
  4. package/build/angular/accessibility-inputs.js.map +1 -1
  5. package/build/angular/callback-host.d.ts +1 -1
  6. package/build/angular/callback-host.js +57 -9
  7. package/build/angular/callback-host.js.map +1 -1
  8. package/build/angular/components/checkbox-props.d.ts +2 -0
  9. package/build/angular/components/checkbox-props.js +2 -0
  10. package/build/angular/components/checkbox-props.js.map +1 -0
  11. package/build/angular/components/flat-list/flat-list-handle.d.ts +35 -0
  12. package/build/angular/components/flat-list/flat-list-handle.js +48 -0
  13. package/build/angular/components/flat-list/flat-list-handle.js.map +1 -0
  14. package/build/angular/components/flat-list/flat-list-template.d.ts +1 -1
  15. package/build/angular/components/flat-list/flat-list-template.js +16 -0
  16. package/build/angular/components/flat-list/flat-list-template.js.map +1 -1
  17. package/build/angular/components/flat-list/index.d.ts +6 -30
  18. package/build/angular/components/flat-list/index.js +6 -36
  19. package/build/angular/components/flat-list/index.js.map +1 -1
  20. package/build/angular/components/image-inputs.d.ts +4 -0
  21. package/build/angular/components/image-inputs.js +81 -0
  22. package/build/angular/components/image-inputs.js.map +1 -0
  23. package/build/angular/components/image-props-resolve.d.ts +3 -0
  24. package/build/angular/components/image-props-resolve.js +133 -0
  25. package/build/angular/components/image-props-resolve.js.map +1 -0
  26. package/build/angular/components/image-shared.d.ts +8 -6
  27. package/build/angular/components/image-shared.js +23 -212
  28. package/build/angular/components/image-shared.js.map +1 -1
  29. package/build/angular/components/input-accessory-view-props.d.ts +4 -4
  30. package/build/angular/components/keyboard-avoiding-view/index.d.ts +3 -6
  31. package/build/angular/components/keyboard-avoiding-view/index.js +29 -56
  32. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
  33. package/build/angular/components/layout-conformance-props.d.ts +4 -0
  34. package/build/angular/components/layout-conformance-props.js +2 -0
  35. package/build/angular/components/layout-conformance-props.js.map +1 -0
  36. package/build/angular/components/modal/index.d.ts +6 -5
  37. package/build/angular/components/modal/index.js +17 -2
  38. package/build/angular/components/modal/index.js.map +1 -1
  39. package/build/angular/components/refresh-control-props.d.ts +7 -7
  40. package/build/angular/components/scroll-view-props.d.ts +8 -5
  41. package/build/angular/components/section-list/index.d.ts +17 -8
  42. package/build/angular/components/section-list/index.js +37 -28
  43. package/build/angular/components/section-list/index.js.map +1 -1
  44. package/build/angular/components/touchable-props.d.ts +2 -2
  45. package/build/angular/components/virtualized-list/cell-renderer-context.d.ts +12 -0
  46. package/build/angular/components/virtualized-list/cell-renderer-context.js +16 -0
  47. package/build/angular/components/virtualized-list/cell-renderer-context.js.map +1 -0
  48. package/build/angular/components/virtualized-list/directives.d.ts +26 -6
  49. package/build/angular/components/virtualized-list/directives.js +59 -5
  50. package/build/angular/components/virtualized-list/directives.js.map +1 -1
  51. package/build/angular/components/virtualized-list/index.d.ts +19 -15
  52. package/build/angular/components/virtualized-list/index.js +91 -61
  53. package/build/angular/components/virtualized-list/index.js.map +1 -1
  54. package/build/angular/components/virtualized-list/list-bags.d.ts +5 -1
  55. package/build/angular/components/virtualized-list/list-bags.js +31 -19
  56. package/build/angular/components/virtualized-list/list-bags.js.map +1 -1
  57. package/build/angular/components/virtualized-list/list-effects.d.ts +2 -2
  58. package/build/angular/components/virtualized-list/list-effects.js +17 -27
  59. package/build/angular/components/virtualized-list/list-effects.js.map +1 -1
  60. package/build/angular/components/virtualized-list/list-handle.d.ts +4 -1
  61. package/build/angular/components/virtualized-list/list-handle.js +13 -3
  62. package/build/angular/components/virtualized-list/list-handle.js.map +1 -1
  63. package/build/angular/components/virtualized-list/list-inputs.d.ts +19 -5
  64. package/build/angular/components/virtualized-list/list-inputs.js +47 -4
  65. package/build/angular/components/virtualized-list/list-inputs.js.map +1 -1
  66. package/build/angular/components/virtualized-list/list-props.d.ts +9 -3
  67. package/build/angular/components/virtualized-list/list-rows.d.ts +25 -0
  68. package/build/angular/components/virtualized-list/list-rows.js +25 -0
  69. package/build/angular/components/virtualized-list/list-rows.js.map +1 -0
  70. package/build/angular/components/virtualized-list/list-styles.d.ts +4 -0
  71. package/build/angular/components/virtualized-list/list-styles.js +10 -2
  72. package/build/angular/components/virtualized-list/list-styles.js.map +1 -1
  73. package/build/angular/components/virtualized-list/list-template.d.ts +1 -1
  74. package/build/angular/components/virtualized-list/list-template.js +159 -73
  75. package/build/angular/components/virtualized-list/list-template.js.map +1 -1
  76. package/build/angular/components/virtualized-list/nested-scope.d.ts +6 -0
  77. package/build/angular/components/virtualized-list/nested-scope.js +17 -0
  78. package/build/angular/components/virtualized-list/nested-scope.js.map +1 -0
  79. package/build/angular/components/virtualized-section-list/directives.d.ts +21 -9
  80. package/build/angular/components/virtualized-section-list/directives.js +8 -28
  81. package/build/angular/components/virtualized-section-list/directives.js.map +1 -1
  82. package/build/angular/components/virtualized-section-list/index.d.ts +39 -60
  83. package/build/angular/components/virtualized-section-list/index.js +67 -33
  84. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  85. package/build/angular/components/virtualized-section-list/section-cell.d.ts +29 -0
  86. package/build/angular/components/virtualized-section-list/section-cell.js +82 -0
  87. package/build/angular/components/virtualized-section-list/section-cell.js.map +1 -0
  88. package/build/angular/components/virtualized-section-list/section-list-props.d.ts +56 -0
  89. package/build/angular/components/virtualized-section-list/section-list-props.js +3 -0
  90. package/build/angular/components/virtualized-section-list/section-list-props.js.map +1 -0
  91. package/build/angular/components/virtualized-section-list/section-list-template.d.ts +1 -1
  92. package/build/angular/components/virtualized-section-list/section-list-template.js +34 -26
  93. package/build/angular/components/virtualized-section-list/section-list-template.js.map +1 -1
  94. package/build/angular/components.d.ts +8 -3
  95. package/build/angular/components.js +2 -1
  96. package/build/angular/components.js.map +1 -1
  97. package/build/angular/descriptor-to-angular/descriptor-host.d.ts +8 -0
  98. package/build/angular/descriptor-to-angular/descriptor-host.js +38 -0
  99. package/build/angular/descriptor-to-angular/descriptor-host.js.map +1 -0
  100. package/build/angular/descriptor-to-angular/index.d.ts +1 -0
  101. package/build/angular/descriptor-to-angular/index.js +4 -0
  102. package/build/angular/descriptor-to-angular/index.js.map +1 -1
  103. package/build/angular/element-base.d.ts +169 -0
  104. package/build/angular/element-base.js +304 -0
  105. package/build/angular/element-base.js.map +1 -0
  106. package/build/angular/element-props.d.ts +7 -7
  107. package/build/angular/element-text-input-native.d.ts +27 -0
  108. package/build/angular/element-text-input-native.js +52 -0
  109. package/build/angular/element-text-input-native.js.map +1 -0
  110. package/build/angular/elements-controls.d.ts +171 -0
  111. package/build/angular/elements-controls.js +394 -0
  112. package/build/angular/elements-controls.js.map +1 -0
  113. package/build/angular/elements-layout.d.ts +139 -0
  114. package/build/angular/elements-layout.js +276 -0
  115. package/build/angular/elements-layout.js.map +1 -0
  116. package/build/angular/elements-press.d.ts +103 -0
  117. package/build/angular/elements-press.js +239 -0
  118. package/build/angular/elements-press.js.map +1 -0
  119. package/build/angular/elements.d.ts +6 -516
  120. package/build/angular/elements.js +9 -1091
  121. package/build/angular/elements.js.map +1 -1
  122. package/build/angular/host-instance/index.d.ts +2 -0
  123. package/build/angular/host-instance/index.js +4 -4
  124. package/build/angular/host-instance/index.js.map +1 -1
  125. package/build/angular/index.d.ts +17 -9
  126. package/build/angular/index.js +24 -27
  127. package/build/angular/index.js.map +1 -1
  128. package/build/angular/modules/animated/create-animated-component.d.ts +1 -1
  129. package/build/angular/modules/animated/create-animated-component.js +1 -1
  130. package/build/angular/modules/animated/create-animated-component.js.map +1 -1
  131. package/build/angular/modules/animated/index.d.ts +54 -41
  132. package/build/angular/modules/animated/index.js +2 -26
  133. package/build/angular/modules/animated/index.js.map +1 -1
  134. package/build/angular/modules/app-registry/index.d.ts +3 -3
  135. package/build/angular/modules/app-registry/index.js +2 -2
  136. package/build/angular/modules/app-registry/index.js.map +1 -1
  137. package/build/angular/modules/status-bar/index.d.ts +9 -5
  138. package/build/angular/modules/status-bar/index.js +21 -10
  139. package/build/angular/modules/status-bar/index.js.map +1 -1
  140. package/build/angular/native-view-base.d.ts +10 -2
  141. package/build/angular/native-view-base.js +23 -2
  142. package/build/angular/native-view-base.js.map +1 -1
  143. package/build/angular/primitives/index.d.ts +4 -0
  144. package/build/angular/primitives/index.js +12 -0
  145. package/build/angular/primitives/index.js.map +1 -1
  146. package/build/angular/services/color-scheme.service.d.ts +1 -1
  147. package/build/angular/services/index.d.ts +1 -0
  148. package/build/angular/services/index.js +1 -0
  149. package/build/angular/services/index.js.map +1 -1
  150. package/build/angular/services/inject-event.d.ts +6 -0
  151. package/build/angular/services/inject-event.js +24 -0
  152. package/build/angular/services/inject-event.js.map +1 -0
  153. package/package.json +6 -6
  154. package/src/accessibility-inputs.ts +3 -0
  155. package/src/callback-host.ts +56 -8
  156. package/src/components/checkbox-props.ts +12 -0
  157. package/src/components/flat-list/flat-list-handle.ts +64 -0
  158. package/src/components/flat-list/flat-list-template.ts +16 -0
  159. package/src/components/flat-list/index.ts +6 -48
  160. package/src/components/image-inputs.ts +94 -0
  161. package/src/components/image-props-resolve.ts +172 -0
  162. package/src/components/image-shared.ts +26 -291
  163. package/src/components/input-accessory-view-props.ts +12 -8
  164. package/src/components/keyboard-avoiding-view/index.ts +39 -79
  165. package/src/components/layout-conformance-props.ts +8 -0
  166. package/src/components/modal/index.ts +42 -20
  167. package/src/components/refresh-control-props.ts +29 -25
  168. package/src/components/scroll-view-props.ts +84 -76
  169. package/src/components/section-list/index.ts +34 -37
  170. package/src/components/touchable-props.ts +6 -2
  171. package/src/components/virtualized-list/cell-renderer-context.ts +36 -0
  172. package/src/components/virtualized-list/directives.ts +84 -8
  173. package/src/components/virtualized-list/index.ts +118 -85
  174. package/src/components/virtualized-list/list-bags.ts +38 -19
  175. package/src/components/virtualized-list/list-effects.ts +20 -32
  176. package/src/components/virtualized-list/list-handle.ts +17 -4
  177. package/src/components/virtualized-list/list-inputs.ts +47 -0
  178. package/src/components/virtualized-list/list-props.ts +57 -50
  179. package/src/components/virtualized-list/list-rows.ts +66 -0
  180. package/src/components/virtualized-list/list-styles.ts +30 -1
  181. package/src/components/virtualized-list/list-template.ts +159 -73
  182. package/src/components/virtualized-list/nested-scope.ts +22 -0
  183. package/src/components/virtualized-section-list/directives.ts +41 -40
  184. package/src/components/virtualized-section-list/index.ts +114 -118
  185. package/src/components/virtualized-section-list/section-cell.ts +109 -0
  186. package/src/components/virtualized-section-list/section-list-props.ts +79 -0
  187. package/src/components/virtualized-section-list/section-list-template.ts +34 -26
  188. package/src/components.ts +9 -0
  189. package/src/descriptor-to-angular/descriptor-host.ts +27 -0
  190. package/src/descriptor-to-angular/index.ts +5 -0
  191. package/src/element-base.ts +289 -0
  192. package/src/element-props.ts +35 -33
  193. package/src/element-text-input-native.ts +31 -0
  194. package/src/elements-controls.ts +290 -0
  195. package/src/elements-layout.ts +168 -0
  196. package/src/elements-press.ts +153 -0
  197. package/src/elements.ts +76 -788
  198. package/src/host-instance/index.ts +4 -4
  199. package/src/index.ts +78 -23
  200. package/src/modules/animated/index.ts +2 -47
  201. package/src/modules/app-registry/index.ts +3 -1
  202. package/src/modules/status-bar/index.ts +24 -11
  203. package/src/native-view-base.ts +37 -2
  204. package/src/primitives/index.ts +7 -0
  205. package/src/services/color-scheme.service.ts +1 -1
  206. package/src/services/index.ts +1 -0
  207. package/src/services/inject-event.ts +52 -0
@@ -21,14 +21,14 @@ import {
21
21
 
22
22
  export type { IHostInstance } from '@symbiote-native/engine';
23
23
 
24
- function resolveHostNode(candidate: unknown): ISymbioteNode | null {
24
+ export function hostNodeOf(candidate: unknown): ISymbioteNode | null {
25
25
  if (candidate === null || candidate === undefined) return null;
26
26
  if (isSymbioteNode(candidate)) return candidate;
27
27
  if (candidate instanceof ElementRef)
28
- return resolveHostNode(candidate.nativeElement);
28
+ return hostNodeOf(candidate.nativeElement);
29
29
  const maybeHost = candidate as { nativeElement?: unknown };
30
30
  if (typeof maybeHost.nativeElement !== 'undefined') {
31
- return resolveHostNode(maybeHost.nativeElement);
31
+ return hostNodeOf(maybeHost.nativeElement);
32
32
  }
33
33
  return null;
34
34
  }
@@ -37,6 +37,6 @@ export function findNodeHandle(componentOrHandle: unknown): number | null {
37
37
  if (componentOrHandle === null || componentOrHandle === undefined)
38
38
  return null;
39
39
  if (typeof componentOrHandle === 'number') return componentOrHandle;
40
- const node = resolveHostNode(componentOrHandle);
40
+ const node = hostNodeOf(componentOrHandle);
41
41
  return node ? (getNativeTag(node) ?? null) : null;
42
42
  }
package/src/index.ts CHANGED
@@ -36,24 +36,27 @@ export {
36
36
  Text,
37
37
  TouchableNativeFeedback,
38
38
  View,
39
+ injectVirtualizedListScope,
39
40
  VirtualizedList,
40
41
  VirtualizedSectionList,
42
+ VListCellDirective,
41
43
  VListEmptyDirective,
42
44
  VListFooterDirective,
43
45
  VListHeaderDirective,
44
46
  VListItemDirective,
47
+ VListOutletDirective,
45
48
  VListSeparatorDirective,
46
49
  VSectionFooterDirective,
47
50
  VSectionHeaderDirective,
48
51
  VSectionItemDirective,
49
52
  VSectionSeparatorDirective,
50
53
  } from './components';
54
+ // What a list built on `FlatList` needs to keep its template and its accessibility gate
55
+ export { FLAT_LIST_TEMPLATE } from './components/flat-list/flat-list-template';
56
+ export { provideGateDemand } from './gate-demand';
51
57
  export { Animated } from './modules/animated';
52
- // Also exposed as named top-level symbols (not just Animated.View/.Text/...): ngtsc's partial-mode
53
- // static evaluator can't trace a component class through property access on an external
54
- // namespace object, only through a direct named import binding —
55
- // so `<AnimatedView>` in a template requires `import { AnimatedView } from '@symbiote-native/angular'`,
56
- // not `const AnimatedView = Animated.View`. Plain tsc/vitest don't catch this; only a real ngc run does.
58
+ // Named top-level too, as the ngtsc static evaluator cannot trace `Animated.View` property access
59
+ // A template tag like `<AnimatedView>` needs a direct import, only a real ngc run catches it
57
60
  export {
58
61
  AnimatedFlatList,
59
62
  AnimatedImage,
@@ -62,15 +65,9 @@ export {
62
65
  AnimatedText,
63
66
  AnimatedView,
64
67
  } from './modules/animated';
65
- // Exported even though Angular's version maps only the four primitives (View/Text/Image/
66
- // ScrollView) onto the pre-authored wrappers above and THROWS on anything else — there is no JIT
67
- // under AOT/Metro, so it cannot synthesize a wrapper at runtime the way the other four adapters
68
- // do. It ships anyway because portable code (`createAnimatedComponent(View)`) then compiles and
69
- // runs identically on all five adapters, and the one case Angular cannot serve fails with a
70
- // message naming the fix (author a standalone @Component over AnimatedComponentBase) instead of
71
- // failing as a missing export, which names nothing. Found by the barrel audit in
72
- // `.claude/rules/adapter-parity-audit.md`: it was implemented and tested here all along and simply
73
- // never reached this file, so `@symbiote-native/angular` consumers could not reach it at all.
68
+ // Maps only View/Text/Image/ScrollView onto the wrappers above and throws on anything else (no JIT)
69
+ // Portable `createAnimatedComponent(View)` still runs on all five adapters, and the error names
70
+ // the fix: a standalone `@Component` over `AnimatedComponentBase`
74
71
  export { createAnimatedComponent } from './modules/animated';
75
72
  export type {
76
73
  IActivityIndicatorProps,
@@ -78,6 +75,7 @@ export type {
78
75
  IAngularImageBackgroundProps,
79
76
  IAngularInputAccessoryViewProps,
80
77
  IAngularKeyboardAvoidingViewProps,
78
+ IAngularLayoutConformanceProps,
81
79
  IAngularModalProps,
82
80
  IAngularPressableProps,
83
81
  IAngularRefreshControlProps,
@@ -89,6 +87,7 @@ export type {
89
87
  IAngularTouchableOpacityProps,
90
88
  IAngularTouchableWithoutFeedbackProps,
91
89
  IButtonProps,
90
+ ICheckboxProps,
92
91
  ICellLayout,
93
92
  IFlatListHandle,
94
93
  IFlatListProps,
@@ -100,6 +99,7 @@ export type {
100
99
  IImageSourceProp,
101
100
  IInputMode,
102
101
  IKeyboardAvoidingBehavior,
102
+ ILayoutConformanceMode,
103
103
  IModalAnimationType,
104
104
  IModalOrientation,
105
105
  IModalOrientationChangeEvent,
@@ -118,14 +118,17 @@ export type {
118
118
  IViewabilityConfigCallbackPair,
119
119
  IViewableItemsChangedInfo,
120
120
  IViewToken,
121
+ IListScope,
121
122
  IVirtualizedListHandle,
122
123
  IVirtualizedListProps,
123
124
  IVirtualizedSectionListHandle,
124
125
  IVirtualizedSectionListProps,
126
+ IVListCellContext,
125
127
  IVListItemContext,
126
128
  IVListSeparatorContext,
127
129
  IVSectionContext,
128
130
  IVSectionItemContext,
131
+ IVSectionSeparatorContext,
129
132
  ISection,
130
133
  ISwitchProps,
131
134
  ISwitchTrackColor,
@@ -144,6 +147,7 @@ export {
144
147
  ActivityIndicatorElement,
145
148
  ActivityIndicatorSpinnerElement,
146
149
  ButtonElement,
150
+ CheckboxElement,
147
151
  HorizontalScrollContentElement,
148
152
  HorizontalScrollViewElement,
149
153
  ImageBackgroundElement,
@@ -154,6 +158,7 @@ export {
154
158
  PressableElement,
155
159
  RefreshControlElement,
156
160
  SafeAreaViewElement,
161
+ LayoutConformanceElement,
157
162
  ScrollContentElement,
158
163
  ScrollViewElement,
159
164
  StickyHeaderElement,
@@ -187,12 +192,9 @@ export { mount, unmount } from './render';
187
192
  // @symbiote-native/slider) can render a shared @symbiote-native/components/@symbiote-native/slider Descriptor tree
188
193
  // without hand-writing its own Renderer2 walker.
189
194
  export { DescriptorOutlet } from './descriptor-to-angular';
190
- // createPortal (same-surface only — see the file header) and createTunnel (cross-surface,
191
- // see its file header) are the Angular twins of the React/Vue portal/tunnel primitives.
192
- // Angular can't synthesize components at runtime (no JIT under Metro/Hermes), so both are
193
- // static, pre-authored structural directives (`*portal`/`*tunnelIn`, the `*ngIf`/`*ngFor`
194
- // idiom) parameterized by an `@Input()`, rather than a factory returning fresh components per
195
- // call.
195
+ export { DescriptorHost } from './descriptor-to-angular/descriptor-host';
196
+ // Twins of the React/Vue portal and tunnel: same-surface portal, cross-surface tunnel
197
+ // No JIT under Metro/Hermes, so both are pre-authored structural directives (`*portal`/`*tunnelIn`)
196
198
  export { PortalDirective, PortalOutletDirective } from './create-portal';
197
199
  export {
198
200
  createTunnel,
@@ -206,15 +208,20 @@ export { SymbioteRenderer, SymbioteRendererFactory } from './renderer';
206
208
  // import straight from that subpath so app-screen registration never routes through this cyclic
207
209
  // barrel.
208
210
  export { registerComposedComponent } from './anchor-host-registry';
209
- export { findNodeHandle } from './host-instance';
211
+ export { findNodeHandle, hostNodeOf } from './host-instance';
210
212
  export type { IHostInstance } from './host-instance';
211
213
  export { StatusBar } from './modules/status-bar';
212
214
  export type { IStatusBarProps, IStatusBarStyle } from './modules/status-bar';
213
215
  // AppRegistry: RN's app entry point over `mount`. setHostRegistrar wires RN's own
214
216
  // registrar so the native Fabric host finds our runnable by app key.
215
- export { AppRegistry, setHostRegistrar } from './modules/app-registry';
217
+ export {
218
+ AppRegistry,
219
+ HeadlessJsTaskError,
220
+ setHostRegistrar,
221
+ } from './modules/app-registry';
216
222
  export type {
217
223
  IComponentProvider,
224
+ IAppConfig,
218
225
  IAppParameters,
219
226
  IRunnable,
220
227
  IHostRegistrar,
@@ -230,9 +237,16 @@ export {
230
237
  WindowDimensionsService,
231
238
  createResourceHook,
232
239
  createEventValueHook,
240
+ injectEvent,
241
+ injectEventListener,
233
242
  connectWatchedSignal,
234
243
  PermissionsServiceBase,
235
244
  } from './services';
245
+ export {
246
+ createAnimatedColor as injectAnimatedColor,
247
+ createAnimatedValue as injectAnimatedValue,
248
+ createAnimatedValueXY as injectAnimatedValueXY,
249
+ } from '@symbiote-native/engine';
236
250
  export { AccessibilityInputsBase } from './accessibility-inputs';
237
251
  export { NativeViewBase } from './native-view-base';
238
252
  export { anchorStyleProp } from './primitives/shared';
@@ -253,6 +267,7 @@ export {
253
267
  AppState,
254
268
  Keyboard,
255
269
  KEYBOARD_EVENT,
270
+ TextInputState,
256
271
  BackHandler,
257
272
  PermissionsAndroid,
258
273
  PERMISSIONS,
@@ -328,7 +343,6 @@ export {
328
343
  Platform,
329
344
  processColor,
330
345
  setColorProcessor,
331
- setDeviceEventSource,
332
346
  setNativeViewConfigSource,
333
347
  StyleSheet,
334
348
  } from '@symbiote-native/engine';
@@ -376,3 +390,44 @@ export {
376
390
  setAngularProfileDetail,
377
391
  } from './diagnostics';
378
392
  export type { IAngularProfile, IAngularProfileDetail } from './diagnostics';
393
+
394
+ // The device event bus and the easing curves, shared verbatim from the engine
395
+ export {
396
+ DeviceEventEmitter,
397
+ Easing,
398
+ EventEmitter,
399
+ NativeAppEventEmitter,
400
+ NativeEventEmitter,
401
+ } from '@symbiote-native/engine';
402
+ export type {
403
+ IEasing,
404
+ IEasingFunction,
405
+ IEmitterSubscription,
406
+ IEventEmitter,
407
+ IEventEmitterModule,
408
+ IEventSubscription,
409
+ INativeEventListener,
410
+ } from '@symbiote-native/engine';
411
+
412
+ // RN's dev and native-module utilities, shared verbatim from the engine. The ones RN owns forward
413
+ // to its own module, which `registerApp` hands over
414
+ export {
415
+ codegenNativeCommands,
416
+ codegenNativeComponent,
417
+ DevMenu,
418
+ DevSettings,
419
+ LogBox,
420
+ NativeComponentRegistry,
421
+ NativeModules,
422
+ Networking,
423
+ PushNotificationIOS,
424
+ ReactNativeVersion,
425
+ registerCallableModule,
426
+ requireNativeComponent,
427
+ Systrace,
428
+ Touchable,
429
+ TurboModuleRegistry,
430
+ UIManager,
431
+ UTFSequence,
432
+ } from '@symbiote-native/engine';
433
+ export type { IDevSettings } from '@symbiote-native/engine';
@@ -6,29 +6,9 @@
6
6
  // `Animated.timing(new Animated.Value(0), …).start()`, works against the Angular-driven engine.
7
7
 
8
8
  import {
9
- AnimatedValue,
10
- AnimatedValueXY,
11
- AnimatedColor,
9
+ AnimatedDrivers,
12
10
  AnimatedMock,
13
- Easing,
14
11
  Platform,
15
- timing,
16
- spring,
17
- decay,
18
- parallel,
19
- sequence,
20
- stagger,
21
- loop,
22
- delay,
23
- add,
24
- subtract,
25
- multiply,
26
- divide,
27
- modulo,
28
- diffClamp,
29
- event,
30
- forkEvent,
31
- unforkEvent,
32
12
  } from '@symbiote-native/engine';
33
13
  import {
34
14
  AnimatedFlatList,
@@ -61,37 +41,12 @@ export {
61
41
  // components exist. Angular still cannot synthesize arbitrary animated wrappers at runtime; custom
62
42
  // animated components remain explicit standalone components over AnimatedComponentBase.
63
43
 
64
- // The live, JS-driven driver namespace (real frames). RN's AnimatedImplementation.
65
- const liveDrivers = {
66
- Value: AnimatedValue,
67
- ValueXY: AnimatedValueXY,
68
- Color: AnimatedColor,
69
- Easing,
70
- timing,
71
- spring,
72
- decay,
73
- parallel,
74
- sequence,
75
- stagger,
76
- loop,
77
- delay,
78
- add,
79
- subtract,
80
- multiply,
81
- divide,
82
- modulo,
83
- diffClamp,
84
- event,
85
- forkEvent,
86
- unforkEvent,
87
- };
88
-
89
44
  // RN swaps the WHOLE driver namespace for the mock when the host reports isDisableAnimations
90
45
  // (reduced motion / test env): the mock keeps the same surface but jumps each animation to its
91
46
  // final value synchronously, no frames. The animated COMPONENTS are live in both branches; only
92
47
  // the drivers/value/operators/events half is swapped, exactly like RN spreading `...Animated`
93
48
  // (impl or mock) over the same components.
94
- const drivers = Platform.isDisableAnimations ? AnimatedMock : liveDrivers;
49
+ const drivers = Platform.isDisableAnimations ? AnimatedMock : AnimatedDrivers;
95
50
 
96
51
  export const Animated = {
97
52
  View: AnimatedView,
@@ -10,6 +10,7 @@ import type { Type } from '@angular/core';
10
10
  import {
11
11
  createAppRegistry,
12
12
  dlog,
13
+ HeadlessJsTaskError,
13
14
  type IAppParameters,
14
15
  type IRunnable,
15
16
  } from '@symbiote-native/engine';
@@ -47,8 +48,9 @@ const { AppRegistry, setHostRegistrar } = createAppRegistry<
47
48
  IWrapperComponentProvider
48
49
  >(runnableFor);
49
50
 
50
- export { AppRegistry, setHostRegistrar };
51
+ export { AppRegistry, HeadlessJsTaskError, setHostRegistrar };
51
52
  export type {
53
+ IAppConfig,
52
54
  IAppParameters,
53
55
  IRunnable,
54
56
  IHostRegistrar,
@@ -1,21 +1,20 @@
1
- // StatusBar, the Angular lifecycle half. The native StatusBarManager driving, the imperative
2
- // statics, and the Android bar-height constant all live in @symbiote-native/engine, shared verbatim with
3
- // React and Vue; Metro selects the engine's platform variant. Angular supplies only the
4
- // declarative shape: a component that renders nothing and re-applies the props through
5
- // ngOnChanges on mount + every prop change. Imperative statics are attached to the component
6
- // object the same way RN does.
1
+ // Angular half of StatusBar, the props stack, statics and Android bar-height constant live in
2
+ // @symbiote-native/engine. It renders nothing, keeps one stack entry through `ngOnChanges` and
3
+ // releases it in `ngOnDestroy`
7
4
 
8
5
  import {
9
6
  Component,
10
7
  Input,
11
8
  type OnChanges,
12
- type SimpleChanges,
9
+ type OnDestroy,
10
+ type OnInit,
13
11
  } from '@angular/core';
14
12
  import {
15
- applyStatusBarProps,
13
+ createStatusBarEntry,
16
14
  statusBarImperative,
17
15
  statusBarCurrentHeight,
18
16
  type IColorValue,
17
+ type IStatusBarAnimation,
19
18
  type IStatusBarProps,
20
19
  type IStatusBarStyle,
21
20
  } from '@symbiote-native/engine';
@@ -27,16 +26,29 @@ export type { IStatusBarProps, IStatusBarStyle } from '@symbiote-native/engine';
27
26
  standalone: true,
28
27
  template: '',
29
28
  })
30
- class StatusBarComponent implements OnChanges {
29
+ class StatusBarComponent implements OnInit, OnChanges, OnDestroy {
31
30
  @Input() barStyle?: IStatusBarStyle;
32
31
  @Input() hidden?: boolean;
33
32
  @Input() animated?: boolean;
33
+ @Input() showHideTransition?: IStatusBarAnimation;
34
34
  @Input() networkActivityIndicatorVisible?: boolean;
35
35
  @Input() backgroundColor?: IColorValue;
36
36
  @Input() translucent?: boolean;
37
37
 
38
- ngOnChanges(_changes: SimpleChanges): void {
39
- applyStatusBarProps(this.buildProps());
38
+ private readonly entry = createStatusBarEntry();
39
+
40
+ // `ngOnChanges` never runs without bound inputs, the bar still takes its place in the stack
41
+ ngOnInit(): void {
42
+ this.entry.apply(this.buildProps());
43
+ }
44
+
45
+ ngOnChanges(): void {
46
+ this.entry.apply(this.buildProps());
47
+ }
48
+
49
+ // Popping restores what the stack held below this entry
50
+ ngOnDestroy(): void {
51
+ this.entry.release();
40
52
  }
41
53
 
42
54
  private buildProps(): IStatusBarProps {
@@ -44,6 +56,7 @@ class StatusBarComponent implements OnChanges {
44
56
  barStyle: this.barStyle,
45
57
  hidden: this.hidden,
46
58
  animated: this.animated,
59
+ showHideTransition: this.showHideTransition,
47
60
  networkActivityIndicatorVisible: this.networkActivityIndicatorVisible,
48
61
  backgroundColor: this.backgroundColor,
49
62
  translucent: this.translucent,
@@ -1,18 +1,32 @@
1
- import { Directive, ElementRef, inject, Input } from '@angular/core';
1
+ import {
2
+ ChangeDetectorRef,
3
+ Directive,
4
+ ElementRef,
5
+ inject,
6
+ Input,
7
+ ViewChild,
8
+ } from '@angular/core';
9
+ import type { OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
2
10
  import { resolveAccessibilityProps } from '@symbiote-native/components';
3
11
  import type { IDescriptor } from '@symbiote-native/components';
4
12
  import type {
5
13
  IStyleProp,
6
14
  ISymbioteEvent,
15
+ ISymbioteNode,
7
16
  IViewStyle,
8
17
  } from '@symbiote-native/engine';
9
18
  import { AccessibilityInputsBase } from './accessibility-inputs';
19
+ import { DescriptorOutlet } from './descriptor-to-angular';
20
+ import { hostNodeOf } from './host-instance';
10
21
  import { anchorStyleProp } from './primitives/shared';
11
22
 
12
23
  // Shared shell of a component that paints one Expo native view: the common inputs, the anchor
13
24
  // host `class="..."` resolves onto, and a descriptor that recomputes on every OnPush check
14
25
  @Directive()
15
- export abstract class NativeViewBase extends AccessibilityInputsBase {
26
+ export abstract class NativeViewBase
27
+ extends AccessibilityInputsBase
28
+ implements OnChanges, OnDestroy
29
+ {
16
30
  @Input() style?: IStyleProp<IViewStyle>;
17
31
  @Input() testID?: string;
18
32
  @Input() nativeID?: string;
@@ -23,6 +37,27 @@ export abstract class NativeViewBase extends AccessibilityInputsBase {
23
37
 
24
38
  // This component's own `ElementRef`, the anchor a `class="..."` at the use site lands on
25
39
  private readonly elementRef = inject(ElementRef);
40
+ protected readonly changeDetector = inject(ChangeDetectorRef);
41
+
42
+ @ViewChild(DescriptorOutlet) private readonly nativeOutlet?: DescriptorOutlet;
43
+
44
+ // The committed host node of the native view, for a component that calls its view functions
45
+ protected hostNode(): ISymbioteNode | null {
46
+ return hostNodeOf(this.nativeOutlet?.rootNode);
47
+ }
48
+
49
+ // Hook for a component that holds more than its native node, runs once when it is destroyed
50
+ protected disposeView(): void {}
51
+
52
+ // A `[style]` binding reaches the `style` input without dirtying an OnPush view, a plain
53
+ // `[prop]` does. A subclass with its own `ngOnChanges` calls this one first
54
+ ngOnChanges(changes: SimpleChanges): void {
55
+ if ('style' in changes) this.changeDetector.markForCheck();
56
+ }
57
+
58
+ ngOnDestroy(): void {
59
+ this.disposeView();
60
+ }
26
61
 
27
62
  // Names of the component's own inputs that go to the native view, read off `this`
28
63
  protected abstract readonly propNames: readonly string[];
@@ -103,6 +103,13 @@ export class ActivityIndicatorHost extends SymbiotePrimitiveHost {}
103
103
  })
104
104
  export class SafeAreaViewHost extends SymbiotePrimitiveHost {}
105
105
 
106
+ @Component({
107
+ selector: 'layout-conformance',
108
+ standalone: true,
109
+ template: '<ng-content></ng-content>',
110
+ })
111
+ export class LayoutConformanceHost extends SymbiotePrimitiveHost {}
112
+
106
113
  @Component({
107
114
  selector: 'modal',
108
115
  standalone: true,
@@ -11,7 +11,7 @@ import { Appearance, type IColorSchemeName } from '@symbiote-native/engine';
11
11
  */
12
12
  @Injectable({ providedIn: 'root' })
13
13
  export class ColorSchemeService {
14
- readonly colorScheme = signal<IColorSchemeName | null>(
14
+ readonly colorScheme = signal<IColorSchemeName | null | undefined>(
15
15
  Appearance.getColorScheme(),
16
16
  );
17
17
 
@@ -2,5 +2,6 @@ export { ColorSchemeService } from './color-scheme.service';
2
2
  export { WindowDimensionsService } from './window-dimensions.service';
3
3
  export { createResourceHook } from './create-resource-hook';
4
4
  export { createEventValueHook } from './create-event-value-hook';
5
+ export { injectEvent, injectEventListener } from './inject-event';
5
6
  export { connectWatchedSignal } from './connect-watched-signal';
6
7
  export { PermissionsServiceBase } from './permissions-service-base';
@@ -0,0 +1,52 @@
1
+ // Angular twins of `useEvent` and `useEventListener` of the `expo` package, for any emitter
2
+
3
+ import { effect, signal, untracked } from '@angular/core';
4
+ import type { Signal } from '@angular/core';
5
+ import { bindEventListener } from '@symbiote-native/engine';
6
+ import type {
7
+ IEventEmitterOf,
8
+ IEventName,
9
+ IEventPayload,
10
+ IEventsMap,
11
+ } from '@symbiote-native/engine';
12
+
13
+ /** Calls the listener for each event, the latest one, and stops with the injection context */
14
+ export function injectEventListener<
15
+ TEventsMap extends IEventsMap,
16
+ TName extends IEventName<TEventsMap>,
17
+ >(
18
+ emitter: () => IEventEmitterOf<TEventsMap>,
19
+ eventName: () => TName,
20
+ listener: () => TEventsMap[TName],
21
+ ): void {
22
+ effect(onCleanup => {
23
+ const source = emitter();
24
+ const name = eventName();
25
+ // The listener is read at each event, a new one is not a new subscription
26
+ onCleanup(bindEventListener(source, name, () => untracked(listener)));
27
+ });
28
+ }
29
+
30
+ /** The payload of the last event, `initialValue` (or `null`) until the first one */
31
+ export function injectEvent<
32
+ TEventsMap extends IEventsMap,
33
+ TName extends IEventName<TEventsMap>,
34
+ >(
35
+ emitter: () => IEventEmitterOf<TEventsMap>,
36
+ eventName: () => TName,
37
+ initialValue: IEventPayload<TEventsMap, TName> | null = null,
38
+ ): Signal<IEventPayload<TEventsMap, TName> | null> {
39
+ const event = signal<IEventPayload<TEventsMap, TName> | null>(initialValue);
40
+ effect(onCleanup => {
41
+ const source = emitter();
42
+ const name = eventName();
43
+ onCleanup(
44
+ bindEventListener(
45
+ source,
46
+ name,
47
+ () => (next: IEventPayload<TEventsMap, TName>) => event.set(next),
48
+ ),
49
+ );
50
+ });
51
+ return event.asReadonly();
52
+ }