@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
@@ -1,7 +1,83 @@
1
- // Same body on both axes, only the outer tag differs
2
- // Written out once per branch: ngc needs one literal, no shared outlet primitive exists
1
+ // Same body on both axes and in the nested view, only the outer tag differs
2
+ // Written out once per branch: ngc needs one literal, and a shared outlet would add one per list
3
3
  export const VIRTUALIZED_LIST_TEMPLATE = `
4
- @if (isHorizontal) {
4
+ @if (nesting.isNested) {
5
+ <view #scrollHost [symbioteHostProps]="nestedViewBag()">
6
+ @if (headerDir !== undefined) {
7
+ <view [style]="headerStyle">
8
+ <ng-container [vListOutlet]="headerDir.templateRef"></ng-container>
9
+ </view>
10
+ }
11
+
12
+ @if (itemCount === 0) {
13
+ @if (emptyDir !== undefined) {
14
+ <view [style]="cellStyle">
15
+ <ng-container [vListOutlet]="emptyDir.templateRef"></ng-container>
16
+ </view>
17
+ }
18
+ } @else {
19
+ @for (row of rows; track row.key) {
20
+ @if (row.kind === spacerKind) {
21
+ <view [style]="row.style"></view>
22
+ } @else if (row.renderer !== undefined) {
23
+ @if (row.cell.isSticky) {
24
+ <sticky-header>
25
+ <ng-container
26
+ [vListOutlet]="cellRendererTpl"
27
+ [vListOutletContext]="row.renderer"
28
+ ></ng-container>
29
+ </sticky-header>
30
+ } @else {
31
+ <ng-container
32
+ [vListOutlet]="cellRendererTpl"
33
+ [vListOutletContext]="row.renderer"
34
+ ></ng-container>
35
+ }
36
+ } @else if (row.cell.isSticky) {
37
+ <sticky-header
38
+ (layout)="handleCellLayout(row.cell.measure, $event, row.cell.index)"
39
+ (focus)="handleCellFocus(row.cell.index)"
40
+ [style]="cellStyle"
41
+ >
42
+ <ng-container
43
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
44
+ [vListOutletContext]="row.cell.context"
45
+ ></ng-container>
46
+ @if (row.cell.separatorContext !== undefined) {
47
+ <ng-container
48
+ [vListOutlet]="separatorTemplate"
49
+ [vListOutletContext]="row.cell.separatorContext"
50
+ ></ng-container>
51
+ }
52
+ </sticky-header>
53
+ } @else {
54
+ <view
55
+ (layout)="handleCellLayout(row.cell.measure, $event, row.cell.index)"
56
+ (focus)="handleCellFocus(row.cell.index)"
57
+ [style]="cellStyle"
58
+ >
59
+ <ng-container
60
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
61
+ [vListOutletContext]="row.cell.context"
62
+ ></ng-container>
63
+ @if (row.cell.separatorContext !== undefined) {
64
+ <ng-container
65
+ [vListOutlet]="separatorTemplate"
66
+ [vListOutletContext]="row.cell.separatorContext"
67
+ ></ng-container>
68
+ }
69
+ </view>
70
+ }
71
+ }
72
+ }
73
+
74
+ @if (footerDir !== undefined) {
75
+ <view [style]="footerStyle">
76
+ <ng-container [vListOutlet]="footerDir.templateRef"></ng-container>
77
+ </view>
78
+ }
79
+ </view>
80
+ } @else if (isHorizontal) {
5
81
  <horizontal-scroll-view #scrollHost [symbioteHostProps]="scrollViewBag()">
6
82
  @if (shouldRenderRefreshControl) {
7
83
  <refresh-control
@@ -10,77 +86,75 @@ export const VIRTUALIZED_LIST_TEMPLATE = `
10
86
  }
11
87
 
12
88
  @if (headerDir !== undefined) {
13
- <view>
89
+ <view [style]="headerStyle">
14
90
  <ng-container [vListOutlet]="headerDir.templateRef"></ng-container>
15
91
  </view>
16
92
  }
17
93
 
