@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
@@ -31,6 +31,7 @@ export const FLAT_LIST_TEMPLATE = `
31
31
  [maxToRenderPerBatch]="maxToRenderPerBatch"
32
32
  [updateCellsBatchingPeriod]="updateCellsBatchingPeriod"
33
33
  [windowSize]="windowSize"
34
+ [disableVirtualization]="disableVirtualization"
34
35
  [stickyHeaderIndices]="stickyHeaderIndices"
35
36
  [maintainVisibleContentPosition]="maintainVisibleContentPosition"
36
37
  [onScroll]="onScroll"
@@ -38,15 +39,21 @@ export const FLAT_LIST_TEMPLATE = `
38
39
  [onScrollEndDrag]="onScrollEndDrag"
39
40
  [onMomentumScrollBegin]="onMomentumScrollBegin"
40
41
  [onMomentumScrollEnd]="onMomentumScrollEnd"
42
+ [onContentSizeChange]="onContentSizeChange"
41
43
  [scrollEventThrottle]="scrollEventThrottle"
42
44
  [keyboardShouldPersistTaps]="keyboardShouldPersistTaps"
43
45
  [keyboardDismissMode]="keyboardDismissMode"
44
46
  [removeClippedSubviews]="resolvedRemoveClippedSubviews"
45
47
  [nestedScrollEnabled]="nestedScrollEnabled"
48
+ [stickyHeaderHiddenOnScroll]="stickyHeaderHiddenOnScroll"
49
+ [innerViewRef]="innerViewRef"
46
50
  [testID]="testID"
47
51
  [nativeID]="nativeID"
48
52
  [style]="resolvedStyle"
49
53
  [contentContainerStyle]="contentContainerStyle"
54
+ [listHeaderComponentStyle]="listHeaderComponentStyle"
55
+ [listFooterComponentStyle]="listFooterComponentStyle"
56
+ [cellRendererTemplate]="cellRendererTpl"
50
57
  ${LIST_ACCESSIBILITY_FORWARD}
51
58
  >
52
59
  <ng-template vListItem let-row let-separators="separators">
@@ -55,6 +62,7 @@ export const FLAT_LIST_TEMPLATE = `
55
62
  <view [style]="columnCellStyle">
56
63
  <ng-container
57
64
  [vListOutlet]="itemDir?.templateRef"
65
+ [vListOutletComponent]="itemComponent"
58
66
  [vListOutletContext]="cell.context"
59
67
  ></ng-container>
60
68
  </view>
@@ -119,6 +127,7 @@ export const FLAT_LIST_TEMPLATE = `
119
127
  [maxToRenderPerBatch]="maxToRenderPerBatch"
120
128
  [updateCellsBatchingPeriod]="updateCellsBatchingPeriod"
121
129
  [windowSize]="windowSize"
130
+ [disableVirtualization]="disableVirtualization"
122
131
  [stickyHeaderIndices]="stickyHeaderIndices"
123
132
  [maintainVisibleContentPosition]="maintainVisibleContentPosition"
124
133
  [onScroll]="onScroll"
