@legendapp/list 3.0.6 → 3.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 3.1.1
2
+
3
+ - Fix: `maintainScrollAtEnd` now stays pinned when a `ListFooterComponent` appears, disappears, or changes size, so chat typing indicators and other dynamic footers do not leave the list slightly above the end. If you use an explicit `maintainScrollAtEnd.on` config, add `footerLayout` to opt into footer size changes.
4
+
5
+ ## 3.1.0
6
+
7
+ - Feat: Add `experimental_adaptiveRender` prop, with `useAdaptiveRender` and `useAdaptiveRenderChange` hooks, so item components can render a lighter version while the list is moving quickly and return to normal after scrolling slows.
8
+ - Feat: Add `setItemSize` to the list ref for updating a known item's measured size directly when its content changes outside normal layout measurement.
9
+ - Fix: Web maintainVisibleContentPosition keeps the intended anchor when headers change, browser scroll anchoring runs, or an animated `scrollToEnd` is already in progress. #468 #463
10
+ - Fix: `initialScrollIndex` and `initialScrollAtEnd` use the latest initial scroll props when data starts empty and loads later, so lists do not scroll to an old startup target.
11
+ - Fix: Changing `gap` now refreshes cached item measurements, and fixed-size rows include the gap in their positions.
12
+ - Fix: SectionList sticky headers update after the section data changes. #445
13
+ - Fix: Horizontal lists with end alignment now place items at the end instead of ignoring the alignment. #472
14
+ - Fix: Lists clear scheduled timers on unmount, preventing delayed adaptive-render or scroll work from running after the list is gone.
15
+ - Perf: The first render starts with a smaller draw distance and expands shortly after, reducing offscreen work before the initial content appears.
16
+ - Perf: `alignItemsAtEnd` spacer updates cause fewer ScrollView rerenders.
17
+ - Types: Export `AdaptiveRender` and `AdaptiveRenderConfig` from the React Native and web type entrypoints.
18
+
1
19
  ## 3.0.6
2
20
 
3
21
  - Fix: KeyboardAwareLegendList now accounts for bottom insets when alignItemsAtEnd is used, so short chat-style lists stay pinned above the keyboard or safe area instead of being pushed too low or leaving extra scroll space.
package/animated.d.ts CHANGED
@@ -8,8 +8,8 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
8
8
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
9
9
  }
10
10
 