18
94
  @if (itemCount === 0) {
19
95
  @if (emptyDir !== undefined) {
20
- <view>
96
+ <view [style]="cellStyle">
21
97
  <ng-container [vListOutlet]="emptyDir.templateRef"></ng-container>
22
98
  </view>
23
99
  }
24
100
  } @else {
25
- @if (leadingSpacerStyle !== null) {
26
- <view [style]="leadingSpacerStyle"></view>
27
- }
28
- @if (forcedStickyCell !== null) {
29
- <sticky-header
30
- (layout)="handleCellLayout(forcedStickyCell.measure, $event)"
31
- [style]="cellStyle"
32
- >
33
- <ng-container
34
- [vListOutlet]="cellTemplate"
35
- [vListOutletContext]="forcedStickyCell.context"
36
- ></ng-container>
37
- </sticky-header>
38
- }
39
- @if (gapSpacerStyle !== null) {
40
- <view [style]="gapSpacerStyle"></view>
41
- }
42
- @for (cell of windowCells; track cell.key) {
43
- @if (cell.isSticky) {
101
+ @for (row of rows; track row.key) {
102
+ @if (row.kind === spacerKind) {
103
+ <view [style]="row.style"></view>
104
+ } @else if (row.renderer !== undefined) {
105
+ @if (row.cell.isSticky) {
106
+ <sticky-header>
107
+ <ng-container
108
+ [vListOutlet]="cellRendererTpl"
109
+ [vListOutletContext]="row.renderer"
110
+ ></ng-container>
111
+ </sticky-header>
112
+ } @else {
113
+ <ng-container
114
+ [vListOutlet]="cellRendererTpl"
115
+ [vListOutletContext]="row.renderer"
116
+ ></ng-container>
117
+ }
118
+ } @else if (row.cell.isSticky) {
44
119
  <sticky-header
45
- (layout)="handleCellLayout(cell.measure, $event)"
120
+ (layout)="handleCellLayout(row.cell.measure, $event, row.cell.index)"
121
+ (focus)="handleCellFocus(row.cell.index)"
46
122
  [style]="cellStyle"
47
123
  >
48
124
  <ng-container
49
- [vListOutlet]="cellTemplate"
50
- [vListOutletContext]="cell.context"
125
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
126
+ [vListOutletContext]="row.cell.context"
51
127
  ></ng-container>
52
- @if (cell.separatorContext !== undefined) {
128
+ @if (row.cell.separatorContext !== undefined) {
53
129
  <ng-container
54
130
  [vListOutlet]="separatorTemplate"
55
- [vListOutletContext]="cell.separatorContext"
131
+ [vListOutletContext]="row.cell.separatorContext"
56
132
  ></ng-container>
57
133
  }
58
134
  </sticky-header>
59
135
  } @else {
60
136
  <view
61
- (layout)="handleCellLayout(cell.measure, $event)"
137
+ (layout)="handleCellLayout(row.cell.measure, $event, row.cell.index)"
138
+ (focus)="handleCellFocus(row.cell.index)"
62
139
  [style]="cellStyle"
63
140
  >
64
141
  <ng-container
65
- [vListOutlet]="cellTemplate"
66
- [vListOutletContext]="cell.context"
142
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
143
+ [vListOutletContext]="row.cell.context"
67
144
  ></ng-container>
68
- @if (cell.separatorContext !== undefined) {
145
+ @if (row.cell.separatorContext !== undefined) {
69
146
  <ng-container
70
147
  [vListOutlet]="separatorTemplate"
71
- [vListOutletContext]="cell.separatorContext"
148
+ [vListOutletContext]="row.cell.separatorContext"
72
149
  ></ng-container>
73
150
  }
74
151
  </view>
75
152
  }
76
153
  }
77
- @if (trailingSpacerStyle !== null) {
78
- <view [style]="trailingSpacerStyle"></view>
79
- }
80
154
  }
81
155
 
82
156
  @if (footerDir !== undefined) {
83
- <view>
157
+ <view [style]="footerStyle">
84
158
  <ng-container [vListOutlet]="footerDir.templateRef"></ng-container>
85
159
  </view>
86
160
  }
@@ -94,82 +168,94 @@ export const VIRTUALIZED_LIST_TEMPLATE = `
94
168
  }
95
169
 
96
170
  @if (headerDir !== undefined) {
97
- <view>
171
+ <view [style]="headerStyle">
98
172
  <ng-container [vListOutlet]="headerDir.templateRef"></ng-container>
99
173
  </view>
100
174
  }
101
175
 
102
176
  @if (itemCount === 0) {
103
177
  @if (emptyDir !== undefined) {
104
- <view>
178
+ <view [style]="cellStyle">
105
179
  <ng-container [vListOutlet]="emptyDir.templateRef"></ng-container>
106
180
  </view>
107
181
  }
108
182
  } @else {
109
- @if (leadingSpacerStyle !== null) {
110
- <view [style]="leadingSpacerStyle"></view>
111
- }
112
- @if (forcedStickyCell !== null) {
113
- <sticky-header
114
- (layout)="handleCellLayout(forcedStickyCell.measure, $event)"
115
- [style]="cellStyle"
116
- >
117
- <ng-container
118
- [vListOutlet]="cellTemplate"
119
- [vListOutletContext]="forcedStickyCell.context"
120
- ></ng-container>
121
- </sticky-header>
122
- }
123
- @if (gapSpacerStyle !== null) {
124
- <view [style]="gapSpacerStyle"></view>
125
- }
126
183
  <!-- The separator sits INSIDE the measuring view, matching RN's cell renderer, as a
127
184
  sibling it would add an extra flex gap -->
128
- @for (cell of windowCells; track cell.key) {
129
- @if (cell.isSticky) {
185
+ @for (row of rows; track row.key) {
186
+ @if (row.kind === spacerKind) {
187
+ <view [style]="row.style"></view>
188
+ } @else if (row.renderer !== undefined) {
189
+ @if (row.cell.isSticky) {
190
+ <sticky-header>
191
+ <ng-container
192
+ [vListOutlet]="cellRendererTpl"
193
+ [vListOutletContext]="row.renderer"
194
+ ></ng-container>
195
+ </sticky-header>
196
+ } @else {
197
+ <ng-container
198
+ [vListOutlet]="cellRendererTpl"
199
+ [vListOutletContext]="row.renderer"
200
+ ></ng-container>
201
+ }
202
+ } @else if (row.cell.isSticky) {
130
203
  <sticky-header
131
- (layout)="handleCellLayout(cell.measure, $event)"
204
+ (layout)="handleCellLayout(row.cell.measure, $event, row.cell.index)"
205
+ (focus)="handleCellFocus(row.cell.index)"
132
206
  [style]="cellStyle"
133
207
  >
134
208
  <ng-container
135
- [vListOutlet]="cellTemplate"
136
- [vListOutletContext]="cell.context"
209
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
210
+ [vListOutletContext]="row.cell.context"
137
211
  ></ng-container>
138
- @if (cell.separatorContext !== undefined) {
212
+ @if (row.cell.separatorContext !== undefined) {
139
213
  <ng-container
140
214
  [vListOutlet]="separatorTemplate"
141
- [vListOutletContext]="cell.separatorContext"
215
+ [vListOutletContext]="row.cell.separatorContext"
142
216
  ></ng-container>
143
217
  }
144
218
  </sticky-header>
145
219
  } @else {
146
220
  <view
147
- (layout)="handleCellLayout(cell.measure, $event)"
221
+ (layout)="handleCellLayout(row.cell.measure, $event, row.cell.index)"
222
+ (focus)="handleCellFocus(row.cell.index)"
148
223
  [style]="cellStyle"
149
224
  >
150
225
  <ng-container
151
- [vListOutlet]="cellTemplate"
152
- [vListOutletContext]="cell.context"
226
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
227
+ [vListOutletContext]="row.cell.context"
153
228
  ></ng-container>
154
- @if (cell.separatorContext !== undefined) {
229
+ @if (row.cell.separatorContext !== undefined) {
155
230
  <ng-container
156
231
  [vListOutlet]="separatorTemplate"
157
- [vListOutletContext]="cell.separatorContext"
232
+ [vListOutletContext]="row.cell.separatorContext"
158
233
  ></ng-container>
159
234
  }
160
235
  </view>
161
236
  }
162
237
  }
163
- @if (trailingSpacerStyle !== null) {
164
- <view [style]="trailingSpacerStyle"></view>
165
- }
166
238
  }
167
239
 
168
240
  @if (footerDir !== undefined) {
169
- <view>
241
+ <view [style]="footerStyle">
170
242
  <ng-container [vListOutlet]="footerDir.templateRef"></ng-container>
171
243
  </view>
172
244
  }
173
245
  </scroll-view>
174
246
  }
247
+
248
+ <!-- What a \`vListCell\` wrapper stamps for its item and separator, once per list -->
249
+ <ng-template #cellBody let-cell>
250
+ <ng-container
251
+ [vListOutlet]="cellTemplate" [vListOutletComponent]="itemComponent"
252
+ [vListOutletContext]="cell.context"
253
+ ></ng-container>
254
+ @if (cell.separatorContext !== undefined) {
255
+ <ng-container
256
+ [vListOutlet]="separatorTemplate"
257
+ [vListOutletContext]="cell.separatorContext"
258
+ ></ng-container>
259
+ }
260
+ </ng-template>
175
261
  `;
@@ -0,0 +1,22 @@
1
+ // The scope a list hands down to the lists nested in its cells, Angular's way to carry it
2
+ // What it holds and how it behaves is `createListNesting` in the shared components package
3
+
4
+ import { inject } from '@angular/core';
5
+ import type { IListScope } from '@symbiote-native/components';
6
+
7
+ // A list provides itself under this token, a cell declared inside it injects the nearest one
8
+ export abstract class ListScopeProvider {
9
+ abstract readonly listScope: IListScope | null;
10
+ }
11
+
12
+ // A portal-like component (Modal) provides this, its content sits outside the list's scroll
13
+ export const NO_LIST_SCOPE: ListScopeProvider = { listScope: null };
14
+
15
+ // Null outside every list, the scope of the nearest list above otherwise
16
+ export function injectVirtualizedListScope(): IListScope | null {
17
+ const provider = inject(ListScopeProvider, {
18
+ skipSelf: true,
19
+ optional: true,
20
+ });
21
+ return provider?.listScope ?? null;
22
+ }
@@ -1,49 +1,43 @@
1
- // VirtualizedSectionList authoring directives: the Angular-faithful equivalent of React/Vue's
2
- // `renderItem` / `renderSectionHeader` / `renderSectionFooter` / `SectionSeparatorComponent`.
3
- // React/Vue pass element-returning callbacks; that does NOT translate to Angular, where per-cell
4
- // content is a TEMPLATE. So the app supplies each section slot as an `<ng-template>` carrying one
5
- // of these structural directives, and VirtualizedSectionList stamps the windowed slice through
6
- // them. The shared flatten/window surface stays in @symbiote-native/components, only the cell-AUTHORING shape is
7
- // framework-specific. SectionList (the next layer) reuses these same directives verbatim.
8
- //
9
- // Authoring API (what the app imports and what SectionList builds on):
10
- // <VirtualizedSectionList [sections]="sections">
11
- // <ng-template vSectionItem let-item let-index="index" let-section="section" let-separators="separators"> … </ng-template>
12
- // <ng-template vSectionHeader let-section> … </ng-template>
13
- // <ng-template vSectionFooter let-section> … </ng-template>
14
- // <ng-template vSectionSeparator> … </ng-template> <!-- between adjacent sections -->
15
- // <!-- list-level slots reuse VirtualizedList's own directives: -->
16
- // <ng-template vListHeader> … </ng-template>
17
- // <ng-template vListFooter> … </ng-template>
18
- // <ng-template vListEmpty> … </ng-template>
19
- // <ng-template vListSeparator let-highlighted let-leadingItem="leadingItem"> … </ng-template> <!-- between items -->
20
- // </VirtualizedSectionList>
21
- //
22
- // Each directive carries a static ngTemplateContextGuard so the `let-` bindings infer at the call
23
- // site (the Angular twin of renderItem / renderSectionHeader's typed info arg).
1
+ // Section list slots are `<ng-template>`s carrying these directives, the list stamps the window
2
+ // through them. Each has a context guard so the `let-` bindings infer at the call site
24
3
 
25
4
  import { Directive, TemplateRef, inject } from '@angular/core';
26
- import type { ISection, ISeparators } from '@symbiote-native/components';
5
+ import type {
6
+ ISection as ICoreSection,
7
+ ISeparators,
8
+ } from '@symbiote-native/components';
9
+ import type { IVListSeparatorContext } from '../virtualized-list';
27
10
 
28
- // The context a `vSectionItem` template receives, mirroring RN's section renderItem info arg
29
- // ({ item, index, section, separators }). `$implicit` is the item, so `let-item` (no key) binds it.
30
- export interface IVSectionItemContext<ItemT> {
11
+ // A section may bring its own `item` and `separator` templates, which beat the list's
12
+ export type ISection<ItemT> = ICoreSection<ItemT> & {
13
+ item?: TemplateRef<IVSectionItemContext<ItemT>>;
14
+ separator?: TemplateRef<IVListSeparatorContext<ItemT>>;
15
+ };
16
+
17
+ // The `renderItem` info arg of RN, `$implicit` is the item so `let-item` binds it
18
+ export type IVSectionItemContext<ItemT> = {
31
19
  $implicit: ItemT;
32
20
  item: ItemT;
33
21
  index: number;
34
22
  section: ISection<ItemT>;
35
23
  separators: ISeparators;
36
- }
24
+ };
37
25
 
38
- // The context a `vSectionHeader` / `vSectionFooter` template receives (RN's renderSectionHeader /
39
- // renderSectionFooter info arg, { section }). `$implicit` is the section, so `let-section` (no key)
40
- // binds it.
41
- export interface IVSectionContext<ItemT> {
26
+ // The `renderSectionHeader` and `renderSectionFooter` info arg, `$implicit` is the section
27
+ export type IVSectionContext<ItemT> = {
42
28
  $implicit: ISection<ItemT>;
43
29
  section: ISection<ItemT>;
44
- }
30
+ };
31
+
32
+ // RN's separator props around a section edge, `props` is the same bag whole so a forwarding
33
+ // layer can pass it on without naming every key
34
+ export type IVSectionSeparatorContext<ItemT> = IVListSeparatorContext<ItemT> & {
35
+ section?: ISection<ItemT>;
36
+ leadingSection?: ISection<ItemT>;
37
+ trailingSection?: ISection<ItemT>;
38
+ props?: IVListSeparatorContext<ItemT>;
39
+ };
45
40
 
46
- // `<ng-template vSectionItem>` — one section item row. The static guard types the `let-` bindings.
47
41
  @Directive({ selector: '[vSectionItem]', standalone: true })
48
42
  export class VSectionItemDirective<ItemT = unknown> {
49
43
  readonly templateRef =
@@ -57,7 +51,7 @@ export class VSectionItemDirective<ItemT = unknown> {
57
51
  }
58
52
  }
59
53
 
60
- // `<ng-template vSectionHeader>` — rendered above each section's items (RN renderSectionHeader).
54
+ // Rendered above each section's items, RN's `renderSectionHeader`
61
55
  @Directive({ selector: '[vSectionHeader]', standalone: true })
62
56
  export class VSectionHeaderDirective<ItemT = unknown> {
63
57
  readonly templateRef =
@@ -71,7 +65,7 @@ export class VSectionHeaderDirective<ItemT = unknown> {
71
65
  }
72
66
  }
73
67
 
74
- // `<ng-template vSectionFooter>` — rendered below each section's items (RN renderSectionFooter).
68
+ // Rendered below each section's items, RN's `renderSectionFooter`
75
69
  @Directive({ selector: '[vSectionFooter]', standalone: true })
76
70
  export class VSectionFooterDirective<ItemT = unknown> {
77
71
  readonly templateRef =
@@ -85,9 +79,16 @@ export class VSectionFooterDirective<ItemT = unknown> {
85
79
  }
86
80
  }
87
81
 
88
- // `<ng-template vSectionSeparator>` — painted between adjacent sections (after one section's footer,
89
- // before the next section's header). Mirrors RN's SectionSeparatorComponent; carries no context.
82
+ // Painted before a section's first item and after its last, RN's `SectionSeparatorComponent`
90
83
  @Directive({ selector: '[vSectionSeparator]', standalone: true })
91
- export class VSectionSeparatorDirective {
92
- readonly templateRef = inject(TemplateRef);
84
+ export class VSectionSeparatorDirective<ItemT = unknown> {
85
+ readonly templateRef =
86
+ inject<TemplateRef<IVSectionSeparatorContext<ItemT>>>(TemplateRef);
87
+
88
+ static ngTemplateContextGuard<T>(
89
+ _dir: VSectionSeparatorDirective<T>,
90
+ _ctx: unknown,
91
+ ): _ctx is IVSectionSeparatorContext<T> {
92
+ return true;
93
+ }
93
94
  }