@symbiote-native/angular 3.3.0 → 3.5.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 (187) hide show
  1. package/babel-register-composed.cjs +1 -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/flat-list/flat-list-handle.d.ts +35 -0
  9. package/build/angular/components/flat-list/flat-list-handle.js +48 -0
  10. package/build/angular/components/flat-list/flat-list-handle.js.map +1 -0
  11. package/build/angular/components/flat-list/flat-list-template.d.ts +1 -1
  12. package/build/angular/components/flat-list/flat-list-template.js +16 -0
  13. package/build/angular/components/flat-list/flat-list-template.js.map +1 -1
  14. package/build/angular/components/flat-list/index.d.ts +6 -30
  15. package/build/angular/components/flat-list/index.js +6 -36
  16. package/build/angular/components/flat-list/index.js.map +1 -1
  17. package/build/angular/components/image-inputs.d.ts +4 -0
  18. package/build/angular/components/image-inputs.js +81 -0
  19. package/build/angular/components/image-inputs.js.map +1 -0
  20. package/build/angular/components/image-props-resolve.d.ts +3 -0
  21. package/build/angular/components/image-props-resolve.js +133 -0
  22. package/build/angular/components/image-props-resolve.js.map +1 -0
  23. package/build/angular/components/image-shared.d.ts +8 -6
  24. package/build/angular/components/image-shared.js +23 -212
  25. package/build/angular/components/image-shared.js.map +1 -1
  26. package/build/angular/components/input-accessory-view-props.d.ts +4 -4
  27. package/build/angular/components/keyboard-avoiding-view/index.d.ts +3 -6
  28. package/build/angular/components/keyboard-avoiding-view/index.js +29 -56
  29. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
  30. package/build/angular/components/layout-conformance-props.d.ts +4 -0
  31. package/build/angular/components/layout-conformance-props.js +2 -0
  32. package/build/angular/components/layout-conformance-props.js.map +1 -0
  33. package/build/angular/components/modal/index.d.ts +6 -5
  34. package/build/angular/components/modal/index.js +17 -2
  35. package/build/angular/components/modal/index.js.map +1 -1
  36. package/build/angular/components/refresh-control-props.d.ts +7 -7
  37. package/build/angular/components/scroll-view-props.d.ts +8 -5
  38. package/build/angular/components/section-list/index.d.ts +17 -8
  39. package/build/angular/components/section-list/index.js +37 -28
  40. package/build/angular/components/section-list/index.js.map +1 -1
  41. package/build/angular/components/touchable-props.d.ts +2 -2
  42. package/build/angular/components/virtualized-list/cell-renderer-context.d.ts +12 -0
  43. package/build/angular/components/virtualized-list/cell-renderer-context.js +16 -0
  44. package/build/angular/components/virtualized-list/cell-renderer-context.js.map +1 -0
  45. package/build/angular/components/virtualized-list/directives.d.ts +26 -6
  46. package/build/angular/components/virtualized-list/directives.js +59 -5
  47. package/build/angular/components/virtualized-list/directives.js.map +1 -1
  48. package/build/angular/components/virtualized-list/index.d.ts +19 -15
  49. package/build/angular/components/virtualized-list/index.js +91 -61
  50. package/build/angular/components/virtualized-list/index.js.map +1 -1
  51. package/build/angular/components/virtualized-list/list-bags.d.ts +5 -1
  52. package/build/angular/components/virtualized-list/list-bags.js +31 -19
  53. package/build/angular/components/virtualized-list/list-bags.js.map +1 -1
  54. package/build/angular/components/virtualized-list/list-effects.d.ts +2 -2
  55. package/build/angular/components/virtualized-list/list-effects.js +17 -27
  56. package/build/angular/components/virtualized-list/list-effects.js.map +1 -1
  57. package/build/angular/components/virtualized-list/list-handle.d.ts +4 -1
  58. package/build/angular/components/virtualized-list/list-handle.js +13 -3
  59. package/build/angular/components/virtualized-list/list-handle.js.map +1 -1
  60. package/build/angular/components/virtualized-list/list-inputs.d.ts +19 -5
  61. package/build/angular/components/virtualized-list/list-inputs.js +47 -4
  62. package/build/angular/components/virtualized-list/list-inputs.js.map +1 -1
  63. package/build/angular/components/virtualized-list/list-props.d.ts +9 -3
  64. package/build/angular/components/virtualized-list/list-rows.d.ts +25 -0
  65. package/build/angular/components/virtualized-list/list-rows.js +25 -0
  66. package/build/angular/components/virtualized-list/list-rows.js.map +1 -0
  67. package/build/angular/components/virtualized-list/list-styles.d.ts +4 -0
  68. package/build/angular/components/virtualized-list/list-styles.js +10 -2
  69. package/build/angular/components/virtualized-list/list-styles.js.map +1 -1
  70. package/build/angular/components/virtualized-list/list-template.d.ts +1 -1
  71. package/build/angular/components/virtualized-list/list-template.js +159 -73
  72. package/build/angular/components/virtualized-list/list-template.js.map +1 -1
  73. package/build/angular/components/virtualized-list/nested-scope.d.ts +6 -0
  74. package/build/angular/components/virtualized-list/nested-scope.js +17 -0
  75. package/build/angular/components/virtualized-list/nested-scope.js.map +1 -0
  76. package/build/angular/components/virtualized-section-list/directives.d.ts +21 -9
  77. package/build/angular/components/virtualized-section-list/directives.js +8 -28
  78. package/build/angular/components/virtualized-section-list/directives.js.map +1 -1
  79. package/build/angular/components/virtualized-section-list/index.d.ts +39 -60
  80. package/build/angular/components/virtualized-section-list/index.js +67 -33
  81. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  82. package/build/angular/components/virtualized-section-list/section-cell.d.ts +29 -0
  83. package/build/angular/components/virtualized-section-list/section-cell.js +82 -0
  84. package/build/angular/components/virtualized-section-list/section-cell.js.map +1 -0
  85. package/build/angular/components/virtualized-section-list/section-list-props.d.ts +56 -0
  86. package/build/angular/components/virtualized-section-list/section-list-props.js +3 -0
  87. package/build/angular/components/virtualized-section-list/section-list-props.js.map +1 -0
  88. package/build/angular/components/virtualized-section-list/section-list-template.d.ts +1 -1
  89. package/build/angular/components/virtualized-section-list/section-list-template.js +34 -26
  90. package/build/angular/components/virtualized-section-list/section-list-template.js.map +1 -1
  91. package/build/angular/components.d.ts +7 -3
  92. package/build/angular/components.js +2 -1
  93. package/build/angular/components.js.map +1 -1
  94. package/build/angular/element-base.d.ts +17 -1
  95. package/build/angular/element-base.js +33 -1
  96. package/build/angular/element-base.js.map +1 -1
  97. package/build/angular/element-props.d.ts +7 -7
  98. package/build/angular/element-text-input-native.d.ts +27 -0
  99. package/build/angular/element-text-input-native.js +52 -0
  100. package/build/angular/element-text-input-native.js.map +1 -0
  101. package/build/angular/elements-controls.d.ts +8 -2
  102. package/build/angular/elements-controls.js +13 -1
  103. package/build/angular/elements-controls.js.map +1 -1
  104. package/build/angular/elements-layout.d.ts +20 -3
  105. package/build/angular/elements-layout.js +37 -3
  106. package/build/angular/elements-layout.js.map +1 -1
  107. package/build/angular/elements-press.d.ts +10 -3
  108. package/build/angular/elements-press.js +13 -1
  109. package/build/angular/elements-press.js.map +1 -1
  110. package/build/angular/elements.d.ts +3 -3
  111. package/build/angular/elements.js +3 -2
  112. package/build/angular/elements.js.map +1 -1
  113. package/build/angular/index.d.ts +15 -7
  114. package/build/angular/index.js +22 -25
  115. package/build/angular/index.js.map +1 -1
  116. package/build/angular/modules/animated/create-animated-component.d.ts +1 -1
  117. package/build/angular/modules/animated/create-animated-component.js +1 -1
  118. package/build/angular/modules/animated/create-animated-component.js.map +1 -1
  119. package/build/angular/modules/animated/index.d.ts +54 -41
  120. package/build/angular/modules/animated/index.js +2 -26
  121. package/build/angular/modules/animated/index.js.map +1 -1
  122. package/build/angular/modules/app-registry/index.d.ts +3 -3
  123. package/build/angular/modules/app-registry/index.js +2 -2
  124. package/build/angular/modules/app-registry/index.js.map +1 -1
  125. package/build/angular/modules/status-bar/index.d.ts +9 -5
  126. package/build/angular/modules/status-bar/index.js +21 -10
  127. package/build/angular/modules/status-bar/index.js.map +1 -1
  128. package/build/angular/primitives/index.d.ts +4 -0
  129. package/build/angular/primitives/index.js +12 -0
  130. package/build/angular/primitives/index.js.map +1 -1
  131. package/build/angular/render/index.d.ts +2 -2
  132. package/build/angular/render/index.js +10 -29
  133. package/build/angular/render/index.js.map +1 -1
  134. package/build/angular/root-tag.d.ts +4 -0
  135. package/build/angular/root-tag.js +10 -0
  136. package/build/angular/root-tag.js.map +1 -0
  137. package/build/angular/services/color-scheme.service.d.ts +1 -1
  138. package/package.json +6 -6
  139. package/src/accessibility-inputs.ts +3 -0
  140. package/src/callback-host.ts +56 -8
  141. package/src/components/flat-list/flat-list-handle.ts +64 -0
  142. package/src/components/flat-list/flat-list-template.ts +16 -0
  143. package/src/components/flat-list/index.ts +6 -48
  144. package/src/components/image-inputs.ts +94 -0
  145. package/src/components/image-props-resolve.ts +172 -0
  146. package/src/components/image-shared.ts +26 -291
  147. package/src/components/input-accessory-view-props.ts +12 -8
  148. package/src/components/keyboard-avoiding-view/index.ts +39 -79
  149. package/src/components/layout-conformance-props.ts +8 -0
  150. package/src/components/modal/index.ts +42 -20
  151. package/src/components/refresh-control-props.ts +29 -25
  152. package/src/components/scroll-view-props.ts +84 -76
  153. package/src/components/section-list/index.ts +34 -37
  154. package/src/components/touchable-props.ts +6 -2
  155. package/src/components/virtualized-list/cell-renderer-context.ts +36 -0
  156. package/src/components/virtualized-list/directives.ts +84 -8
  157. package/src/components/virtualized-list/index.ts +118 -85
  158. package/src/components/virtualized-list/list-bags.ts +38 -19
  159. package/src/components/virtualized-list/list-effects.ts +20 -32
  160. package/src/components/virtualized-list/list-handle.ts +17 -4
  161. package/src/components/virtualized-list/list-inputs.ts +47 -0
  162. package/src/components/virtualized-list/list-props.ts +57 -50
  163. package/src/components/virtualized-list/list-rows.ts +66 -0
  164. package/src/components/virtualized-list/list-styles.ts +30 -1
  165. package/src/components/virtualized-list/list-template.ts +159 -73
  166. package/src/components/virtualized-list/nested-scope.ts +22 -0
  167. package/src/components/virtualized-section-list/directives.ts +41 -40
  168. package/src/components/virtualized-section-list/index.ts +114 -118
  169. package/src/components/virtualized-section-list/section-cell.ts +109 -0
  170. package/src/components/virtualized-section-list/section-list-props.ts +79 -0
  171. package/src/components/virtualized-section-list/section-list-template.ts +34 -26
  172. package/src/components.ts +8 -0
  173. package/src/element-base.ts +17 -0
  174. package/src/element-props.ts +35 -33
  175. package/src/element-text-input-native.ts +31 -0
  176. package/src/elements-controls.ts +9 -1
  177. package/src/elements-layout.ts +27 -0
  178. package/src/elements-press.ts +10 -2
  179. package/src/elements.ts +3 -0
  180. package/src/index.ts +79 -22
  181. package/src/modules/animated/index.ts +2 -47
  182. package/src/modules/app-registry/index.ts +3 -1
  183. package/src/modules/status-bar/index.ts +24 -11
  184. package/src/primitives/index.ts +7 -0
  185. package/src/render/index.ts +23 -50
  186. package/src/root-tag.ts +14 -0
  187. package/src/services/color-scheme.service.ts +1 -1
