@legendapp/list 3.0.0-beta.43 → 3.0.0-beta.45

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.
package/section-list.d.ts CHANGED
@@ -59,16 +59,28 @@ type BuildSectionListDataResult<ItemT, SectionT> = {
59
59
  stickyHeaderIndices: number[];
60
60
  };
61
61
 
62
- type ListenerType = "activeStickyIndex" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
63
- type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
62
+ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
63
+ data: boolean;
64
+ size: boolean;
65
+ shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
66
+ }
67
+
68
+ type ListenerType = "activeStickyIndex" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
69
+ type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
64
70
  type ListenerTypeValueMap = {
65
71
  activeStickyIndex: number;
72
+ anchoredEndSpaceSize: number;
66
73
  animatedScrollY: any;
67
74
  debugComputedScroll: number;
68
75
  debugRawScroll: number;
69
76
  extraData: any;
70
77
  footerSize: number;
71
78
  headerSize: number;
79
+ isAtEnd: boolean;
80
+ isAtStart: boolean;
81
+ isNearEnd: boolean;
82
+ isNearStart: boolean;
83
+ isWithinMaintainScrollAtEndThreshold: boolean;
72
84
  lastItemKeys: string[];
73
85
  lastPositionUpdate: number;
74
86
  maintainVisibleContentPosition: MaintainVisibleContentPositionNormalized;
@@ -170,6 +182,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
170
182
  * Style applied to each column's wrapper view.
171
183
  */
172
184
  columnWrapperStyle?: ColumnWrapperStyle;
185
+ /**
186
+ * Version token that forces the list to treat data as updated even when the array reference is stable.
187
+ * Increment or change this when mutating the data array in place.
188
+ */
189
+ dataVersion?: Key;
173
190
  /**
174
191
  * Distance in pixels to pre-render items ahead of the visible area.
175
192
  * @default 250
@@ -193,33 +210,35 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
193
210
  * Extra data to trigger re-rendering when changed.
194
211
  */
195
212
  extraData?: any;
196
- /**
197
- * Version token that forces the list to treat data as updated even when the array reference is stable.
198
- * Increment or change this when mutating the data array in place.
199
- */
200
- dataVersion?: Key;
201
213
  /**
202
214
  * In case you have distinct item sizes, you can provide a function to get the size of an item.
203
- * Use instead of FlatList's getItemLayout or FlashList overrideItemLayout if you want to have accurate initialScrollOffset, you should provide this function
204
215
  */
205
216
  getEstimatedItemSize?: (item: ItemT, index: number, type: TItemType) => number;
206
217
  /**
207
- * Customize layout for multi-column lists, such as allowing items to span multiple columns.
208
- * Similar to FlashList's overrideItemLayout.
218
+ * In case items always have a fixed size, you can provide a function to return it.
209
219
  */
210
- overrideItemLayout?: (layout: {
211
- span?: number;
212
- }, item: ItemT, index: number, maxColumns: number, extraData?: any) => void;
220
+ getFixedItemSize?: (item: ItemT, index: number, type: TItemType) => number | undefined;
221
+ /**
222
+ * Returns a stable item type used for pooling and size estimation.
223
+ */
224
+ getItemType?: (item: ItemT, index: number) => TItemType;
225
+ /**
226
+ * Component to render between items, receiving the leading item as prop.
227
+ */
228
+ ItemSeparatorComponent?: React.ComponentType<{
229
+ leadingItem: ItemT;
230
+ }>;
213
231
  /**
214
232
  * Ratio of initial container pool size to data length (e.g., 0.5 for half).
215
233
  * @default 2
216
234
  */
217
235
  initialContainerPoolRatio?: number | undefined;
218
236
  /**
219
- * Initial scroll position in pixels.
220
- * @default 0
237
+ * When true, the list initializes scrolled to the last item.
238
+ * Overrides `initialScrollIndex` and `initialScrollOffset` when data is available.
239
+ * @default false
221
240
  */
222
- initialScrollOffset?: number;
241
+ initialScrollAtEnd?: boolean;
223
242
  /**
224
243
  * Index to scroll to initially.
225
244
  * @default 0
@@ -230,17 +249,14 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
230
249
  viewPosition?: number | undefined;
231
250
  };
232
251
  /**
233
- * When true, the list initializes scrolled to the last item.
234
- * Overrides `initialScrollIndex` and `initialScrollOffset` when data is available.
235
- * @default false
252
+ * Initial scroll position in pixels.
253
+ * @default 0
236
254
  */
237
- initialScrollAtEnd?: boolean;
255
+ initialScrollOffset?: number;
238
256
  /**
239
- * Component to render between items, receiving the leading item as prop.
257
+ * Custom equality function to detect semantically unchanged items.
240
258
  */
241
- ItemSeparatorComponent?: React.ComponentType<{
242
- leadingItem: ItemT;
243
- }>;
259
+ itemsAreEqual?: (itemPrevious: ItemT, item: ItemT, index: number, data: readonly ItemT[]) => boolean;
244
260
  /**
245
261
  * Function to extract a unique key for each item.
246
262
  */
@@ -286,10 +302,9 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
286
302
  */
287
303
  maintainVisibleContentPosition?: boolean | MaintainVisibleContentPositionConfig<ItemT>;
288
304
  /**
289
- * Web only: when true, listens to window/body scrolling instead of rendering a scrollable list container.
290
- * @default false
305
+ * Keeps an item visually anchored to the start by adding trailing space when the content below it underflows.
291
306
  */
292
- useWindowScroll?: boolean;
307
+ anchoredEndSpace?: AnchoredEndSpaceConfig;
293
308
  /**
294
309
  * Number of columns to render items in.
295
310
  * @default 1
@@ -316,6 +331,12 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
316
331
  itemKey: string;
317
332
  itemData: ItemT;
318
333
  }) => void;
334
+ /**
335
+ * Called after the initial render work completes.
336
+ */
337
+ onLoad?: (info: {
338
+ elapsedTimeInMs: number;
339
+ }) => void;
319
340
  /**
320
341
  * Called when list layout metrics change.
321
342
  */
@@ -324,6 +345,9 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
324
345
  * Function to call when the user pulls to refresh.
325
346
  */
326
347
  onRefresh?: () => void;
348
+ /**
349
+ * Called when the list scrolls.
350
+ */
327
351
  onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
328
352
  /**
329
353
  * Called when scrolling reaches the start within onStartReachedThreshold.
@@ -347,6 +371,12 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
347
371
  * Called when the viewability of items changes.
348
372
  */
349
373
  onViewableItemsChanged?: OnViewableItemsChanged<ItemT> | undefined;
374
+ /**
375
+ * Customize layout for multi-column lists, such as allowing items to span multiple columns.
376
+ */
377
+ overrideItemLayout?: (layout: {
378
+ span?: number;
379
+ }, item: ItemT, index: number, maxColumns: number, extraData?: any) => void;
350
380
  /**
351
381
  * Offset in pixels for the refresh indicator.
352
382
  * @default 0
@@ -372,6 +402,10 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
372
402
  * @default (props) => <ScrollView {...props} />
373
403
  */
374
404
  renderScrollComponent?: (props: any) => React.ReactElement | null;
405
+ /**
406
+ * Array of item indices to use as snap points.
407
+ */
408
+ snapToIndices?: number[];
375
409
  /**
376
410
  * This will log a suggested estimatedItemSize.
377
411
  * @required
@@ -386,15 +420,6 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
386
420
  * Pairs of viewability configs and their callbacks for tracking visibility.
387
421
  */
388
422
  viewabilityConfigCallbackPairs?: ViewabilityConfigCallbackPairs<ItemT> | undefined;
389
- /**
390
- * If true, delays rendering until initial layout is complete.
391
- * @default false
392
- */
393
- waitForInitialLayout?: boolean;
394
- onLoad?: (info: {
395
- elapsedTimeInMs: number;
396
- }) => void;
397
- snapToIndices?: number[];
398
423
  /**
399
424
  * Array of child indices determining which children get docked to the top of the screen when scrolling.
400
425
  * For example, passing stickyHeaderIndices={[0]} will cause the first child to be fixed to the top of the scroll view.
@@ -411,9 +436,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
411
436
  * @default undefined
412
437
  */
413
438
  stickyHeaderConfig?: StickyHeaderConfig;
414
- getItemType?: (item: ItemT, index: number) => TItemType;
415
- getFixedItemSize?: (item: ItemT, index: number, type: TItemType) => number | undefined;
416
- itemsAreEqual?: (itemPrevious: ItemT, item: ItemT, index: number, data: readonly ItemT[]) => boolean;
439
+ /**
440
+ * Web only: when true, listens to window/body scrolling instead of rendering a scrollable list container.
441
+ * @default false
442
+ */
443
+ useWindowScroll?: boolean;
417
444
  }