@@ -126,16 +135,23 @@ export const FLAT_LIST_TEMPLATE = `
126
135
  [onScrollEndDrag]="onScrollEndDrag"
127
136
  [onMomentumScrollBegin]="onMomentumScrollBegin"
128
137
  [onMomentumScrollEnd]="onMomentumScrollEnd"
138
+ [onContentSizeChange]="onContentSizeChange"
129
139
  [scrollEventThrottle]="scrollEventThrottle"
130
140
  [keyboardShouldPersistTaps]="keyboardShouldPersistTaps"
131
141
  [keyboardDismissMode]="keyboardDismissMode"
132
142
  [removeClippedSubviews]="resolvedRemoveClippedSubviews"
133
143
  [nestedScrollEnabled]="nestedScrollEnabled"
144
+ [stickyHeaderHiddenOnScroll]="stickyHeaderHiddenOnScroll"
145
+ [innerViewRef]="innerViewRef"
134
146
  [testID]="testID"
135
147
  [nativeID]="nativeID"
136
148
  [style]="resolvedStyle"
137
149
  [contentContainerStyle]="contentContainerStyle"
150
+ [listHeaderComponentStyle]="listHeaderComponentStyle"
151
+ [listFooterComponentStyle]="listFooterComponentStyle"
152
+ [cellRendererTemplate]="cellRendererTpl"
138
153
  [itemTemplate]="itemDir?.templateRef"
154
+ [listItemComponent]="listItemComponent"
139
155
  [itemSeparatorTemplate]="separatorDir?.templateRef"
140
156
  ${LIST_ACCESSIBILITY_FORWARD}
141
157
  >
@@ -16,6 +16,7 @@ import {
16
16
  } from '@angular/core';
17
17
  import {
18
18
  SINGLE_COLUMN,
19
+ arrayLikeLength,
19
20
  chunkIntoRows,
20
21
  expandRowViewability,
21
22
  firstItemOfRow,
@@ -23,7 +24,6 @@ import {
23
24
  removeClippedSubviewsOrDefault,
24
25
  rowKeyExtractor,
25
26
  type IRow,
26
- type IScrollViewHandle,
27
27
  type ISeparators,
28
28
  type IViewabilityConfigCallbackPair,
29
29
  type IViewableItemsChangedInfo,
@@ -35,7 +35,6 @@ import {
35
35
  flattenStyle,
36
36
  resolveClassName,
37
37
  type IStyleProp,
38
- type ISymbioteNode,
39
38
  type IViewStyle,
40
39
  } from '@symbiote-native/engine';
41
40
  import {
@@ -50,7 +49,7 @@ import {
50
49
  type IVListSeparatorContext,
51
50
  } from '../virtualized-list';
52
51
  import { VListOutletDirective } from '../virtualized-list/directives';
53
- import { ListInputsBase } from '../virtualized-list/list-inputs';
52
+ import { FlatListHandleBase } from './flat-list-handle';
54
53
  import { provideGateDemand } from '../../gate-demand';
55
54
  import {
56
55
  stableAnchorStyle,
@@ -151,7 +150,7 @@ export type IFlatListInputs<ItemT> = Omit<
151
150
  template: FLAT_LIST_TEMPLATE,
152
151
  })
153
152
  export class FlatList<ItemT = unknown>
154
- extends ListInputsBase<ItemT>
153
+ extends FlatListHandleBase<ItemT>
155
154
  implements IFlatListInputs<ItemT>, IVirtualizedListHandle, DoCheck, OnChanges
156
155
  {
157
156
  @Input({ required: true }) data!: readonly ItemT[];
@@ -166,8 +165,7 @@ export class FlatList<ItemT = unknown>
166
165
  );
167
166
  }
168
167
 
169
- // The composed inner list, whichever branch rendered, its instance is the scroll handle
170
- @ViewChild(VirtualizedList) private listRef?: VirtualizedList;
168
+ @ViewChild(VirtualizedList) protected override listRef?: VirtualizedList;
171
169
 
172
170
  // This component's own host, the anchor `class="..."` resolves onto, not the inner list's
173
171
  private readonly elementRef = inject(ElementRef);
@@ -213,7 +211,7 @@ export class FlatList<ItemT = unknown>
213
211
  ? chunkIntoRows(this.data, this.columns)
214
212
  : [];
215
213
  dlog(
216
- `Angular FlatList over ${this.data?.length ?? 0} items, ${this.columns} column(s)`,
214
+ `Angular FlatList over ${arrayLikeLength(this.data)} items, ${this.columns} column(s)`,
217
215
  );
218
216
  }
219
217
  if (
@@ -225,7 +223,7 @@ export class FlatList<ItemT = unknown>
225
223
  }
226
224
 
227
225
  getFlatItem = (_data: unknown, index: number): ItemT => this.data[index];
228
- getFlatCount = (_data: unknown): number => this.data.length;
226
+ getFlatCount = (_data: unknown): number => arrayLikeLength(this.data);
229
227
 
230
228
  // With several columns the virtualized stream is rows
231
229
  getRow = (_data: unknown, index: number): IRow<ItemT> => this.rows[index];
@@ -291,44 +289,4 @@ export class FlatList<ItemT = unknown>
291
289
  : undefined,
292
290
  };
293
291
  }
294
-
295
- scrollToOffset(params: { offset: number; animated?: boolean }): void {
296
- this.listRef?.scrollToOffset(params);
297
- }
298
- scrollToIndex(params: {
299
- index: number;
300
- animated?: boolean;
301
- viewOffset?: number;
302
- viewPosition?: number;
303
- }): void {
304
- this.listRef?.scrollToIndex(params);
305
- }
306
- scrollToItem(params: {
307
- item: unknown;
308
- animated?: boolean;
309
- viewPosition?: number;
310
- }): void {
311
- this.listRef?.scrollToItem(params);
312
- }
313
- scrollToEnd(params?: { animated?: boolean }): void {
314
- this.listRef?.scrollToEnd(params);
315
- }
316
- flashScrollIndicators(): void {
317
- this.listRef?.flashScrollIndicators();
318
- }
319
- getNativeScrollRef(): IScrollViewHandle | null {
320
- return this.listRef?.getNativeScrollRef() ?? null;
321
- }
322
- getScrollableNode(): IScrollViewHandle | null {
323
- return this.listRef?.getScrollableNode() ?? null;
324
- }
325
- getScrollResponder(): IScrollViewHandle | null {
326
- return this.listRef?.getScrollResponder() ?? null;
327
- }
328
- getScrollNode(): ISymbioteNode | null {
329
- return this.listRef?.getScrollNode() ?? null;
330
- }
331
- recordInteraction(): void {
332
- this.listRef?.recordInteraction();
333
- }
334
292
  }
@@ -0,0 +1,94 @@
1
+ // The input and output names of `Animated.Image`, kept apart from the prop fold so the list reads
2
+ // as one table
3
+
4
+ export const IMAGE_INPUTS = [
5
+ 'source',
6
+ 'defaultSource',
7
+ 'loadingIndicatorSource',
8
+ 'style',
9
+ 'resizeMode',
10
+ 'resizeMethod',
11
+ 'resizeMultiplier',
12
+ 'tintColor',
13
+ 'blurRadius',
14
+ 'capInsets',
15
+ 'fadeDuration',
16
+ 'progressiveRenderingEnabled',
17
+ 'src',
18
+ 'srcSet',
19
+ 'alt',
20
+ 'width',
21
+ 'height',
22
+ 'crossOrigin',
23
+ 'referrerPolicy',
24
+ 'testID',
25
+ 'nativeID',
26
+ 'accessible',
27
+ 'accessibilityLabel',
28
+ 'accessibilityHint',
29
+ 'accessibilityRole',
30
+ 'accessibilityState',
31
+ 'accessibilityValue',
32
+ 'accessibilityActions',
33
+ 'accessibilityLabelledBy',
34
+ 'importantForAccessibility',
35
+ 'accessibilityLiveRegion',
36
+ 'screenReaderFocusable',
37
+ 'accessibilityViewIsModal',
38
+ 'accessibilityElementsHidden',
39
+ 'accessibilityIgnoresInvertColors',
40
+ 'accessibilityLanguage',
41
+ 'accessibilityRespondsToUserInteraction',
42
+ 'accessibilityShowsLargeContentViewer',
43
+ 'accessibilityLargeContentTitle',
44
+ 'role',
45
+ 'ariaLabel: aria-label',
46
+ 'ariaLabelledBy: aria-labelledby',
47
+ 'ariaLive: aria-live',
48
+ 'ariaHidden: aria-hidden',
49
+ 'ariaBusy: aria-busy',
50
+ 'ariaChecked: aria-checked',
51
+ 'ariaDisabled: aria-disabled',
52
+ 'ariaExpanded: aria-expanded',
53
+ 'ariaSelected: aria-selected',
54
+ 'ariaModal: aria-modal',
55
+ 'ariaValueMax: aria-valuemax',
56
+ 'ariaValueMin: aria-valuemin',
57
+ 'ariaValueNow: aria-valuenow',
58
+ 'ariaValueText: aria-valuetext',
59
+ 'onAccessibilityAction',
60
+ 'onAccessibilityTap',
61
+ 'onMagicTap',
62
+ 'onAccessibilityEscape',
63
+ 'onLoadStart',
64
+ 'onLoad',
65
+ 'onLoadEnd',
66
+ 'onError',
67
+ 'onProgress',
68
+ 'onPartialLoad',
69
+ ];
70
+
71
+ type IImageOutput =
72
+ | 'accessibilityAction'
73
+ | 'accessibilityTap'
74
+ | 'magicTap'
75
+ | 'accessibilityEscape'
76
+ | 'loadStart'
77
+ | 'load'
78
+ | 'loadEnd'
79
+ | 'error'
80
+ | 'progress'
81
+ | 'partialLoad';
82
+
83
+ export const IMAGE_OUTPUTS: IImageOutput[] = [
84
+ 'accessibilityAction',
85
+ 'accessibilityTap',
86
+ 'magicTap',
87
+ 'accessibilityEscape',
88
+ 'loadStart',
89
+ 'load',
90
+ 'loadEnd',
91
+ 'error',
92
+ 'progress',
93
+ 'partialLoad',
94
+ ];
@@ -0,0 +1,172 @@
1
+ // Narrows the untyped `Animated.Image` input bag into the props `renderImage` takes
2
+ import {
3
+ renderImage,
4
+ resolveAccessibilityProps,
5
+ type IImageSourceProp,
6
+ type IResizeMode,
7
+ } from '@symbiote-native/components';
8
+ import {
9
+ isBoolean,
10
+ isNumber,
11
+ isProcessableColor,
12
+ isString,
13
+ type IStyleProp,
14
+ type ISymbioteEvent,
15
+ type IViewStyle,
16
+ } from '@symbiote-native/engine';
17
+
18
+ type IGuard = (value: unknown) => boolean;
19
+
20
+ function isAny(): boolean {
21
+ return true;
22
+ }
23
+
24
+ // Input key -> the guard its value must pass. A union, object or handler is checked by Angular's
25
+ // template type check, so it gets `isAny` and goes through as it came
26
+ const PASSTHROUGH_GUARDS: Readonly<Record<string, IGuard>> = {
27
+ resizeMethod: isAny,
28
+ resizeMultiplier: isNumber,
29
+ blurRadius: isNumber,
30
+ capInsets: isAny,
31
+ fadeDuration: isNumber,
32
+ progressiveRenderingEnabled: isBoolean,
33
+ testID: isString,
34
+ nativeID: isString,
35
+ accessible: isBoolean,
36
+ accessibilityLabel: isString,
37
+ accessibilityHint: isString,
38
+ accessibilityRole: isAny,
39
+ accessibilityState: isAny,
40
+ accessibilityValue: isAny,
41
+ accessibilityActions: isAny,
42
+ accessibilityLabelledBy: isAny,
43
+ importantForAccessibility: isAny,
44
+ accessibilityLiveRegion: isAny,
45
+ screenReaderFocusable: isBoolean,
46
+ accessibilityViewIsModal: isBoolean,
47
+ accessibilityElementsHidden: isBoolean,
48
+ accessibilityIgnoresInvertColors: isBoolean,
49
+ accessibilityLanguage: isString,
50
+ accessibilityRespondsToUserInteraction: isBoolean,
51
+ accessibilityShowsLargeContentViewer: isBoolean,
52
+ accessibilityLargeContentTitle: isString,
53
+ role: isAny,
54
+ ariaLabel: isString,
55
+ ariaLabelledBy: isString,
56
+ ariaLive: isAny,
57
+ ariaHidden: isBoolean,
58
+ ariaBusy: isBoolean,
59
+ ariaChecked: isAny,
60
+ ariaDisabled: isBoolean,
61
+ ariaExpanded: isBoolean,
62
+ ariaSelected: isBoolean,
63
+ ariaModal: isBoolean,
64
+ ariaValueMax: isNumber,
65
+ ariaValueMin: isNumber,
66
+ ariaValueNow: isNumber,
67
+ ariaValueText: isString,
68
+ onAccessibilityAction: isAny,
69
+ onAccessibilityTap: isAny,
70
+ onMagicTap: isAny,
71
+ onAccessibilityEscape: isAny,
72
+ onLoadStart: isAny,
73
+ onLoad: isAny,
74
+ onLoadEnd: isAny,
75
+ onError: isAny,
76
+ onProgress: isAny,
77
+ onPartialLoad: isAny,
78
+ };
79
+
80
+ // The name a template binds -> the `aria-*` prop RN spells
81
+ const ARIA_PROP_NAMES: Readonly<Record<string, string>> = {
82
+ ariaLabel: 'aria-label',
83
+ ariaLabelledBy: 'aria-labelledby',
84
+ ariaLive: 'aria-live',
85
+ ariaHidden: 'aria-hidden',
86
+ ariaBusy: 'aria-busy',
87
+ ariaChecked: 'aria-checked',
88
+ ariaDisabled: 'aria-disabled',
89
+ ariaExpanded: 'aria-expanded',
90
+ ariaSelected: 'aria-selected',
91
+ ariaModal: 'aria-modal',
92
+ ariaValueMax: 'aria-valuemax',
93
+ ariaValueMin: 'aria-valuemin',
94
+ ariaValueNow: 'aria-valuenow',
95
+ ariaValueText: 'aria-valuetext',
96
+ };
97
+
98
+ const RESIZE_MODES = [
99
+ 'cover',
100
+ 'contain',
101
+ 'stretch',
102
+ 'repeat',
103
+ 'center',
104
+ 'none',
105
+ ] as const satisfies readonly IResizeMode[];
106
+
107
+ function narrowTo<T>(
108
+ value: unknown,
109
+ guard: (candidate: unknown) => candidate is T,
110
+ ): T | undefined {
111
+ return guard(value) ? value : undefined;
112
+ }
113
+
114
+ function isSource(value: unknown): value is IImageSourceProp {
115
+ return (
116
+ typeof value === 'number' || (typeof value === 'object' && value !== null)
117
+ );
118
+ }
119
+
120
+ function isStyle(value: unknown): value is IStyleProp<IViewStyle> {
121
+ return typeof value === 'object' && value !== null;
122
+ }
123
+
124
+ function isCrossOrigin(
125
+ value: unknown,
126
+ ): value is 'anonymous' | 'use-credentials' {
127
+ return value === 'anonymous' || value === 'use-credentials';
128
+ }
129
+
130
+ export function isImageEventCallback(
131
+ value: unknown,
132
+ ): value is (event: ISymbioteEvent) => void {
133
+ return typeof value === 'function';
134
+ }
135
+
136
+ // An animated bag may carry the RN `aria-*` spelling instead of the name a template binds
137
+ function inputValue(input: Record<string, unknown>, key: string): unknown {
138
+ const rnName = ARIA_PROP_NAMES[key];
139
+ return input[key] ?? (rnName === undefined ? undefined : input[rnName]);
140
+ }
141
+
142
+ function passthroughOf(
143
+ input: Record<string, unknown>,
144
+ ): Record<string, unknown> {
145
+ const passthrough: Record<string, unknown> = {};
146
+ for (const [key, guard] of Object.entries(PASSTHROUGH_GUARDS)) {
147
+ const value = inputValue(input, key);
148
+ passthrough[ARIA_PROP_NAMES[key] ?? key] = guard(value) ? value : undefined;
149
+ }
150
+ return passthrough;
151
+ }
152
+
153
+ export function resolveImageProps(
154
+ input: Record<string, unknown>,
155
+ ): Record<string, unknown> {
156
+ return renderImage({
157
+ source: narrowTo(input['source'], isSource),
158
+ defaultSource: narrowTo(input['defaultSource'], isSource),
159
+ loadingIndicatorSource: narrowTo(input['loadingIndicatorSource'], isSource),
160
+ style: narrowTo(input['style'], isStyle),
161
+ resizeMode: RESIZE_MODES.find(mode => mode === input['resizeMode']),
162
+ tintColor: narrowTo(input['tintColor'], isProcessableColor),
163
+ src: narrowTo(input['src'], isString),
164
+ srcSet: narrowTo(input['srcSet'], isString),
165
+ alt: narrowTo(input['alt'], isString),
166
+ width: narrowTo(input['width'], isNumber),
167
+ height: narrowTo(input['height'], isNumber),
168
+ crossOrigin: narrowTo(input['crossOrigin'], isCrossOrigin),
169
+ referrerPolicy: narrowTo(input['referrerPolicy'], isString),
170
+ passthrough: resolveAccessibilityProps(passthroughOf(input)),
171
+ }).props;
172
+ }