@@ -8,12 +8,16 @@ import {
8
8
  Input,
9
9
  Output,
10
10
  TemplateRef,
11
+ type Type,
11
12
  } from '@angular/core';
12
13
  import {
13
14
  DEFAULT_INITIAL_NUM_TO_RENDER,
14
15
  DEFAULT_MAX_TO_RENDER_PER_BATCH,
15
16
  DEFAULT_UPDATE_CELLS_BATCHING_PERIOD,
16
17
  DEFAULT_WINDOW_SIZE,
18
+ ITEM_RENDERER,
19
+ pickItemRenderer,
20
+ type IInnerViewRef,
17
21
  type IViewabilityConfig,
18
22
  type IViewabilityConfigCallbackPair,
19
23
  type IViewableItemsChangedInfo,
@@ -24,11 +28,13 @@ import type {
24
28
  IViewStyle,
25
29
  } from '@symbiote-native/engine';
26
30
  import {
31
+ VListCellDirective,
27
32
  VListEmptyDirective,
28
33
  VListFooterDirective,
29
34
  VListHeaderDirective,
30
35
  VListItemDirective,
31
36
  VListSeparatorDirective,
37
+ type IVListCellContext,
32
38
  type IVListItemContext,
33
39
  type IVListSeparatorContext,
34
40
  } from './directives';
@@ -66,6 +72,8 @@ export abstract class ListInputsBase<ItemT> extends ListEventsBase {
66
72
  @Input() maxToRenderPerBatch?: number;
67
73
  @Input() updateCellsBatchingPeriod?: number;
68
74
  @Input() windowSize?: number;
75
+ // Mounts every cell from the top and paints no spacer, the window only grows toward the end
76
+ @Input() disableVirtualization?: boolean;
69
77
  @Input() stickyHeaderIndices?: number[];
70
78
  @Input() maintainVisibleContentPosition?: {
71
79
  minIndexForVisible: number;
@@ -76,15 +84,23 @@ export abstract class ListInputsBase<ItemT> extends ListEventsBase {
76
84
  @Input() onScrollEndDrag?: (event: ISymbioteEvent) => void;
77
85
  @Input() onMomentumScrollBegin?: (event: ISymbioteEvent) => void;
78
86
  @Input() onMomentumScrollEnd?: (event: ISymbioteEvent) => void;
87
+ @Input() onContentSizeChange?: (width: number, height: number) => void;
79
88
  @Input() scrollEventThrottle?: number;
80
89
  @Input() keyboardShouldPersistTaps?: boolean | 'always' | 'never' | 'handled';
81
90
  @Input() keyboardDismissMode?: 'none' | 'on-drag' | 'interactive';
82
91
  @Input() removeClippedSubviews?: boolean;
83
92
  @Input() nestedScrollEnabled?: boolean;
93
+ @Input() stickyHeaderHiddenOnScroll?: boolean;
94
+ @Input() innerViewRef?: IInnerViewRef;
84
95
  @Input() style?: IStyleProp<IViewStyle>;
85
96
  @Input() contentContainerStyle?: IStyleProp<IViewStyle>;
97
+ @Input() listHeaderComponentStyle?: IStyleProp<IViewStyle>;
98
+ @Input() listFooterComponentStyle?: IStyleProp<IViewStyle>;
86
99
  @Input() testID?: string;
87
100
  @Input() nativeID?: string;
101
+ // RN's `ListItemComponent`: a component taking `item`, `index` and `separators` inputs, in place
102
+ // of the `vListItem` template, and it wins when both are given
103
+ @Input() listItemComponent?: Type<unknown>;
88
104
 
89
105
  // The cell and slot templates the app authors, captured from projected <ng-template> content
90
106
  @ContentChild(VListItemDirective) itemDir?: VListItemDirective<ItemT>;
@@ -93,11 +109,33 @@ export abstract class ListInputsBase<ItemT> extends ListEventsBase {
93
109
  @ContentChild(VListEmptyDirective) emptyDir?: VListEmptyDirective;
94
110
  @ContentChild(VListSeparatorDirective)
95
111
  separatorDir?: VListSeparatorDirective<ItemT>;
112
+ @ContentChild(VListCellDirective) cellDir?: VListCellDirective;
96
113
 
97
114
  get isHorizontal(): boolean {
98
115
  return this.horizontal === true;
99
116
  }
100
117
 
118
+ // The app's `vListCell`, which a list built on this one may replace with its own
119
+ get cellRendererTpl(): TemplateRef<IVListCellContext> | undefined {
120
+ return this.cellDir?.templateRef;
121
+ }
122
+
123
+ // The component to stamp per cell, RN's `_renderElement`: it wins over the item template, and a
124
+ // cell with neither throws
125
+ get itemComponent(): Type<unknown> | undefined {
126
+ const kind = pickItemRenderer({
127
+ hasRenderItem: this.hasItemTemplate,
128
+ hasComponent: this.listItemComponent !== undefined,
129
+ });
130
+ return kind === ITEM_RENDERER.component
131
+ ? this.listItemComponent
132
+ : undefined;
133
+ }
134
+
135
+ protected get hasItemTemplate(): boolean {
136
+ return this.itemDir !== undefined;
137
+ }
138
+
101
139
  protected get isInverted(): boolean {
102
140
  return this.inverted === true;
103
141
  }
@@ -137,11 +175,20 @@ export abstract class VirtualizedListInputs<
137
175
  // outlet deep instead of a wrapper outlet around the app's own. Each wins over projection
138
176
  @Input() itemTemplate?: TemplateRef<IVListItemContext<ItemT>>;
139
177
  @Input() itemSeparatorTemplate?: TemplateRef<IVListSeparatorContext<ItemT>>;
178
+ @Input() cellRendererTemplate?: TemplateRef<IVListCellContext>;
179
+
180
+ override get cellRendererTpl(): TemplateRef<IVListCellContext> | undefined {
181
+ return this.cellRendererTemplate ?? this.cellDir?.templateRef;
182
+ }
140
183
 
141
184
  get cellTemplate(): TemplateRef<IVListItemContext<ItemT>> | undefined {
142
185
  return this.itemTemplate ?? this.itemDir?.templateRef;
143
186
  }
144
187
 
188
+ protected override get hasItemTemplate(): boolean {
189
+ return this.cellTemplate !== undefined;
190
+ }
191
+
145
192
  get separatorTemplate():
146
193
  TemplateRef<IVListSeparatorContext<ItemT>> | undefined {
147
194
  return this.itemSeparatorTemplate ?? this.separatorDir?.templateRef;
@@ -3,6 +3,7 @@
3
3
  import type {
4
4
  IAccessibilityProps,
5
5
  IAriaProps,
6
+ IInnerViewRef,
6
7
  IViewabilityConfig,
7
8
  IViewabilityConfigCallbackPair,
8
9
  IViewableItemsChangedInfo,
@@ -14,57 +15,63 @@ import type {
14
15
  } from '@symbiote-native/engine';
15
16
 
16
17
  // The React and Vue surface minus element-returning props, which are `<ng-template>` here
17
- export interface IVirtualizedListProps<ItemT>
18
- extends IAccessibilityProps, IAriaProps {
19
- data: unknown;
20
- getItem: (data: unknown, index: number) => ItemT;
21
- getItemCount: (data: unknown) => number;
22
- keyExtractor?: (item: ItemT, index: number) => string;
23
- getItemLayout?: (
24
- data: unknown,
25
- index: number,
26
- ) => { length: number; offset: number; index: number };
27
- horizontal?: boolean;
28
- inverted?: boolean;
29
- extraData?: unknown;
30
- onEndReached?: (info: { distanceFromEnd: number }) => void;
31
- onEndReachedThreshold?: number;
32
- onStartReached?: (info: { distanceFromStart: number }) => void;
33
- onStartReachedThreshold?: number;
34
- onRefresh?: () => void;
35
- refreshing?: boolean | null;
36
- progressViewOffset?: number;
37
- onViewableItemsChanged?: (info: IViewableItemsChangedInfo<ItemT>) => void;
38
- viewabilityConfig?: IViewabilityConfig;
39
- viewabilityConfigCallbackPairs?: IViewabilityConfigCallbackPair<ItemT>[];
40
- onScrollToIndexFailed?: (info: {
41
- index: number;
42
- highestMeasuredFrameIndex: number;
43
- averageItemLength: number;
44
- }) => void;
45
- initialNumToRender?: number;
46
- initialScrollIndex?: number;
47
- maxToRenderPerBatch?: number;
48
- updateCellsBatchingPeriod?: number;
49
- windowSize?: number;
50
- stickyHeaderIndices?: number[];
51
- maintainVisibleContentPosition?: {
52
- minIndexForVisible: number;
53
- autoscrollToTopThreshold?: number;
18
+ export type IVirtualizedListProps<ItemT> = IAccessibilityProps &
19
+ IAriaProps & {
20
+ data: unknown;
21
+ getItem: (data: unknown, index: number) => ItemT;
22
+ getItemCount: (data: unknown) => number;
23
+ keyExtractor?: (item: ItemT, index: number) => string;
24
+ getItemLayout?: (
25
+ data: unknown,
26
+ index: number,
27
+ ) => { length: number; offset: number; index: number };
28
+ horizontal?: boolean;
29
+ inverted?: boolean;
30
+ extraData?: unknown;
31
+ onEndReached?: (info: { distanceFromEnd: number }) => void;
32
+ onEndReachedThreshold?: number;
33
+ onStartReached?: (info: { distanceFromStart: number }) => void;
34
+ onStartReachedThreshold?: number;
35
+ onRefresh?: () => void;
36
+ refreshing?: boolean | null;
37
+ progressViewOffset?: number;
38
+ onViewableItemsChanged?: (info: IViewableItemsChangedInfo<ItemT>) => void;
39
+ viewabilityConfig?: IViewabilityConfig;
40
+ viewabilityConfigCallbackPairs?: IViewabilityConfigCallbackPair<ItemT>[];
41
+ onScrollToIndexFailed?: (info: {
42
+ index: number;
43
+ highestMeasuredFrameIndex: number;
44
+ averageItemLength: number;
45
+ }) => void;
46
+ initialNumToRender?: number;
47
+ initialScrollIndex?: number;
48
+ maxToRenderPerBatch?: number;
49
+ updateCellsBatchingPeriod?: number;
50
+ windowSize?: number;
51
+ disableVirtualization?: boolean;
52
+ stickyHeaderIndices?: number[];
53
+ maintainVisibleContentPosition?: {
54
+ minIndexForVisible: number;
55
+ autoscrollToTopThreshold?: number;
56
+ };
57
+ onScroll?: (event: ISymbioteEvent) => void;
58
+ onScrollBeginDrag?: (event: ISymbioteEvent) => void;
59
+ onScrollEndDrag?: (event: ISymbioteEvent) => void;
60
+ onMomentumScrollBegin?: (event: ISymbioteEvent) => void;
61
+ onMomentumScrollEnd?: (event: ISymbioteEvent) => void;
62
+ onContentSizeChange?: (width: number, height: number) => void;
63
+ scrollEventThrottle?: number;
64
+ keyboardShouldPersistTaps?: boolean | 'always' | 'never' | 'handled';
65
+ keyboardDismissMode?: 'none' | 'on-drag' | 'interactive';
66
+ removeClippedSubviews?: boolean;
67
+ nestedScrollEnabled?: boolean;
68
+ stickyHeaderHiddenOnScroll?: boolean;
69
+ innerViewRef?: IInnerViewRef;
70
+ style?: IStyleProp<IViewStyle>;
71
+ contentContainerStyle?: IStyleProp<IViewStyle>;
72
+ listHeaderComponentStyle?: IStyleProp<IViewStyle>;
73
+ listFooterComponentStyle?: IStyleProp<IViewStyle>;
54
74
  };
55
- onScroll?: (event: ISymbioteEvent) => void;
56
- onScrollBeginDrag?: (event: ISymbioteEvent) => void;
57
- onScrollEndDrag?: (event: ISymbioteEvent) => void;
58
- onMomentumScrollBegin?: (event: ISymbioteEvent) => void;
59
- onMomentumScrollEnd?: (event: ISymbioteEvent) => void;
60
- scrollEventThrottle?: number;
61
- keyboardShouldPersistTaps?: boolean | 'always' | 'never' | 'handled';
62
- keyboardDismissMode?: 'none' | 'on-drag' | 'interactive';
63
- removeClippedSubviews?: boolean;
64
- nestedScrollEnabled?: boolean;
65
- style?: IStyleProp<IViewStyle>;
66
- contentContainerStyle?: IStyleProp<IViewStyle>;
67
- }
68
75
 
69
76
  // The plain inputs: the full surface minus the events exposed as real outputs
70
77
  export type IVirtualizedListInputs<ItemT> = Omit<
@@ -0,0 +1,66 @@
1
+ // The rows the template stamps: the plan's spacers and cells, keyed so a window slide moves them
2
+
3
+ import {
4
+ LIST_SEGMENT_KIND,
5
+ spacerStyleOf,
6
+ type IWindowPlan,
7
+ } from '@symbiote-native/components';
8
+ import type { IViewStyle } from '@symbiote-native/engine';
9
+ import type { CellRegistry, IWindowCell } from './cell-registry';
10
+ import type { IVListCellContext } from './directives';
11
+
12
+ export type ISpacerRow = {
13
+ kind: typeof LIST_SEGMENT_KIND.spacer;
14
+ key: string;
15
+ style: IViewStyle;
16
+ };
17
+
18
+ export type ICellRow<ItemT> = {
19
+ kind: typeof LIST_SEGMENT_KIND.cell;
20
+ key: string;
21
+ cell: IWindowCell<ItemT>;
22
+ // Only when the app drew its own cell wrapper with `vListCell`
23
+ renderer: IVListCellContext | undefined;
24
+ };
25
+
26
+ export type IListRow<ItemT> = ISpacerRow | ICellRow<ItemT>;
27
+
28
+ export type IRowsParams<ItemT> = {
29
+ windowPlan: IWindowPlan;
30
+ cells: CellRegistry<ItemT>;
31
+ count: number;
32
+ isHorizontal: boolean;
33
+ hasSeparators: boolean;
34
+ rendererFor: ((cell: IWindowCell<ItemT>) => IVListCellContext) | undefined;
35
+ };
36
+
37
+ // A cell and a spacer never share a row key, an item key cannot start with `spacer-`
38
+ export function stampPlanRows<ItemT>(
39
+ params: IRowsParams<ItemT>,
40
+ ): IListRow<ItemT>[] {
41
+ const { windowPlan, cells, count, isHorizontal, hasSeparators, rendererFor } =
42
+ params;
43
+ return windowPlan.plan.segments.map((segment): IListRow<ItemT> => {
44
+ if (segment.kind === LIST_SEGMENT_KIND.spacer) {
45
+ return {
46
+ kind: segment.kind,
47
+ key: segment.key,
48
+ style: spacerStyleOf(segment.extent, isHorizontal),
49
+ };
50
+ }
51
+ // The separator gates on the last index of the data, not of the window, or a cell's height
52
+ // would shift as it slides past
53
+ const cell = cells.windowCell(
54
+ segment.index,
55
+ segment.key,
56
+ hasSeparators && segment.index < count - 1,
57
+ windowPlan.stickySet?.has(segment.index) === true,
58
+ );
59
+ return {
60
+ kind: segment.kind,
61
+ key: `cell-${segment.key}`,
62
+ cell,
63
+ renderer: rendererFor?.(cell),
64
+ };
65
+ });
66
+ }
@@ -4,6 +4,7 @@
4
4
  import {
5
5
  INVERTED_X_STYLE,
6
6
  INVERTED_Y_STYLE,
7
+ cellStyleOf,
7
8
  } from '@symbiote-native/components';
8
9
  import {
9
10
  flattenStyle,
@@ -23,6 +24,8 @@ export type IListStyleInput = {
23
24
  hasHeader: boolean;
24
25
  style: IStyleProp<IViewStyle> | undefined;
25
26
  contentContainerStyle: IStyleProp<IViewStyle> | undefined;
27
+ listHeaderComponentStyle: IStyleProp<IViewStyle> | undefined;
28
+ listFooterComponentStyle: IStyleProp<IViewStyle> | undefined;
26
29
  // The class-derived style of the list's own anchor host
27
30
  anchorStyle: unknown;
28
31
  maintainVisibleContentPosition: IMaintainVisibleContentPosition | undefined;
@@ -34,9 +37,20 @@ export type IListStyles = {
34
37
  style: IViewStyle | undefined;
35
38
  contentContainerStyle: IStyleProp<IViewStyle> | undefined;
36
39
  cellStyle: IViewStyle | undefined;
40
+ // The slot wrappers counter-flip with an inverted list, then take the slot's own style
41
+ headerStyle: IViewStyle | undefined;
42
+ footerStyle: IViewStyle | undefined;
37
43
  maintainVisibleContentPosition: IMaintainVisibleContentPosition | undefined;
38
44
  };
39
45
 
46
+ function slotStyle(
47
+ isInverted: boolean,
48
+ inversion: IViewStyle,
49
+ style: IStyleProp<IViewStyle> | undefined,
50
+ ): IViewStyle | undefined {
51
+ return flattenStyle(isInverted ? [inversion, style] : style);
52
+ }
53
+
40
54
  export function resolveListStyles(input: IListStyleInput): IListStyles {
41
55
  const inversion = input.isHorizontal ? INVERTED_X_STYLE : INVERTED_Y_STYLE;
42
56
  const mvcp = input.maintainVisibleContentPosition;
@@ -49,7 +63,22 @@ export function resolveListStyles(input: IListStyleInput): IListStyles {
49
63
  input.anchorStyle,
50
64
  input.isInverted ? [inversion, input.style] : input.style,
51
65
  ]),
52
- cellStyle: input.isInverted ? inversion : undefined,
66
+ cellStyle: flattenStyle(
67
+ cellStyleOf({
68
+ horizontal: input.isHorizontal,
69
+ inverted: input.isInverted,
70
+ }),
71
+ ),
72
+ headerStyle: slotStyle(
73
+ input.isInverted,
74
+ inversion,
75
+ input.listHeaderComponentStyle,
76
+ ),
77
+ footerStyle: slotStyle(
78
+ input.isInverted,
79
+ inversion,
80
+ input.listFooterComponentStyle,
81
+ ),
53
82
  maintainVisibleContentPosition:
54
83
  mvcp === undefined
55
84
  ? undefined