418
445
  type LegendListPropsBase<ItemT, TScrollViewProps = Record<string, any>, TItemType extends string | undefined = string | undefined> = BaseScrollViewProps<TScrollViewProps> & LegendListSpecificProps<ItemT, TItemType> & (DataModeProps<ItemT, TItemType> | ChildrenModeProps);
419
446
  interface MaintainVisibleContentPositionConfig<ItemT = any> {
@@ -421,10 +448,12 @@ interface MaintainVisibleContentPositionConfig<ItemT = any> {
421
448
  size?: boolean;
422
449
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
423
450
  }
424
- interface MaintainVisibleContentPositionNormalized<ItemT = any> {
425
- data: boolean;
426
- size: boolean;
427
- shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
451
+ interface AnchoredEndSpaceConfig {
452
+ anchorIndex: number;
453
+ anchorOffset?: number;
454
+ anchorMaxSize?: number;
455
+ includeInEndInset?: boolean;
456
+ onSizeChanged?: (size: number) => void;
428
457
  }
429
458
  interface StickyHeaderConfig {
430
459
  /**
@@ -487,8 +516,11 @@ type LegendListState = {
487
516
  endBuffered: number;
488
517
  isAtEnd: boolean;
489
518
  isAtStart: boolean;
519
+ isNearEnd: boolean;
520
+ isNearStart: boolean;
490
521
  isEndReached: boolean;
491
522
  isStartReached: boolean;
523
+ isWithinMaintainScrollAtEndThreshold: boolean;
492
524
  listen: <T extends LegendListListenerType>(listenerType: T, callback: (value: ListenerTypeValueMap[T]) => void) => () => void;
493
525
  listenToPosition: (key: string, callback: (value: number) => void) => () => void;
494
526
  positionAtIndex: (index: number) => number;
@@ -627,10 +659,15 @@ interface ViewabilityConfigCallbackPair<ItemT = any> {
627
659
  viewabilityConfig: ViewabilityConfig;
628
660
  }
629
661
  type ViewabilityConfigCallbackPairs<ItemT> = ViewabilityConfigCallbackPair<ItemT>[];
630
- type OnViewableItemsChanged<ItemT> = ((info: {
631
- viewableItems: Array<ViewToken<ItemT>>;
662
+ interface OnViewableItemsChangedInfo<ItemT> {
632
663
  changed: Array<ViewToken<ItemT>>;
633
- }) => void) | null;
664
+ end: number;
665
+ endBuffered: number;
666
+ start: number;
667
+ startBuffered: number;
668
+ viewableItems: Array<ViewToken<ItemT>>;
669
+ }
670
+ type OnViewableItemsChanged<ItemT> = ((info: OnViewableItemsChangedInfo<ItemT>) => void) | null;
634
671
  interface ViewabilityConfig {
635
672
  /**
636
673
  * A unique ID to identify this viewability config
@@ -661,7 +698,7 @@ interface ViewabilityConfig {
661
698
  waitForInteraction?: boolean | undefined;
662
699
  }
663
700
 
664
- type LegendListPropsOverrides<ItemT, TItemType extends string | undefined> = Omit<LegendListPropsBase<ItemT, ScrollViewProps, TItemType>, "onScroll" | "refScrollView" | "renderScrollComponent" | "ListHeaderComponentStyle" | "ListFooterComponentStyle"> & {
701
+ type LegendListPropsOverrides<ItemT, TItemType extends string | undefined> = Omit<LegendListPropsBase<ItemT, ScrollViewProps, TItemType>, "anchoredEndSpace" | "onScroll" | "refScrollView" | "renderScrollComponent" | "ListHeaderComponentStyle" | "ListFooterComponentStyle"> & {
665
702
  onScroll?: (event: NativeSyntheticEvent$1<NativeScrollEvent$1>) => void;
666
703
  refScrollView?: React.Ref<ScrollView>;
667
704
  renderScrollComponent?: (props: ScrollViewProps) => React.ReactElement<ScrollViewProps>;
@@ -683,8 +720,12 @@ type SectionListViewToken<ItemT, SectionT> = {
683
720
  section: SectionListData<ItemT, SectionT>;
684
721
  };
685
722
  type SectionListOnViewableItemsChanged<ItemT, SectionT> = ((info: {
723
+ end: number;
724
+ endBuffered: number;
686
725
  viewableItems: Array<SectionListViewToken<ItemT, SectionT>>;
687
726
  changed: Array<SectionListViewToken<ItemT, SectionT>>;
727
+ start: number;
728
+ startBuffered: number;
688
729
  }) => void) | null;
689
730
  type SectionListLegendProps<ItemT, SectionT> = Omit<LegendListProps<FlatSectionListItem<ItemT, SectionT>>, "data" | "children" | "renderItem" | "keyExtractor" | "ItemSeparatorComponent" | "getItemType" | "getFixedItemSize" | "stickyHeaderIndices" | "numColumns" | "columnWrapperStyle" | "onViewableItemsChanged">;
690
731
  type SectionListProps<ItemT, SectionT extends SectionBase<ItemT> = SectionBase<ItemT>> = SectionListLegendProps<ItemT, SectionT> & {
package/section-list.js CHANGED
@@ -123,6 +123,7 @@ function buildSectionListData({
123
123
  }
124
124
 
125
125
  // src/section-list/SectionList.tsx
126
+ var { typedForwardRef, typedMemo } = reactNative.internal;
126
127
  var defaultSeparators = {
127
128
  highlight: () => {
128
129
  },
@@ -139,8 +140,8 @@ function resolveSeparatorComponent(component, props) {
139
140
  const Component = component;
140
141
  return /* @__PURE__ */ React__namespace.createElement(Component, { ...props });
141
142
  }
142
- var SectionList = reactNative.typedMemo(
143
- reactNative.typedForwardRef(function SectionListInner(props, ref) {
143
+ var SectionList = typedMemo(
144
+ typedForwardRef(function SectionListInner(props, ref) {
144
145
  const {
145
146
  sections,
146
147
  renderItem: renderItemProp,
@@ -183,7 +184,11 @@ var SectionList = reactNative.typedMemo(
183
184
  if (!onViewableItemsChanged) return void 0;
184
185
  return ({
185
186
  viewableItems,
186
- changed
187
+ changed,
188
+ start,
189
+ end,
190
+ startBuffered,
191
+ endBuffered
187
192
  }) => {
188
193
  const mapToken = (token) => {
189
194
  if (token.item.kind !== "item") return null;
@@ -197,7 +202,14 @@ var SectionList = reactNative.typedMemo(
197
202
  };
198
203
  const mappedViewable = viewableItems.map(mapToken).filter(Boolean);
199
204
  const mappedChanged = changed.map(mapToken).filter(Boolean);
200
- onViewableItemsChanged({ changed: mappedChanged, viewableItems: mappedViewable });
205
+ onViewableItemsChanged({
206
+ changed: mappedChanged,
207
+ end,
208
+ endBuffered,
209
+ start,
210
+ startBuffered,
211
+ viewableItems: mappedViewable
212
+ });
201
213
  };
202
214
  }, [onViewableItemsChanged]);
203
215
  const renderItem = React__namespace.useCallback(
package/section-list.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { Platform } from 'react-native';
3
- import { typedMemo, typedForwardRef, LegendList } from '@legendapp/list/react-native';
3
+ import { internal, LegendList } from '@legendapp/list/react-native';
4
4
 
5
5
  // src/section-list/SectionList.tsx
6
6
 
@@ -101,6 +101,7 @@ function buildSectionListData({
101
101
  }
102
102
 
103
103
  // src/section-list/SectionList.tsx
104
+ var { typedForwardRef, typedMemo } = internal;
104
105
  var defaultSeparators = {
105
106
  highlight: () => {
106
107
  },
@@ -161,7 +162,11 @@ var SectionList = typedMemo(
161
162
  if (!onViewableItemsChanged) return void 0;
162
163
  return ({
163
164
  viewableItems,
164
- changed
165
+ changed,
166
+ start,
167
+ end,
168
+ startBuffered,
169
+ endBuffered
165
170
  }) => {
166
171
  const mapToken = (token) => {
167
172
  if (token.item.kind !== "item") return null;
@@ -175,7 +180,14 @@ var SectionList = typedMemo(
175
180
  };
176
181
  const mappedViewable = viewableItems.map(mapToken).filter(Boolean);
177
182
  const mappedChanged = changed.map(mapToken).filter(Boolean);
178
- onViewableItemsChanged({ changed: mappedChanged, viewableItems: mappedViewable });
183
+ onViewableItemsChanged({
184
+ changed: mappedChanged,
185
+ end,
186
+ endBuffered,
187
+ start,
188
+ startBuffered,
189
+ viewableItems: mappedViewable
190
+ });
179
191
  };
180
192
  }, [onViewableItemsChanged]);
181
193
  const renderItem = React.useCallback(