11
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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}`;
12
- type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
11
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
12
+ type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
13
13
  type ListenerTypeValueMap = {
14
14
  activeStickyIndex: number;
15
15
  alignItemsAtEndPadding: number;
@@ -43,6 +43,7 @@ type ListenerTypeValueMap = {
43
43
  snapToOffsets: number[];
44
44
  stylePaddingTop: number;
45
45
  totalSize: number;
46
+ adaptiveRender: "normal" | "light";
46
47
  } & {
47
48
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
48
49
  } & {
@@ -63,6 +64,12 @@ interface Insets {
63
64
  bottom: number;
64
65
  right: number;
65
66
  }
67
+ interface LayoutRectangle {
68
+ x: number;
69
+ y: number;
70
+ width: number;
71
+ height: number;
72
+ }
66
73
  interface NativeScrollEvent {
67
74
  contentOffset: {
68
75
  x: number;
@@ -84,6 +91,28 @@ interface NativeSyntheticEvent<T> {
84
91
  }
85
92
  type ViewStyle = Record<string, unknown>;
86
93
  type StyleProp<T> = T | T[] | null | undefined | false;
94
+ type AdaptiveRender = "normal" | "light";
95
+ interface AdaptiveRenderConfig {
96
+ /**
97
+ * Scroll velocity in pixels per millisecond above which items should switch to light mode.
98
+ * @default 4
99
+ */
100
+ enterVelocity?: number;
101
+ /**
102
+ * Scroll velocity in pixels per millisecond below which items can return to normal mode.
103
+ * @default 1
104
+ */
105
+ exitVelocity?: number;
106
+ /**
107
+ * Time to wait without velocity above exitVelocity before returning to normal mode.
108
+ * @default 1000
109
+ */
110
+ exitDelay?: number;
111
+ /**
112
+ * Called when the list-level adaptive render changes.
113
+ */
114
+ onChange?: (mode: AdaptiveRender) => void;
115
+ }
87
116
  type BaseScrollViewProps<TScrollView> = Omit<TScrollView, "contentOffset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children" | "onScroll">;
88
117
  interface DataModeProps<ItemT, TItemType extends string | undefined> {
89
118
  /**
@@ -292,6 +321,10 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
292
321
  * Called when list layout metrics change.
293
322
  */
294
323
  onMetricsChange?: (metrics: LegendListMetrics) => void;
324
+ /**
325
+ * Configures the adaptive render signal. Items can use this to render a lighter version while scrolling quickly.
326
+ */
327
+ experimental_adaptiveRender?: AdaptiveRenderConfig;
295
328
  /**
296
329
  * Function to call when the user pulls to refresh.
297
330
  */
@@ -427,6 +460,7 @@ interface AlwaysRenderConfig {
427
460
  }
428
461
  interface MaintainScrollAtEndOnOptions {
429
462
  dataChange?: boolean;
463
+ footerLayout?: boolean;
430
464
  itemLayout?: boolean;
431
465
  layout?: boolean;
432
466
  }
@@ -490,6 +524,14 @@ type LegendListState = {
490
524
  startBuffered: number;
491
525
  };
492
526
  type LegendListRef$1 = {
527
+ /**
528
+ * Clears internal virtualization caches.
529
+ * @param options - Cache clearing options.
530
+ * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
531
+ */
532
+ clearCaches(options?: {
533
+ mode?: "sizes" | "full";
534
+ }): void;
493
535
  /**
494
536
  * Displays the scroll indicators momentarily.
495
537
  */
@@ -510,6 +552,11 @@ type LegendListRef$1 = {
510
552
  * Returns the internal state of the scroll virtualization.
511
553
  */
512
554
  getState(): LegendListState;
555
+ /**
556
+ * Reports an externally measured content inset. Pass null/undefined to clear.
557
+ * Values are merged on top of props/animated/native insets.
558
+ */
559
+ reportContentInset(inset?: Partial<Insets> | null): void;
513
560
  /**
514
561
  * Scrolls a specific index into view.
515
562
  * @param params - Parameters for scrolling.
@@ -576,29 +623,22 @@ type LegendListRef$1 = {
576
623
  animated?: boolean | undefined;
577
624
  }): Promise<void>;
578
625
  /**
579
- * Sets or adds to the offset of the visible content anchor.
580
- * @param value - The offset to set or add.
581
- * @param animated - If true, uses Animated to animate the change.
626
+ * Sets a measured item size and recalculates list positions as needed.
627
+ * @param itemKey - The key of the item whose size changed.
628
+ * @param size - The measured item size.
582
629
  */
583
- setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
630
+ setItemSize(itemKey: string, size: Pick<LayoutRectangle, "height" | "width">): void;
584
631
  /**
585
632
  * Sets whether scroll processing is enabled.
586
633
  * @param enabled - If true, scroll processing is enabled.
587
634
  */
588
635
  setScrollProcessingEnabled(enabled: boolean): void;
589
636
  /**
590
- * Clears internal virtualization caches.
591
- * @param options - Cache clearing options.
592
- * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
593
- */
594
- clearCaches(options?: {
595
- mode?: "sizes" | "full";
596
- }): void;
597
- /**
598
- * Reports an externally measured content inset. Pass null/undefined to clear.
599
- * Values are merged on top of props/animated/native insets.
637
+ * Sets or adds to the offset of the visible content anchor.
638
+ * @param value - The offset to set or add.
639
+ * @param animated - If true, uses Animated to animate the change.
600
640
  */
601
- reportContentInset(inset?: Partial<Insets> | null): void;
641
+ setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
602
642
  };
603
643
  interface ViewToken<ItemT = any> {
604
644
  containerId: number;
@@ -9,8 +9,8 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
9
9
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
10
10
  }
11
11
 
12
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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}`;
13
- type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
12
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
13
+ type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
14
14
  type ListenerTypeValueMap = {
15
15
  activeStickyIndex: number;
16
16
  alignItemsAtEndPadding: number;
@@ -44,6 +44,7 @@ type ListenerTypeValueMap = {
44
44
  snapToOffsets: number[];
45
45
  stylePaddingTop: number;
46
46
  totalSize: number;
47
+ adaptiveRender: "normal" | "light";
47
48
  } & {
48
49
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
49
50
  } & {
@@ -64,6 +65,12 @@ interface Insets {
64
65
  bottom: number;
65
66
  right: number;
66
67
  }
68
+ interface LayoutRectangle {
69
+ x: number;
70
+ y: number;
71
+ width: number;
72
+ height: number;
73
+ }
67
74
  interface ScrollToEndOptions {
68
75
  animated?: boolean;
69
76
  viewOffset?: number;
@@ -100,6 +107,14 @@ type LegendListState = {
100
107
  startBuffered: number;
101
108
  };
102
109
  type LegendListRef$1 = {
110
+ /**
111
+ * Clears internal virtualization caches.
112
+ * @param options - Cache clearing options.
113
+ * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
114
+ */
115
+ clearCaches(options?: {
116
+ mode?: "sizes" | "full";
117
+ }): void;
103
118
  /**
104
119
  * Displays the scroll indicators momentarily.
105
120
  */
@@ -120,6 +135,11 @@ type LegendListRef$1 = {
120
135
  * Returns the internal state of the scroll virtualization.
121
136
  */
122
137
  getState(): LegendListState;
138
+ /**
139
+ * Reports an externally measured content inset. Pass null/undefined to clear.
140
+ * Values are merged on top of props/animated/native insets.
141
+ */
142
+ reportContentInset(inset?: Partial<Insets> | null): void;
123
143
  /**
124
144
  * Scrolls a specific index into view.
125
145
  * @param params - Parameters for scrolling.
@@ -186,29 +206,22 @@ type LegendListRef$1 = {
186
206
  animated?: boolean | undefined;
187
207
  }): Promise<void>;
188
208
  /**
189
- * Sets or adds to the offset of the visible content anchor.
190
- * @param value - The offset to set or add.
191
- * @param animated - If true, uses Animated to animate the change.
209
+ * Sets a measured item size and recalculates list positions as needed.
210
+ * @param itemKey - The key of the item whose size changed.
211
+ * @param size - The measured item size.
192
212
  */
193
- setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
213
+ setItemSize(itemKey: string, size: Pick<LayoutRectangle, "height" | "width">): void;
194
214
  /**
195
215
  * Sets whether scroll processing is enabled.
196
216
  * @param enabled - If true, scroll processing is enabled.
197
217
  */
198
218
  setScrollProcessingEnabled(enabled: boolean): void;
199
219
  /**
200
- * Clears internal virtualization caches.
201
- * @param options - Cache clearing options.
202
- * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
203
- */
204
- clearCaches(options?: {
205
- mode?: "sizes" | "full";
206
- }): void;
207
- /**
208
- * Reports an externally measured content inset. Pass null/undefined to clear.
209
- * Values are merged on top of props/animated/native insets.
220
+ * Sets or adds to the offset of the visible content anchor.
221
+ * @param value - The offset to set or add.
222
+ * @param animated - If true, uses Animated to animate the change.
210
223
  */
211
- reportContentInset(inset?: Partial<Insets> | null): void;
224
+ setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
212
225
  };
213
226
 
214
227
  type LegendListRef = Omit<LegendListRef$1, "getNativeScrollRef" | "getScrollResponder" | "reportContentInset"> & {
package/keyboard.d.ts CHANGED
@@ -10,8 +10,8 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
10
10
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
11
11
  }
12
12
 
13
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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}`;
14
- type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
13
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
14
+ type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
15
15
  type ListenerTypeValueMap = {
16
16
  activeStickyIndex: number;
17
17
  alignItemsAtEndPadding: number;
@@ -45,6 +45,7 @@ type ListenerTypeValueMap = {
45
45
  snapToOffsets: number[];
46
46
  stylePaddingTop: number;
47
47
  totalSize: number;
48
+ adaptiveRender: "normal" | "light";
48
49
  } & {
49
50
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
50
51
  } & {
@@ -65,6 +66,12 @@ interface Insets {
65
66
  bottom: number;
66
67
  right: number;
67
68
  }
69
+ interface LayoutRectangle {
70
+ x: number;
71
+ y: number;
72
+ width: number;
73
+ height: number;
74
+ }
68
75
  interface AnchoredEndSpaceReadyInfo {
69
76
  anchorIndex: number | undefined;
70
77
  anchorKey: string | undefined;
@@ -114,6 +121,14 @@ type LegendListState = {
114
121
  startBuffered: number;
115
122
  };
116
123
  type LegendListRef$1 = {
124
+ /**
125
+ * Clears internal virtualization caches.
126
+ * @param options - Cache clearing options.
127
+ * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
128
+ */
129
+ clearCaches(options?: {
130
+ mode?: "sizes" | "full";
131
+ }): void;
117
132
  /**
118
133
  * Displays the scroll indicators momentarily.
119
134
  */
@@ -134,6 +149,11 @@ type LegendListRef$1 = {
134
149
  * Returns the internal state of the scroll virtualization.
135
150
  */
136
151
  getState(): LegendListState;
152
+ /**
153
+ * Reports an externally measured content inset. Pass null/undefined to clear.
154
+ * Values are merged on top of props/animated/native insets.
155
+ */
156
+ reportContentInset(inset?: Partial<Insets> | null): void;
137
157
  /**
138
158
  * Scrolls a specific index into view.
139
159
  * @param params - Parameters for scrolling.
@@ -200,29 +220,22 @@ type LegendListRef$1 = {
200
220
  animated?: boolean | undefined;
201
221
  }): Promise<void>;
202
222
  /**
203
- * Sets or adds to the offset of the visible content anchor.
204
- * @param value - The offset to set or add.
205
- * @param animated - If true, uses Animated to animate the change.
223
+ * Sets a measured item size and recalculates list positions as needed.
224
+ * @param itemKey - The key of the item whose size changed.
225
+ * @param size - The measured item size.
206
226
  */
207
- setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
227
+ setItemSize(itemKey: string, size: Pick<LayoutRectangle, "height" | "width">): void;
208
228
  /**
209
229
  * Sets whether scroll processing is enabled.
210
230
  * @param enabled - If true, scroll processing is enabled.
211
231
  */
212
232
  setScrollProcessingEnabled(enabled: boolean): void;
213
233
  /**
214
- * Clears internal virtualization caches.
215
- * @param options - Cache clearing options.
216
- * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
217
- */
218
- clearCaches(options?: {
219
- mode?: "sizes" | "full";
220
- }): void;
221
- /**
222
- * Reports an externally measured content inset. Pass null/undefined to clear.
223
- * Values are merged on top of props/animated/native insets.
234
+ * Sets or adds to the offset of the visible content anchor.
235
+ * @param value - The offset to set or add.
236
+ * @param animated - If true, uses Animated to animate the change.
224
237
  */
225
- reportContentInset(inset?: Partial<Insets> | null): void;
238
+ setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
226
239
  };
227
240
 
228
241
  interface AnchoredEndSpaceConfig extends Omit<AnchoredEndSpaceConfig$1, "includeInEndInset"> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "3.0.6",
3
+ "version": "3.1.1",
4
4
  "description": "Legend List is a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
5
5
  "sideEffects": false,
6
6
  "private": false,
package/react-native.d.ts CHANGED
@@ -8,8 +8,8 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
8
8
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
9
9
  }
10
10
 
11
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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}`;
12
- type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
11
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "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" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
12
+ type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
13
13
  type ListenerTypeValueMap = {
14
14
  activeStickyIndex: number;
15
15
  alignItemsAtEndPadding: number;
@@ -43,6 +43,7 @@ type ListenerTypeValueMap = {
43
43
  snapToOffsets: number[];
44
44
  stylePaddingTop: number;
45
45
  totalSize: number;
46
+ adaptiveRender: "normal" | "light";
46
47
  } & {
47
48
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
48
49
  } & {
@@ -90,6 +91,28 @@ interface NativeSyntheticEvent<T> {
90
91
  }
91
92
  type ViewStyle = Record<string, unknown>;
92
93
  type StyleProp<T> = T | T[] | null | undefined | false;
94
+ type AdaptiveRender = "normal" | "light";
95
+ interface AdaptiveRenderConfig {
96
+ /**
97
+ * Scroll velocity in pixels per millisecond above which items should switch to light mode.
98
+ * @default 4
99
+ */
100
+ enterVelocity?: number;
101
+ /**
102
+ * Scroll velocity in pixels per millisecond below which items can return to normal mode.
103
+ * @default 1
104
+ */
105
+ exitVelocity?: number;
106
+ /**
107
+ * Time to wait without velocity above exitVelocity before returning to normal mode.
108
+ * @default 1000
109
+ */
110
+ exitDelay?: number;
111
+ /**
112
+ * Called when the list-level adaptive render changes.
113
+ */
114
+ onChange?: (mode: AdaptiveRender) => void;
115
+ }
93
116
  type BaseScrollViewProps<TScrollView> = Omit<TScrollView, "contentOffset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children" | "onScroll">;
94
117
  interface DataModeProps<ItemT, TItemType extends string | undefined> {
95
118
  /**
@@ -298,6 +321,10 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
298
321
  * Called when list layout metrics change.
299
322
  */
300
323
  onMetricsChange?: (metrics: LegendListMetrics) => void;
324
+ /**
325
+ * Configures the adaptive render signal. Items can use this to render a lighter version while scrolling quickly.
326
+ */
327
+ experimental_adaptiveRender?: AdaptiveRenderConfig;
301
328
  /**
302
329
  * Function to call when the user pulls to refresh.
303
330
  */
@@ -433,6 +460,7 @@ interface AlwaysRenderConfig {
433
460
  }
434
461
  interface MaintainScrollAtEndOnOptions {
435
462
  dataChange?: boolean;
463
+ footerLayout?: boolean;
436
464
  itemLayout?: boolean;
437
465
  layout?: boolean;
438
466
  }
@@ -496,6 +524,14 @@ type LegendListState$1 = {
496
524
  startBuffered: number;
497
525
  };
498
526
  type LegendListRef$1 = {
527
+ /**
528
+ * Clears internal virtualization caches.
529
+ * @param options - Cache clearing options.
530
+ * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
531
+ */
532
+ clearCaches(options?: {
533
+ mode?: "sizes" | "full";
534
+ }): void;
499
535
  /**
500
536
  * Displays the scroll indicators momentarily.
501
537
  */
@@ -516,6 +552,11 @@ type LegendListRef$1 = {
516
552
  * Returns the internal state of the scroll virtualization.
517
553
  */
518
554
  getState(): LegendListState$1;
555
+ /**
556
+ * Reports an externally measured content inset. Pass null/undefined to clear.
557
+ * Values are merged on top of props/animated/native insets.
558
+ */
559
+ reportContentInset(inset?: Partial<Insets> | null): void;
519
560
  /**
520
561
  * Scrolls a specific index into view.
521
562
  * @param params - Parameters for scrolling.
@@ -582,29 +623,22 @@ type LegendListRef$1 = {
582
623
  animated?: boolean | undefined;
583
624
  }): Promise<void>;
584
625
  /**
585
- * Sets or adds to the offset of the visible content anchor.
586
- * @param value - The offset to set or add.
587
- * @param animated - If true, uses Animated to animate the change.
626
+ * Sets a measured item size and recalculates list positions as needed.
627
+ * @param itemKey - The key of the item whose size changed.
628
+ * @param size - The measured item size.
588
629
  */
589
- setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
630
+ setItemSize(itemKey: string, size: Pick<LayoutRectangle, "height" | "width">): void;
590
631
  /**
591
632
  * Sets whether scroll processing is enabled.
592
633
  * @param enabled - If true, scroll processing is enabled.
593
634
  */
594
635
  setScrollProcessingEnabled(enabled: boolean): void;
595
636
  /**
596
- * Clears internal virtualization caches.
597
- * @param options - Cache clearing options.
598
- * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
599
- */
600
- clearCaches(options?: {
601
- mode?: "sizes" | "full";
602
- }): void;
603
- /**
604
- * Reports an externally measured content inset. Pass null/undefined to clear.
605
- * Values are merged on top of props/animated/native insets.
637
+ * Sets or adds to the offset of the visible content anchor.
638
+ * @param value - The offset to set or add.
639
+ * @param animated - If true, uses Animated to animate the change.
606
640
  */
607
- reportContentInset(inset?: Partial<Insets> | null): void;
641
+ setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
608
642
  };
609
643
  interface ViewToken<ItemT = any> {
610
644
  containerId: number;
@@ -701,6 +735,8 @@ type LegendListState = Omit<LegendListState$1, "elementAtIndex"> & {
701
735
  };
702
736
  type LegendListComponent = <ItemT = any>(props: LegendListProps<ItemT> & React.RefAttributes<LegendListRef>) => React.ReactElement | null;
703
737
 
738
+ declare function useAdaptiveRender(): AdaptiveRender;
739
+ declare function useAdaptiveRenderChange(callback: (mode: AdaptiveRender) => void): void;
704
740
  declare function useViewability<ItemT = any>(callback: ViewabilityCallback<ItemT>, configId?: string): void;
705
741
  declare function useViewabilityAmount<ItemT = any>(callback: ViewabilityAmountCallback<ItemT>): void;
706
742
  declare function useRecyclingEffect(effect: (info: LegendListRecyclingState<unknown>) => void | (() => void)): void;
@@ -714,4 +750,4 @@ declare function useSyncLayout(): () => void;
714
750
 
715
751
  declare const LegendList: LegendListComponent;
716
752
 
717
- export { type AlwaysRenderConfig, type ColumnWrapperStyle, type Insets, type LayoutRectangle, LegendList, type LegendListAverageItemSize, type LegendListComponent, type LegendListMetrics, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type LegendListState, type MaintainScrollAtEndOnOptions, type MaintainScrollAtEndOptions, type MaintainVisibleContentPositionConfig, type NativeScrollEvent, type NativeSyntheticEvent, type OnViewableItemsChanged, type OnViewableItemsChangedInfo, type ScrollIndexWithOffset, type ScrollIndexWithOffsetAndContentOffset, type ScrollIndexWithOffsetPosition, type StickyHeaderConfig, type StyleProp, type ViewAmountToken, type ViewStyle, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
753
+ export { type AdaptiveRender, type AdaptiveRenderConfig, type AlwaysRenderConfig, type ColumnWrapperStyle, type Insets, type LayoutRectangle, LegendList, type LegendListAverageItemSize, type LegendListComponent, type LegendListMetrics, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type LegendListState, type MaintainScrollAtEndOnOptions, type MaintainScrollAtEndOptions, type MaintainVisibleContentPositionConfig, type NativeScrollEvent, type NativeSyntheticEvent, type OnViewableItemsChanged, type OnViewableItemsChangedInfo, type ScrollIndexWithOffset, type ScrollIndexWithOffsetAndContentOffset, type ScrollIndexWithOffsetPosition, type StickyHeaderConfig, type StyleProp, type ViewAmountToken, type ViewStyle, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, useAdaptiveRender, useAdaptiveRenderChange, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };