@ng-native/components 0.0.1 → 0.1.1

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 (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -1
  3. package/dist/activity-indicator.d.ts +41 -0
  4. package/dist/activity-indicator.js +66 -0
  5. package/dist/activity-indicator.js.map +1 -0
  6. package/dist/animated-style.d.ts +31 -0
  7. package/dist/animated-style.js +102 -0
  8. package/dist/animated-style.js.map +1 -0
  9. package/dist/animated.d.ts +125 -0
  10. package/dist/animated.js +538 -0
  11. package/dist/animated.js.map +1 -0
  12. package/dist/animation.d.ts +40 -0
  13. package/dist/animation.js +20 -0
  14. package/dist/animation.js.map +1 -0
  15. package/dist/animations-web.d.ts +8 -0
  16. package/dist/animations-web.js +31 -0
  17. package/dist/animations-web.js.map +1 -0
  18. package/dist/animations.d.ts +7 -0
  19. package/dist/animations.js +58 -0
  20. package/dist/animations.js.map +1 -0
  21. package/dist/controlled-model.d.ts +33 -0
  22. package/dist/controlled-model.js +47 -0
  23. package/dist/controlled-model.js.map +1 -0
  24. package/dist/easing.d.ts +21 -0
  25. package/dist/easing.js +50 -0
  26. package/dist/easing.js.map +1 -0
  27. package/dist/events.d.ts +169 -0
  28. package/dist/events.js +2 -0
  29. package/dist/events.js.map +1 -0
  30. package/dist/gesture-backend.d.ts +26 -0
  31. package/dist/gesture-backend.js +14 -0
  32. package/dist/gesture-backend.js.map +1 -0
  33. package/dist/gesture-dispatch.d.ts +67 -0
  34. package/dist/gesture-dispatch.js +106 -0
  35. package/dist/gesture-dispatch.js.map +1 -0
  36. package/dist/gestures.d.ts +23 -0
  37. package/dist/gestures.js +164 -0
  38. package/dist/gestures.js.map +1 -0
  39. package/dist/height-index.d.ts +31 -0
  40. package/dist/height-index.js +80 -0
  41. package/dist/height-index.js.map +1 -0
  42. package/dist/image-background.d.ts +32 -0
  43. package/dist/image-background.js +80 -0
  44. package/dist/image-background.js.map +1 -0
  45. package/dist/image.d.ts +79 -0
  46. package/dist/image.js +155 -0
  47. package/dist/image.js.map +1 -0
  48. package/dist/index.d.ts +38 -0
  49. package/dist/index.js +39 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/input-accessory-view.d.ts +16 -0
  52. package/dist/input-accessory-view.js +29 -0
  53. package/dist/input-accessory-view.js.map +1 -0
  54. package/dist/keyboard-avoiding-view.d.ts +79 -0
  55. package/dist/keyboard-avoiding-view.js +172 -0
  56. package/dist/keyboard-avoiding-view.js.map +1 -0
  57. package/dist/keyboard-dock.d.ts +126 -0
  58. package/dist/keyboard-dock.js +327 -0
  59. package/dist/keyboard-dock.js.map +1 -0
  60. package/dist/keyboard-taps.d.ts +12 -0
  61. package/dist/keyboard-taps.js +51 -0
  62. package/dist/keyboard-taps.js.map +1 -0
  63. package/dist/modal.d.ts +56 -0
  64. package/dist/modal.js +102 -0
  65. package/dist/modal.js.map +1 -0
  66. package/dist/native-gesture.d.ts +21 -0
  67. package/dist/native-gesture.js +56 -0
  68. package/dist/native-gesture.js.map +1 -0
  69. package/dist/native-ref.d.ts +7 -0
  70. package/dist/native-ref.js +13 -0
  71. package/dist/native-ref.js.map +1 -0
  72. package/dist/pressable.d.ts +220 -0
  73. package/dist/pressable.js +484 -0
  74. package/dist/pressable.js.map +1 -0
  75. package/dist/reanimated.d.ts +19 -0
  76. package/dist/reanimated.js +111 -0
  77. package/dist/reanimated.js.map +1 -0
  78. package/dist/refresh-control.d.ts +50 -0
  79. package/dist/refresh-control.js +103 -0
  80. package/dist/refresh-control.js.map +1 -0
  81. package/dist/safe-area-provider.d.ts +11 -0
  82. package/dist/safe-area-provider.js +70 -0
  83. package/dist/safe-area-provider.js.map +1 -0
  84. package/dist/safe-area-view.d.ts +22 -0
  85. package/dist/safe-area-view.js +77 -0
  86. package/dist/safe-area-view.js.map +1 -0
  87. package/dist/safe-area.d.ts +12 -0
  88. package/dist/safe-area.js +27 -0
  89. package/dist/safe-area.js.map +1 -0
  90. package/dist/scroll-view-props.d.ts +89 -0
  91. package/dist/scroll-view-props.js +153 -0
  92. package/dist/scroll-view-props.js.map +1 -0
  93. package/dist/scroll-view.d.ts +95 -0
  94. package/dist/scroll-view.js +181 -0
  95. package/dist/scroll-view.js.map +1 -0
  96. package/dist/section-list.d.ts +146 -0
  97. package/dist/section-list.js +300 -0
  98. package/dist/section-list.js.map +1 -0
  99. package/dist/sticky-headers.d.ts +41 -0
  100. package/dist/sticky-headers.js +118 -0
  101. package/dist/sticky-headers.js.map +1 -0
  102. package/dist/swipe-refresh-layout.d.ts +51 -0
  103. package/dist/swipe-refresh-layout.js +162 -0
  104. package/dist/swipe-refresh-layout.js.map +1 -0
  105. package/dist/switch.d.ts +54 -0
  106. package/dist/switch.js +110 -0
  107. package/dist/switch.js.map +1 -0
  108. package/dist/template-slot.d.ts +18 -0
  109. package/dist/template-slot.js +30 -0
  110. package/dist/template-slot.js.map +1 -0
  111. package/dist/text-input.d.ts +168 -0
  112. package/dist/text-input.js +312 -0
  113. package/dist/text-input.js.map +1 -0
  114. package/dist/text.d.ts +70 -0
  115. package/dist/text.js +111 -0
  116. package/dist/text.js.map +1 -0
  117. package/dist/touchable-opacity.d.ts +36 -0
  118. package/dist/touchable-opacity.js +76 -0
  119. package/dist/touchable-opacity.js.map +1 -0
  120. package/dist/transforms.d.ts +2 -0
  121. package/dist/transforms.js +17 -0
  122. package/dist/transforms.js.map +1 -0
  123. package/dist/view-base.d.ts +332 -0
  124. package/dist/view-base.js +534 -0
  125. package/dist/view-base.js.map +1 -0
  126. package/dist/view.d.ts +12 -0
  127. package/dist/view.js +18 -0
  128. package/dist/view.js.map +1 -0
  129. package/dist/virtual-list.d.ts +530 -0
  130. package/dist/virtual-list.js +1150 -0
  131. package/dist/virtual-list.js.map +1 -0
  132. package/dist/worklet-scroll.d.ts +13 -0
  133. package/dist/worklet-scroll.js +49 -0
  134. package/dist/worklet-scroll.js.map +1 -0
  135. package/dist/worklet-style.d.ts +13 -0
  136. package/dist/worklet-style.js +47 -0
  137. package/dist/worklet-style.js.map +1 -0
  138. package/dist/worklets.d.ts +89 -0
  139. package/dist/worklets.js +42 -0
  140. package/dist/worklets.js.map +1 -0
  141. package/dist/written-props.d.ts +6 -0
  142. package/dist/written-props.js +180 -0
  143. package/dist/written-props.js.map +1 -0
  144. package/package.json +88 -3
@@ -0,0 +1,530 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import { type NativeSyntheticEvent } from '@ng-native/fabric';
3
+ import { type KeyboardShouldPersistTaps } from './keyboard-taps.ts';
4
+ import { ScrollViewProps } from './scroll-view-props.ts';
5
+ import * as i0 from "@angular/core";
6
+ /** One rendered row: the item, its index, and a stable style object for its slot. */
7
+ export interface VirtualRow<T> {
8
+ readonly index: number;
9
+ /**
10
+ * A key that a row keeps while its item stays in the window, and that passes to a row arriving
11
+ * once it has left. `track row.slot` recycles rows: the view of a row scrolling out is reused for
12
+ * the one scrolling in, with only its bindings updated, rather than one destroyed and one created
13
+ * each time. A slot follows its item, not its position, so an insert above the window moves no
14
+ * row to another item.
15
+ */
16
+ readonly slot: number;
17
+ /**
18
+ * The item's identity, from `keyExtractor`, or the item itself without one. `track row.key`
19
+ * gives each item a view of its own for as long as it is in the window and never recycles one,
20
+ * which is what a row holding state of its own, or animating, needs.
21
+ */
22
+ readonly key: unknown;
23
+ readonly item: T;
24
+ readonly style: Record<string, unknown>;
25
+ /**
26
+ * A slot kept rendered but hidden, still bound to the last item it showed, so the next row of
27
+ * its type to arrive reuses its views instead of building them. Always last in the window.
28
+ */
29
+ readonly parked?: true;
30
+ }
31
+ /** A row height: one for every row, or one per item. */
32
+ export type VirtualItemHeight<T> = number | ((item: T, index: number) => number);
33
+ /**
34
+ * Keep what is on screen where it is when rows are added or removed before it, as
35
+ * `ScrollView`'s `maintainVisibleContentPosition` does in React Native.
36
+ */
37
+ export interface VirtualListVisiblePosition {
38
+ /** Rows before this index are never what the position is held by. Defaults to 0. */
39
+ readonly minIndexForVisible?: number;
40
+ /**
41
+ * Within this many points of the start, show what arrived instead of holding position: a feed
42
+ * at its top scrolls to the new posts, a chat at its newest message follows the next one.
43
+ */
44
+ readonly autoscrollToTopThreshold?: number;
45
+ }
46
+ /** What a separator template is given: the rows either side of it, as FlatList's `leadingItem`. */
47
+ export interface VirtualListSeparatorContext<T> {
48
+ readonly $implicit: T;
49
+ readonly leadingItem: T;
50
+ readonly trailingItem: T;
51
+ readonly leadingIndex: number;
52
+ }
53
+ /**
54
+ * Marks the template drawn between two rows: `<ng-template virtualListSeparator let-leading>`.
55
+ * FlatList's `ItemSeparatorComponent`.
56
+ */
57
+ export declare class VirtualListSeparator<T = unknown> {
58
+ readonly template: TemplateRef<VirtualListSeparatorContext<T>>;
59
+ static ngTemplateContextGuard<T>(_directive: VirtualListSeparator<T>, context: unknown): context is VirtualListSeparatorContext<T>;
60
+ static ɵfac: i0.ɵɵFactoryDeclaration<VirtualListSeparator<any>, never>;
61
+ static ɵdir: i0.ɵɵDirectiveDeclaration<VirtualListSeparator<any>, "ng-template[virtualListSeparator]", never, {}, {}, never, never, true, never>;
62
+ }
63
+ /** One separator the list is drawing: its slot, and what its template is told. */
64
+ interface Gap<T> {
65
+ readonly index: number;
66
+ readonly style: Record<string, unknown>;
67
+ readonly context: VirtualListSeparatorContext<T>;
68
+ }
69
+ /**
70
+ * Windowed list: a native scroll view whose content is sized to the full list, with only the
71
+ * visible slice rendered. Commits as `RCTScrollView`.
72
+ *
73
+ * RN's FlatList, SectionList and VirtualizedList are a large React component tree, and none of
74
+ * it is reachable. This is the small equivalent. Angular's own `@for` does the rendering, so
75
+ * tracking, reuse and destruction all behave normally, and the loop stays in the caller's
76
+ * template:
77
+ *
78
+ * ```html
79
+ * <virtual-list #list [items]="rows()" [itemHeight]="44" (endReached)="loadMore()">
80
+ * <text listHeader>Header</text>
81
+ * @for (row of list.window(); track row.slot) {
82
+ * <view [virtualListRow]="row"><text>{{ row.item.label }}</text></view>
83
+ * }
84
+ * <text listFooter>Footer</text>
85
+ * </virtual-list>
86
+ * ```
87
+ *
88
+ * With `itemHeight`, every row's size is known up front and each is absolutely positioned at its
89
+ * offset. Without it, rows size themselves, as a feed's posts and a chat's messages do: the window
90
+ * is laid out in normal flow after a spacer standing in for the rows above it, so native places
91
+ * every row correctly in the frame it first appears, and each row's layout tells the list its
92
+ * height for sizing what is not rendered. Until a row has been measured it counts as
93
+ * `estimatedItemHeight`. Measurements are kept by `keyExtractor`, so they follow their item across
94
+ * inserts, removals and moves. `virtualListRow` on each row's view applies its style and reports
95
+ * its layout; `[style]="row.style"` still works for fixed heights, which need no measuring.
96
+ *
97
+ * Content marked `listHeader` and `listFooter` renders above and below the rows in normal flow,
98
+ * as FlatList's header and footer components do. A `<refresh-control>` projects like any child.
99
+ *
100
+ * `<ng-template virtualListSeparator let-leading let-trailing="trailingItem">` is drawn between
101
+ * each pair of rows and not after the last, as FlatList's `ItemSeparatorComponent` is. It is drawn
102
+ * inside the leading row's slot, at its trailing edge, so `itemHeight` includes it the way
103
+ * `getItemLayout`'s `length` includes it in RN; a measured row has it drawn over its trailing edge
104
+ * once its height is known. The slot it sits in lets touches through to the row underneath.
105
+ *
106
+ * `horizontal` swaps the axis: rows are placed by `left` and sized by `width`, and the offset is
107
+ * read from `contentOffset.x`. `inverted` is a scale of -1 on the list and on each row, which is
108
+ * how FlatList does it too - the list scrolls from the bottom and each row is flipped back the
109
+ * right way up, so a chat transcript needs no reversed array.
110
+ *
111
+ * `stickyIndices` pins a row to the leading edge while the rows under it scroll past, which is
112
+ * FlatList's `stickyHeaderIndices` counted without the header. `stickyHeader` pins the
113
+ * `listHeader` content the same way, FlatList's index 0 when it has a `ListHeaderComponent`, and
114
+ * the first sticky row pushes it off as RN's sticky headers push each other. Neither is native:
115
+ * RN's `ScrollView.js` translates a sticky child against the scroll offset in JavaScript, and a
116
+ * row here follows the offset the same way while it is the current one - by its `top` when
117
+ * absolutely positioned, by a transform when in flow.
118
+ *
119
+ * What is on screen stays on screen when a measured row above it turns out taller or shorter than
120
+ * its estimate: the offset is corrected by the difference. `maintainVisibleContentPosition` does
121
+ * the same for rows inserted or removed above it, which a feed receiving new posts and a chat
122
+ * loading older messages above the ones being read both need.
123
+ *
124
+ * ponytail: viewability is `itemVisiblePercentThreshold` only: `minimumViewTime` and
125
+ * `waitForInteraction` are timing policy on top of the same measurement, and nothing has needed
126
+ * them. A separator is not told `highlighted`, which RN drives from the row's press state. A
127
+ * sticky header follows the scroll a commit behind native, where RN's is on the native driver. A
128
+ * held position is restored by a `scrollTo` after the commit, not in the mount as native
129
+ * `maintainVisibleContentPosition` is, so a correction made mid-fling lands where the last scroll
130
+ * event said the list was.
131
+ */
132
+ export declare class VirtualList<T> extends ScrollViewProps {
133
+ readonly items: import("@angular/core").InputSignal<readonly T[]>;
134
+ /**
135
+ * A fixed height, or a function for variable ones, when every row's size is known up front. The
136
+ * function form builds a cumulative offset table and binary-searches it, which is what section
137
+ * lists need: a header row and an item row are different heights, so uniform maths cannot place
138
+ * them. Leave it unset for rows that size themselves.
139
+ */
140
+ readonly itemHeight: import("@angular/core").InputSignal<VirtualItemHeight<T> | undefined>;
141
+ /**
142
+ * What a row that sizes itself counts as until it has been measured. The closer it is, the more
143
+ * honest the scroll bar is and the less a jump to an unmeasured row has to correct.
144
+ */
145
+ readonly estimatedItemHeight: import("@angular/core").InputSignal<VirtualItemHeight<T>>;
146
+ /**
147
+ * An item's identity, as FlatList's `keyExtractor`: what a measured height, a slot and a held
148
+ * position follow across an insert. Without it an item is its own key, which is enough for items
149
+ * that are replaced, not copied, when they change.
150
+ */
151
+ readonly keyExtractor: import("@angular/core").InputSignal<((item: T, index: number) => unknown) | undefined>;
152
+ /**
153
+ * What kind of row an item is, when rows of different kinds share the list: a text post and a
154
+ * photo post, a message and a date divider. A slot is only ever recycled into a row of the same
155
+ * type, so its views are reused rather than torn down for another kind's, as UIKit's reuse
156
+ * identifiers and FlashList's `getItemType` do.
157
+ */
158
+ readonly itemType: import("@angular/core").InputSignal<((item: T, index: number) => unknown) | undefined>;
159
+ /** Keep what is on screen still when rows are inserted or removed before it. */
160
+ readonly maintainVisibleContentPosition: import("@angular/core").InputSignal<VirtualListVisiblePosition | undefined>;
161
+ /** Rows rendered beyond each edge of the viewport, to cover fling gaps. */
162
+ readonly overscan: import("@angular/core").InputSignalWithTransform<number, unknown>;
163
+ /** How close to the end, in viewport heights, `(endReached)` fires. RN's default is 2. */
164
+ readonly endReachedThreshold: import("@angular/core").InputSignalWithTransform<number, unknown>;
165
+ /** Lay the rows out along x instead of y, and scroll that way. */
166
+ readonly horizontal: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
167
+ /** Start at the end and scroll backwards, with every row flipped back the right way up. */
168
+ readonly inverted: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
169
+ /**
170
+ * Rows that pin to the leading edge while the ones under them scroll past. Ascending; a row is
171
+ * pinned from the moment it would leave until the next sticky row pushes it off.
172
+ */
173
+ readonly stickyIndices: import("@angular/core").InputSignal<readonly number[]>;
174
+ /** Pin the `listHeader` content to the leading edge until the first sticky row pushes it off. */
175
+ readonly stickyHeader: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
176
+ /** What a tap in the list does while a text input has the keyboard up. See `ScrollView`. */
177
+ readonly keyboardShouldPersistTaps: import("@angular/core").InputSignal<KeyboardShouldPersistTaps>;
178
+ /** How much of a row must be on screen to count as viewable. RN's default is 0, meaning any. */
179
+ readonly itemVisiblePercentThreshold: import("@angular/core").InputSignalWithTransform<number, unknown>;
180
+ /**
181
+ * The scroll position is within `endReachedThreshold` of the end: once per item count, and again
182
+ * after the list has scrolled away from the end and come back.
183
+ */
184
+ readonly endReached: import("@angular/core").OutputEmitterRef<{
185
+ distanceFromEnd: number;
186
+ }>;
187
+ /** Which rows are on screen, and what changed since last time. */
188
+ readonly viewableItemsChanged: import("@angular/core").OutputEmitterRef<{
189
+ viewable: readonly VirtualRow<T>[];
190
+ entered: readonly number[];
191
+ left: readonly number[];
192
+ }>;
193
+ private readonly viewport;
194
+ /** The leading edge of the viewport in content space, which sticky rows and viewability need. */
195
+ private readonly offset;
196
+ private readonly headerHeight;
197
+ /** What native reported the content measures along the axis, once it has. */
198
+ private contentSize;
199
+ /** The item count `endReached` last fired for, cleared once the list is away from the end. */
200
+ private endReachedFor;
201
+ /** Slot styles are cached so a scroll does not hand Fabric new prop objects for stable rows. */
202
+ private readonly slots;
203
+ /** A separator's slot style, per row slot style, so it is as stable as the row's own. */
204
+ private readonly gapStyles;
205
+ /** The same for a measured row's separator, by key, while its place and size stay put. */
206
+ private readonly measuredGaps;
207
+ protected readonly separator: import("@angular/core").Signal<VirtualListSeparator<T> | undefined>;
208
+ private readonly refreshControl;
209
+ /** See ScrollView: inside Android's swipe layout the list must see a drag first. */
210
+ protected readonly nestedScroll: import("@angular/core").Signal<true | undefined>;
211
+ /**
212
+ * Whether native moves sticky rows. Each then stays at its own place in the list and native
213
+ * translates it on every frame the list scrolls, as RN's `ScrollViewStickyHeader` does; a
214
+ * translate committed from each scroll event lands a frame or more late, and on a fast fling
215
+ * the row shudders and comes away from the edge.
216
+ */
217
+ private readonly nativeSticky;
218
+ /** The offset once scrolling pauses, which the settled translate of a native-moved row is from. */
219
+ private readonly settled;
220
+ private settleTimer;
221
+ /** What native is moving, by row view, with the transform kept beside the translate. */
222
+ private readonly drives;
223
+ private readonly canvasView;
224
+ /** Whether the scroll offset is needed as a signal, which only pinning needs. */
225
+ private readonly pinning;
226
+ /** Rows size themselves and are laid out in flow, rather than placed at a known offset. */
227
+ readonly measuring: import("@angular/core").Signal<boolean>;
228
+ /** Heights native has reported, by key. */
229
+ private readonly measured;
230
+ /** Bumped when a measurement changes, which is what re-sizes the list. */
231
+ private readonly measuredVersion;
232
+ /** Each item's key, or null when items are their own. */
233
+ private readonly keys;
234
+ private keyAt;
235
+ /**
236
+ * Each row's size and where it starts, for variable heights; uniform rows need no index at all.
237
+ * Built once per change of items. A measurement changes it in place and bumps
238
+ * `measuredVersion`, which is what everything that reads it depends on, so a row laying out
239
+ * costs a walk of the tree rather than a rebuild of every offset.
240
+ */
241
+ private readonly table;
242
+ /** Where each key is, so a measurement finds its row without a search. */
243
+ private readonly indexOfKey;
244
+ /** The index, with a dependency on its measurements for whoever is reading it. */
245
+ private layout;
246
+ /** The list's own total extent along its axis. */
247
+ private readonly extent;
248
+ protected readonly canvas: import("@angular/core").Signal<{
249
+ width: number;
250
+ flexDirection: string;
251
+ height?: undefined;
252
+ } | {
253
+ height: number;
254
+ width?: undefined;
255
+ flexDirection?: undefined;
256
+ }>;
257
+ /**
258
+ * `scaleY: -1` on the list, and the same on every row.
259
+ *
260
+ * The list ends up scrolled from the far end with its rows in reverse, and the second flip puts
261
+ * each row's own content back the right way up. It is what `FlatList` does, and it is why an
262
+ * inverted list needs no reversed array and no reversed maths.
263
+ */
264
+ protected readonly flip: import("@angular/core").Signal<Readonly<Record<string, number>>[] | undefined>;
265
+ /**
266
+ * The flip as a style's transform: CSS text, which the engine turns into the list native reads.
267
+ * A style binding validates its values as the DOM's, and warns on a list in development.
268
+ */
269
+ private readonly flipText;
270
+ /** A row in flow, flipped back when the list is inverted. One object, so rows never re-clone. */
271
+ private readonly flowStyle;
272
+ /** Top of a row. */
273
+ private topOf;
274
+ private heightOf;
275
+ /** First row whose bottom is past `y`. */
276
+ private indexAt;
277
+ /** The row the viewport's leading edge is in, taken at each scroll. */
278
+ private anchor;
279
+ /** The last offset seen. A field rather than a signal: reading it renders nothing. */
280
+ private lastOffset;
281
+ /**
282
+ * A correction to make once the commit that needs it is on its way to native: an offset in the
283
+ * rows' own space, after the header, or the very start of the list.
284
+ */
285
+ private pendingScroll;
286
+ /** What moves the rows: which items, and where each one is. */
287
+ private readonly placement;
288
+ /**
289
+ * The first *visible* row, not the first rendered one, and not the raw scroll offset. A fling
290
+ * produces a scroll event per frame, and setting a signal on each one costs a change-detection
291
+ * pass even when the visible rows are identical. Deriving the index in the handler means most
292
+ * scroll events change nothing and cost nothing.
293
+ *
294
+ * Linked to the rows' placement, because that is when the row on screen can move without the
295
+ * user scrolling: an insert above it, or a row above it measuring differently from its estimate.
296
+ * The index follows the anchored row there, and the offset follows it too.
297
+ */
298
+ private readonly visible;
299
+ /** Take the anchor at a row, keeping the viewport where it is. */
300
+ private anchorAt;
301
+ /**
302
+ * Where the row on screen went when the rows moved under it, and the offset that keeps it where
303
+ * the user left it. An insert or a removal is only held when the caller asked for it; a row
304
+ * above measuring differently always is, since nothing the user did moved anything.
305
+ */
306
+ private reanchor;
307
+ /**
308
+ * The row under the offset native is still at, in rows that have just replaced the old ones, as
309
+ * a filter replaces them. Native keeps its offset whatever the items became, so the window is
310
+ * worked out from that, not from the old row's index, which in the new rows sits somewhere else.
311
+ * When the new rows end before that offset, the list is scrolled back to their end: native
312
+ * would otherwise stay scrolled past it, showing nothing until the next drag.
313
+ */
314
+ private atOffset;
315
+ /**
316
+ * The index to hold the viewport at, -1 to let it move, or the start of the list when an
317
+ * insert lands within the autoscroll threshold of it.
318
+ */
319
+ private heldIndex;
320
+ /** Scroll to what arrived at the start, rather than holding the viewport past it. */
321
+ private showStart;
322
+ /**
323
+ * The anchored row's new index, or the first row after it that survived when it did not. Only
324
+ * the rows that were rendered are searched for a successor: past those the viewport has moved
325
+ * on, and holding it by something off screen would be holding it by nothing the user saw.
326
+ */
327
+ private successorOf;
328
+ /** Make a queued correction, after the commit that moved the rows has gone to native. */
329
+ private flushScroll;
330
+ constructor();
331
+ /** The rows to render, and the edges of the run they sit in. */
332
+ private readonly span;
333
+ readonly window: import("@angular/core").Signal<VirtualRow<T>[]>;
334
+ /**
335
+ * What stands in for the rows above the window when rows are in flow: their total extent, less
336
+ * a pinned row's, which is rendered in flow ahead of the window.
337
+ */
338
+ protected readonly spacer: import("@angular/core").Signal<{
339
+ width: number;
340
+ height?: undefined;
341
+ } | {
342
+ height: number;
343
+ width?: undefined;
344
+ }>;
345
+ /** The rows from `first` up to `last`, and the pinned row above them if there is one. */
346
+ private rowsFor;
347
+ /**
348
+ * A pinned row native moves stays at its own place, so the rows between it and the window are
349
+ * made up before the window rather than after the row: new props on a view native is moving
350
+ * put its transform back for a frame.
351
+ */
352
+ private leadWindow;
353
+ private styleFor;
354
+ /** A pinned row in flow, moved from where flow put it to the leading edge by a transform. */
355
+ private pinnedFlowStyle;
356
+ /**
357
+ * A sticky row native moves: at its own place, with the translate native had reached when
358
+ * scrolling paused, so the props agree with what is on screen.
359
+ */
360
+ private stickyStyle;
361
+ /** Each sticky row, and the one after it, which pushes it off. */
362
+ private readonly nextSticky;
363
+ /** Where a sticky row stops, pushed off by the next: that row's top, less this row's size. */
364
+ private stopOf;
365
+ /**
366
+ * How native moves a rendered row, or null when it does not: along the scroll view's own
367
+ * offset, which counts the header, from the row's top until the next sticky row pushes it off.
368
+ */
369
+ private stickyDrive;
370
+ /**
371
+ * Hand each rendered sticky row's view to native to move, and let go of the rest. The rows'
372
+ * views are the canvas's element children in window order, after the spacer, which is how
373
+ * `@for` over `window()` leaves them.
374
+ */
375
+ private driveStickyRows;
376
+ /** Which recycling slot each rendered item holds, by key: its type, and the row it last drew. */
377
+ private readonly recycled;
378
+ /** Slots that have left the window and are kept hidden, by the type of row that held them. */
379
+ private readonly parked;
380
+ private nextSlot;
381
+ /** Note the row a slot is drawing, for parking it once it leaves. */
382
+ private hold;
383
+ /**
384
+ * Park the slots of the items that have left the window, for the items arriving.
385
+ *
386
+ * Parked rather than freed: a slot missing from the window is destroyed by `@for`, so a slot is
387
+ * only reused if a row of its type arrives in the same pass as it left. Kept rendered and
388
+ * hidden, it waits for the next row of its type however many passes later, which is what a
389
+ * reuse queue of cells does in UIKit.
390
+ */
391
+ private releaseRecycled;
392
+ /**
393
+ * Keep a few hidden slots of each type once this pass has taken what it needs, dropping the
394
+ * oldest: `@for` destroys the views of a slot that leaves the window for good.
395
+ */
396
+ private trimParked;
397
+ /** A parked row for a slot that never drew, which only a slot taken and left in one pass is. */
398
+ private placeholder;
399
+ private recycledSlot;
400
+ /**
401
+ * A row laid itself out; what `virtualListRow` calls. Only a row that sizes itself is measured,
402
+ * and a height that has not changed changes nothing.
403
+ */
404
+ measureRow(row: VirtualRow<T>, layout: {
405
+ width?: number;
406
+ height?: number;
407
+ } | undefined): void;
408
+ /** Drop the measurements of items long gone, so churn cannot grow the map without bound. */
409
+ private forgetDeparted;
410
+ /** A separator for every rendered row but the list's last, in its leading row's slot. */
411
+ protected readonly gaps: import("@angular/core").Signal<Gap<T>[]>;
412
+ /** The row's own slot, laid out to put the separator at its trailing edge. */
413
+ private gapStyle;
414
+ /**
415
+ * A measured row's slot, over the row itself: nothing until its height is known, since drawing
416
+ * it at the estimate would put a line through the middle of a row that turns out taller.
417
+ */
418
+ private measuredGapStyle;
419
+ /**
420
+ * The header's translation while it is pinned: the scroll position, held back at zero by an
421
+ * overscroll and at the first sticky row, which pushes it off.
422
+ */
423
+ protected readonly headerStyle: import("@angular/core").Signal<{
424
+ transform: string;
425
+ zIndex?: undefined;
426
+ } | {
427
+ zIndex: number;
428
+ transform: string;
429
+ } | {
430
+ zIndex: number;
431
+ transform?: undefined;
432
+ } | undefined>;
433
+ /**
434
+ * The footer, flipped back like every row when the list is inverted, as FlatList inverts its
435
+ * header and footer cells too; otherwise both read upside down.
436
+ */
437
+ protected readonly footerStyle: import("@angular/core").Signal<{
438
+ transform: string;
439
+ } | undefined>;
440
+ /**
441
+ * The sticky row currently holding the leading edge: the last one at or before the offset.
442
+ * Null when the list has scrolled back above the first of them.
443
+ */
444
+ private readonly pinnedIndex;
445
+ /** Which rows are on screen far enough to count, by the caller's threshold. */
446
+ private viewableAt;
447
+ /** The last set announced, so the output fires on a change rather than on every frame. */
448
+ private announced;
449
+ /**
450
+ * Announce a change in what is on screen.
451
+ *
452
+ * Deliberately not a `computed` over a signal offset. A fling produces a scroll event per
453
+ * frame, and writing a signal on each one costs a change-detection pass whether or not anything
454
+ * moved into view; comparing here costs an array walk over the window and emits only when the
455
+ * set really changed.
456
+ */
457
+ private announceViewable;
458
+ /**
459
+ * Scroll so that a row is at the start of the viewport, less `viewOffset`. The window moves
460
+ * there at once, and the row is held there while the rows around it are measured.
461
+ */
462
+ scrollToIndex(options: {
463
+ index: number;
464
+ animated?: boolean;
465
+ viewOffset?: number;
466
+ }): void;
467
+ /** Scroll to an offset along the list's own axis: x when it is horizontal, y otherwise. */
468
+ scrollToOffset(options: {
469
+ offset: number;
470
+ animated?: boolean;
471
+ }): void;
472
+ scrollToEnd(options?: {
473
+ animated?: boolean;
474
+ }): void;
475
+ private slotStyle;
476
+ protected onScroll(event: NativeSyntheticEvent<{
477
+ contentOffset?: {
478
+ x?: number;
479
+ y?: number;
480
+ };
481
+ }>): void;
482
+ /** RN's sticky header commits its translate after 64 ms without a scroll event, as this does. */
483
+ private settleAfterPause;
484
+ protected onLayout(event: NativeSyntheticEvent<{
485
+ layout?: {
486
+ width?: number;
487
+ height?: number;
488
+ };
489
+ }>): void;
490
+ /** The header's extent along the axis, which every row sits after. */
491
+ protected onHeaderLayout(event: NativeSyntheticEvent<{
492
+ layout?: {
493
+ width?: number;
494
+ height?: number;
495
+ };
496
+ }>): void;
497
+ /**
498
+ * The header grew or shrank - a typing indicator in a chat's, a banner in a feed's - and every
499
+ * row moved with it. Held like an insert when the caller asked for that and the viewport is
500
+ * past the header, among the rows; at the start the user is looking at the header, and it is
501
+ * left to push the rows along. Made at once rather than after a render, because a layout arrives
502
+ * outside change detection and nothing else may be about to render.
503
+ */
504
+ private holdPastHeader;
505
+ protected onContentSize(event: NativeSyntheticEvent<{
506
+ width?: number;
507
+ height?: number;
508
+ }>): void;
509
+ private checkEnd;
510
+ static ɵfac: i0.ɵɵFactoryDeclaration<VirtualList<any>, never>;
511
+ static ɵcmp: i0.ɵɵComponentDeclaration<VirtualList<any>, "virtual-list", ["virtualList"], { "items": { "alias": "items"; "required": true; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "estimatedItemHeight": { "alias": "estimatedItemHeight"; "required": false; "isSignal": true; }; "keyExtractor": { "alias": "keyExtractor"; "required": false; "isSignal": true; }; "itemType": { "alias": "itemType"; "required": false; "isSignal": true; }; "maintainVisibleContentPosition": { "alias": "maintainVisibleContentPosition"; "required": false; "isSignal": true; }; "overscan": { "alias": "overscan"; "required": false; "isSignal": true; }; "endReachedThreshold": { "alias": "endReachedThreshold"; "required": false; "isSignal": true; }; "horizontal": { "alias": "horizontal"; "required": false; "isSignal": true; }; "inverted": { "alias": "inverted"; "required": false; "isSignal": true; }; "stickyIndices": { "alias": "stickyIndices"; "required": false; "isSignal": true; }; "stickyHeader": { "alias": "stickyHeader"; "required": false; "isSignal": true; }; "keyboardShouldPersistTaps": { "alias": "keyboardShouldPersistTaps"; "required": false; "isSignal": true; }; "itemVisiblePercentThreshold": { "alias": "itemVisiblePercentThreshold"; "required": false; "isSignal": true; }; }, { "endReached": "endReached"; "viewableItemsChanged": "viewableItemsChanged"; }, ["separator", "refreshControl"], ["refresh-control", "[listHeader]", "*", "[listFooter]"], true, never>;
512
+ }
513
+ /**
514
+ * Put on each row's view: `<view [virtualListRow]="row">`. Applies the row's style, and reports
515
+ * the row's layout to the list, which is how a list of rows that size themselves learns how tall
516
+ * each one is.
517
+ */
518
+ export declare class VirtualListRow<T = unknown> {
519
+ readonly row: import("@angular/core").InputSignal<VirtualRow<T>>;
520
+ private readonly list;
521
+ protected onLayout(event: NativeSyntheticEvent<{
522
+ layout?: {
523
+ width?: number;
524
+ height?: number;
525
+ };
526
+ }>): void;
527
+ static ɵfac: i0.ɵɵFactoryDeclaration<VirtualListRow<any>, never>;
528
+ static ɵdir: i0.ɵɵDirectiveDeclaration<VirtualListRow<any>, "[virtualListRow]", never, { "row": { "alias": "virtualListRow"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
529
+ }
530
+ export {};