@legendapp/list 3.0.0-beta.20 → 3.0.0-beta.22

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/keyboard.js CHANGED
@@ -28,6 +28,9 @@ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
28
 
29
29
  // src/integrations/keyboard.tsx
30
30
 
31
+ // src/constants-platform.ts
32
+ var IsNewArchitecture = true;
33
+
31
34
  // src/utils/helpers.ts
32
35
  function isFunction(obj) {
33
36
  return typeof obj === "function";
@@ -51,19 +54,48 @@ var useCombinedRef = (...refs) => {
51
54
  };
52
55
 
53
56
  // src/integrations/keyboard.tsx
57
+ var clampProgress = (progress) => {
58
+ "worklet";
59
+ return Math.min(1, Math.max(0, progress));
60
+ };
54
61
  var calculateKeyboardInset = (height, safeAreaInsetBottom, isNewArchitecture) => {
55
62
  "worklet";
56
63
  return Math.max(0, height - safeAreaInsetBottom) ;
57
64
  };
65
+ var calculateEffectiveKeyboardHeight = (keyboardHeight, contentLength, scrollLength, alignItemsAtEnd) => {
66
+ "worklet";
67
+ if (alignItemsAtEnd) {
68
+ return keyboardHeight;
69
+ } else {
70
+ const availableSpace = Math.max(0, scrollLength - contentLength);
71
+ return Math.max(0, keyboardHeight - availableSpace);
72
+ }
73
+ };
74
+ var calculateEndPaddingInset = (keyboardHeight, alignItemsAtEndPadding) => {
75
+ "worklet";
76
+ return Math.min(keyboardHeight, alignItemsAtEndPadding);
77
+ };
78
+ var calculateTopInset = (safeAreaInsetTop, isNewArchitecture, extraTopInset) => {
79
+ "worklet";
80
+ return (isNewArchitecture ? 0 : safeAreaInsetTop * 2) + extraTopInset;
81
+ };
82
+ var calculateKeyboardTargetOffset = (startOffset, keyboardHeight, isOpening, progress) => {
83
+ "worklet";
84
+ const normalizedProgress = isOpening ? progress : 1 - progress;
85
+ const delta = (isOpening ? keyboardHeight : -keyboardHeight) * normalizedProgress;
86
+ return Math.max(0, startOffset + delta);
87
+ };
58
88
  var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegendList2(props, forwardedRef) {
59
89
  const {
60
90
  contentInset: contentInsetProp,
61
91
  horizontal,
92
+ onMetricsChange: onMetricsChangeProp,
62
93
  onScroll: onScrollProp,
63
94
  safeAreaInsets = { bottom: 0, top: 0 },
64
95
  style: styleProp,
65
96
  ...rest
66
97
  } = props;
98
+ const { alignItemsAtEnd } = props;
67
99
  const styleFlattened = reactNative.StyleSheet.flatten(styleProp);
68
100
  const refLegendList = React.useRef(null);
69
101
  const combinedRef = useCombinedRef(forwardedRef, refLegendList);
@@ -76,13 +108,18 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
76
108
  const mode = reactNativeReanimated.useSharedValue("idle");
77
109
  const keyboardInset = reactNativeReanimated.useSharedValue({ bottom: 0, top: 0 });
78
110
  const keyboardHeight = reactNativeReanimated.useSharedValue(0);
111
+ const contentLength = reactNativeReanimated.useSharedValue(0);
112
+ const scrollLength = reactNativeReanimated.useSharedValue(0);
113
+ const alignItemsAtEndPadding = reactNativeReanimated.useSharedValue(0);
79
114
  const isOpening = reactNativeReanimated.useSharedValue(false);
80
115
  const didInteractive = reactNativeReanimated.useSharedValue(false);
81
116
  const { top: safeAreaInsetTop, bottom: safeAreaInsetBottom } = safeAreaInsets;
82
117
  const isKeyboardOpen = reactNativeReanimated.useSharedValue(false);
83
118
  const scrollHandler = reactNativeReanimated.useAnimatedScrollHandler(
84
119
  (event) => {
85
- scrollOffsetY.set(event.contentOffset[horizontal ? "x" : "y"]);
120
+ if (mode.get() !== "running" || didInteractive.get()) {
121
+ scrollOffsetY.set(event.contentOffset[horizontal ? "x" : "y"]);
122
+ }
86
123
  if (onScrollProp) {
87
124
  reactNativeReanimated.runOnJS(onScrollProp)(event);
88
125
  }
@@ -96,20 +133,69 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
96
133
  },
97
134
  [refLegendList]
98
135
  );
136
+ const updateScrollMetrics = React.useCallback(() => {
137
+ var _a;
138
+ const state = (_a = refLegendList.current) == null ? void 0 : _a.getState();
139
+ if (!state) {
140
+ return;
141
+ }
142
+ contentLength.set(state.contentLength);
143
+ scrollLength.set(state.scrollLength);
144
+ }, [contentLength, scrollLength]);
145
+ const handleMetricsChange = React.useCallback(
146
+ (metrics) => {
147
+ updateScrollMetrics();
148
+ const nextPadding = metrics.alignItemsAtEndPadding || 0;
149
+ alignItemsAtEndPadding.set(nextPadding);
150
+ if (!horizontal) {
151
+ reactNativeReanimated.runOnUI((padding, safeInsetTop, isNewArchitecture) => {
152
+ "worklet";
153
+ if (!isKeyboardOpen.get()) {
154
+ return;
155
+ }
156
+ const vKeyboardHeight = keyboardHeight.get();
157
+ const vEffectiveKeyboardHeight = calculateEffectiveKeyboardHeight(
158
+ vKeyboardHeight,
159
+ contentLength.get(),
160
+ scrollLength.get(),
161
+ alignItemsAtEnd
162
+ );
163
+ const vTopInset = calculateEndPaddingInset(vEffectiveKeyboardHeight, padding);
164
+ const topInset = calculateTopInset(safeInsetTop, isNewArchitecture, vTopInset);
165
+ keyboardInset.set({
166
+ bottom: keyboardInset.get().bottom,
167
+ top: topInset
168
+ });
169
+ })(nextPadding, safeAreaInsetTop, IsNewArchitecture);
170
+ }
171
+ onMetricsChangeProp == null ? void 0 : onMetricsChangeProp(metrics);
172
+ },
173
+ [
174
+ alignItemsAtEndPadding,
175
+ horizontal,
176
+ isKeyboardOpen,
177
+ keyboardHeight,
178
+ keyboardInset,
179
+ onMetricsChangeProp,
180
+ safeAreaInsetTop,
181
+ updateScrollMetrics
182
+ ]
183
+ );
99
184
  reactNativeKeyboardController.useKeyboardHandler(
100
185
  // biome-ignore assist/source/useSortedKeys: prefer start/move/end
101
186
  {
102
187
  onStart: (event) => {
103
188
  "worklet";
104
189
  mode.set("running");
105
- if (isKeyboardOpen.get() && event.progress === 1 && event.height > 0) {
190
+ const progress = clampProgress(event.progress);
191
+ if (isKeyboardOpen.get() && progress >= 1 && event.height > 0) {
106
192
  return;
107
193
  }
108
194
  if (!didInteractive.get()) {
109
195
  if (event.height > 0) {
110
196
  keyboardHeight.set(event.height - safeAreaInsetBottom);
111
197
  }
112
- isOpening.set(event.progress > 0);
198
+ isOpening.set(progress > 0);
113
199
  scrollOffsetAtKeyboardStart.set(scrollOffsetY.get());
114
200
  animatedOffsetY.set(scrollOffsetY.get());
115
201
  reactNativeReanimated.runOnJS(setScrollProcessingEnabled)(false);
@@ -122,6 +208,13 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
122
208
  }
123
209
  mode.set("running");
124
210
  if (!didInteractive.get()) {
211
+ if (!isAndroid && !IsNewArchitecture) {
212
+ keyboardInset.set({
213
+ bottom: keyboardInset.get().bottom,
214
+ // Legacy iOS uses a doubled top inset to keep content below the status bar.
215
+ top: calculateTopInset(safeAreaInsetTop, IsNewArchitecture, 0)
216
+ });
217
+ }
125
218
  didInteractive.set(true);
126
219
  }
127
220
  if (isAndroid && !horizontal) {
@@ -132,18 +225,37 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
132
225
  onMove: (event) => {
133
226
  "worklet";
134
227
  if (!didInteractive.get()) {
228
+ const progress = clampProgress(event.progress);
135
229
  const vIsOpening = isOpening.get();
136
230
  const vKeyboardHeight = keyboardHeight.get();
137
- const vProgress = vIsOpening ? event.progress : 1 - event.progress;
138
- const targetOffset = Math.max(
139
- 0,
140
- scrollOffsetAtKeyboardStart.get() + (vIsOpening ? vKeyboardHeight : -vKeyboardHeight) * vProgress
231
+ const vEffectiveKeyboardHeight = calculateEffectiveKeyboardHeight(
232
+ vKeyboardHeight,
233
+ contentLength.get(),
234
+ scrollLength.get(),
235
+ alignItemsAtEnd
236
+ );
237
+ const vAlignItemsPadding = alignItemsAtEndPadding.get();
238
+ const vTopInset = calculateEndPaddingInset(vEffectiveKeyboardHeight, vAlignItemsPadding);
239
+ const targetOffset = calculateKeyboardTargetOffset(
240
+ scrollOffsetAtKeyboardStart.get(),
241
+ vEffectiveKeyboardHeight,
242
+ vIsOpening,
243
+ progress
141
244
  );
142
245
  scrollOffsetY.set(targetOffset);
143
246
  animatedOffsetY.set(targetOffset);
144
247
  if (!horizontal) {
145
248
  const newInset = calculateKeyboardInset(event.height, safeAreaInsetBottom);
146
- keyboardInset.set({ bottom: newInset, top: 0 });
249
+ const topInset = calculateTopInset(
250
+ safeAreaInsetTop,
251
+ IsNewArchitecture,
252
+ vIsOpening ? vTopInset : 0
253
+ );
254
+ keyboardInset.set({
255
+ bottom: newInset,
256
+ // Add top padding only while opening to keep end-aligned items visible.
257
+ top: topInset
258
+ });
147
259
  }
148
260
  }
149
261
  },
@@ -153,12 +265,23 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
153
265
  const vMode = mode.get();
154
266
  mode.set("idle");
155
267
  if (vMode === "running") {
268
+ const progress = clampProgress(event.progress);
269
+ const vKeyboardHeight = keyboardHeight.get();
270
+ const vEffectiveKeyboardHeight = calculateEffectiveKeyboardHeight(
271
+ vKeyboardHeight,
272
+ contentLength.get(),
273
+ scrollLength.get(),
274
+ alignItemsAtEnd
275
+ );
276
+ const vAlignItemsPadding = alignItemsAtEndPadding.get();
277
+ const vTopInset = calculateEndPaddingInset(vEffectiveKeyboardHeight, vAlignItemsPadding);
278
+ const vIsOpening = isOpening.get();
156
279
  if (!wasInteractive) {
157
- const vIsOpening = isOpening.get();
158
- const vKeyboardHeight = keyboardHeight.get();
159
- const targetOffset = Math.max(
160
- 0,
161
- scrollOffsetAtKeyboardStart.get() + (vIsOpening ? vKeyboardHeight : -vKeyboardHeight) * (vIsOpening ? event.progress : 1 - event.progress)
280
+ const targetOffset = calculateKeyboardTargetOffset(
281
+ scrollOffsetAtKeyboardStart.get(),
282
+ vEffectiveKeyboardHeight,
283
+ vIsOpening,
284
+ progress
162
285
  );
163
286
  scrollOffsetY.set(targetOffset);
164
287
  animatedOffsetY.set(targetOffset);
@@ -168,7 +291,16 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
168
291
  isKeyboardOpen.set(event.height > 0);
169
292
  if (!horizontal) {
170
293
  const newInset = calculateKeyboardInset(event.height, safeAreaInsetBottom);
171
- keyboardInset.set({ bottom: newInset, top: 0 });
294
+ const topInset = calculateTopInset(
295
+ safeAreaInsetTop,
296
+ IsNewArchitecture,
297
+ event.height > 0 ? vTopInset : 0
298
+ );
299
+ keyboardInset.set({
300
+ bottom: newInset,
301
+ // Preserve end-aligned padding only while the keyboard is visible.
302
+ top: topInset
303
+ });
172
304
  if (newInset <= 0) {
173
305
  animatedOffsetY.set(scrollOffsetY.get());
174
306
  }
@@ -176,7 +308,7 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
176
308
  }
177
309
  }
178
310
  },
179
- [scrollViewRef, safeAreaInsetBottom]
311
+ [alignItemsAtEnd, safeAreaInsetBottom, scrollViewRef]
180
312
  );
181
313
  const animatedProps = reactNativeReanimated.useAnimatedProps(() => {
182
314
  "worklet";
@@ -214,6 +346,7 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
214
346
  ...rest,
215
347
  animatedProps,
216
348
  keyboardDismissMode: "interactive",
349
+ onMetricsChange: handleMetricsChange,
217
350
  onScroll: scrollHandler,
218
351
  ref: combinedRef,
219
352
  refScrollView: scrollViewRef,
package/keyboard.mjs CHANGED
@@ -2,11 +2,14 @@ import * as React from 'react';
2
2
  import { forwardRef, useRef, useCallback } from 'react';
3
3
  import { StyleSheet, Platform } from 'react-native';
4
4
  import { useKeyboardHandler } from 'react-native-keyboard-controller';
5
- import { useAnimatedRef, useSharedValue, useAnimatedScrollHandler, runOnJS, useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated';
5
+ import { useAnimatedRef, useSharedValue, useAnimatedScrollHandler, runOnJS, runOnUI, useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated';
6
6
  import { AnimatedLegendList } from '@legendapp/list/reanimated';
7
7
 
8
8
  // src/integrations/keyboard.tsx
9
9
 
10
+ // src/constants-platform.ts
11
+ var IsNewArchitecture = true;
12
+
10
13
  // src/utils/helpers.ts
11
14
  function isFunction(obj) {
12
15
  return typeof obj === "function";
@@ -30,19 +33,48 @@ var useCombinedRef = (...refs) => {
30
33
  };
31
34
 
32
35
  // src/integrations/keyboard.tsx
36
+ var clampProgress = (progress) => {
37
+ "worklet";
38
+ return Math.min(1, Math.max(0, progress));
39
+ };
33
40
  var calculateKeyboardInset = (height, safeAreaInsetBottom, isNewArchitecture) => {
34
41
  "worklet";
35
42
  return Math.max(0, height - safeAreaInsetBottom) ;
36
43
  };
44
+ var calculateEffectiveKeyboardHeight = (keyboardHeight, contentLength, scrollLength, alignItemsAtEnd) => {
45
+ "worklet";
46
+ if (alignItemsAtEnd) {
47
+ return keyboardHeight;
48
+ } else {
49
+ const availableSpace = Math.max(0, scrollLength - contentLength);
50
+ return Math.max(0, keyboardHeight - availableSpace);
51
+ }
52
+ };
53
+ var calculateEndPaddingInset = (keyboardHeight, alignItemsAtEndPadding) => {
54
+ "worklet";
55
+ return Math.min(keyboardHeight, alignItemsAtEndPadding);
56
+ };
57
+ var calculateTopInset = (safeAreaInsetTop, isNewArchitecture, extraTopInset) => {
58
+ "worklet";
59
+ return (isNewArchitecture ? 0 : safeAreaInsetTop * 2) + extraTopInset;
60
+ };
61
+ var calculateKeyboardTargetOffset = (startOffset, keyboardHeight, isOpening, progress) => {
62
+ "worklet";
63
+ const normalizedProgress = isOpening ? progress : 1 - progress;
64
+ const delta = (isOpening ? keyboardHeight : -keyboardHeight) * normalizedProgress;
65
+ return Math.max(0, startOffset + delta);
66
+ };
37
67
  var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2(props, forwardedRef) {
38
68
  const {
39
69
  contentInset: contentInsetProp,
40
70
  horizontal,
71
+ onMetricsChange: onMetricsChangeProp,
41
72
  onScroll: onScrollProp,
42
73
  safeAreaInsets = { bottom: 0, top: 0 },
43
74
  style: styleProp,
44
75
  ...rest
45
76
  } = props;
77
+ const { alignItemsAtEnd } = props;
46
78
  const styleFlattened = StyleSheet.flatten(styleProp);
47
79
  const refLegendList = useRef(null);
48
80
  const combinedRef = useCombinedRef(forwardedRef, refLegendList);
@@ -55,13 +87,18 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
55
87
  const mode = useSharedValue("idle");
56
88
  const keyboardInset = useSharedValue({ bottom: 0, top: 0 });
57
89
  const keyboardHeight = useSharedValue(0);
90
+ const contentLength = useSharedValue(0);
91
+ const scrollLength = useSharedValue(0);
92
+ const alignItemsAtEndPadding = useSharedValue(0);
58
93
  const isOpening = useSharedValue(false);
59
94
  const didInteractive = useSharedValue(false);
60
95
  const { top: safeAreaInsetTop, bottom: safeAreaInsetBottom } = safeAreaInsets;
61
96
  const isKeyboardOpen = useSharedValue(false);
62
97
  const scrollHandler = useAnimatedScrollHandler(
63
98
  (event) => {
64
- scrollOffsetY.set(event.contentOffset[horizontal ? "x" : "y"]);
99
+ if (mode.get() !== "running" || didInteractive.get()) {
100
+ scrollOffsetY.set(event.contentOffset[horizontal ? "x" : "y"]);
101
+ }
65
102
  if (onScrollProp) {
66
103
  runOnJS(onScrollProp)(event);
67
104
  }
@@ -75,20 +112,69 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
75
112
  },
76
113
  [refLegendList]
77
114
  );
115
+ const updateScrollMetrics = useCallback(() => {
116
+ var _a;
117
+ const state = (_a = refLegendList.current) == null ? void 0 : _a.getState();
118
+ if (!state) {
119
+ return;
120
+ }
121
+ contentLength.set(state.contentLength);
122
+ scrollLength.set(state.scrollLength);
123
+ }, [contentLength, scrollLength]);
124
+ const handleMetricsChange = useCallback(
125
+ (metrics) => {
126
+ updateScrollMetrics();
127
+ const nextPadding = metrics.alignItemsAtEndPadding || 0;
128
+ alignItemsAtEndPadding.set(nextPadding);
129
+ if (!horizontal) {
130
+ runOnUI((padding, safeInsetTop, isNewArchitecture) => {
131
+ "worklet";
132
+ if (!isKeyboardOpen.get()) {
133
+ return;
134
+ }
135
+ const vKeyboardHeight = keyboardHeight.get();
136
+ const vEffectiveKeyboardHeight = calculateEffectiveKeyboardHeight(
137
+ vKeyboardHeight,
138
+ contentLength.get(),
139
+ scrollLength.get(),
140
+ alignItemsAtEnd
141
+ );
142
+ const vTopInset = calculateEndPaddingInset(vEffectiveKeyboardHeight, padding);
143
+ const topInset = calculateTopInset(safeInsetTop, isNewArchitecture, vTopInset);
144
+ keyboardInset.set({
145
+ bottom: keyboardInset.get().bottom,
146
+ top: topInset
147
+ });
148
+ })(nextPadding, safeAreaInsetTop, IsNewArchitecture);
149
+ }
150
+ onMetricsChangeProp == null ? void 0 : onMetricsChangeProp(metrics);
151
+ },
152
+ [
153
+ alignItemsAtEndPadding,
154
+ horizontal,
155
+ isKeyboardOpen,
156
+ keyboardHeight,
157
+ keyboardInset,
158
+ onMetricsChangeProp,
159
+ safeAreaInsetTop,
160
+ updateScrollMetrics
161
+ ]
162
+ );
78
163
  useKeyboardHandler(
79
164
  // biome-ignore assist/source/useSortedKeys: prefer start/move/end
80
165
  {
81
166
  onStart: (event) => {
82
167
  "worklet";
83
168
  mode.set("running");
84
- if (isKeyboardOpen.get() && event.progress === 1 && event.height > 0) {
169
+ const progress = clampProgress(event.progress);
170
+ if (isKeyboardOpen.get() && progress >= 1 && event.height > 0) {
85
171
  return;
86
172
  }
87
173
  if (!didInteractive.get()) {
88
174
  if (event.height > 0) {
89
175
  keyboardHeight.set(event.height - safeAreaInsetBottom);
90
176
  }
91
- isOpening.set(event.progress > 0);
177
+ isOpening.set(progress > 0);
92
178
  scrollOffsetAtKeyboardStart.set(scrollOffsetY.get());
93
179
  animatedOffsetY.set(scrollOffsetY.get());
94
180
  runOnJS(setScrollProcessingEnabled)(false);
@@ -101,6 +187,13 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
101
187
  }
102
188
  mode.set("running");
103
189
  if (!didInteractive.get()) {
190
+ if (!isAndroid && !IsNewArchitecture) {
191
+ keyboardInset.set({
192
+ bottom: keyboardInset.get().bottom,
193
+ // Legacy iOS uses a doubled top inset to keep content below the status bar.
194
+ top: calculateTopInset(safeAreaInsetTop, IsNewArchitecture, 0)
195
+ });
196
+ }
104
197
  didInteractive.set(true);
105
198
  }
106
199
  if (isAndroid && !horizontal) {
@@ -111,18 +204,37 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
111
204
  onMove: (event) => {
112
205
  "worklet";
113
206
  if (!didInteractive.get()) {
207
+ const progress = clampProgress(event.progress);
114
208
  const vIsOpening = isOpening.get();
115
209
  const vKeyboardHeight = keyboardHeight.get();
116
- const vProgress = vIsOpening ? event.progress : 1 - event.progress;
117
- const targetOffset = Math.max(
118
- 0,
119
- scrollOffsetAtKeyboardStart.get() + (vIsOpening ? vKeyboardHeight : -vKeyboardHeight) * vProgress
210
+ const vEffectiveKeyboardHeight = calculateEffectiveKeyboardHeight(
211
+ vKeyboardHeight,
212
+ contentLength.get(),
213
+ scrollLength.get(),
214
+ alignItemsAtEnd
215
+ );
216
+ const vAlignItemsPadding = alignItemsAtEndPadding.get();
217
+ const vTopInset = calculateEndPaddingInset(vEffectiveKeyboardHeight, vAlignItemsPadding);
218
+ const targetOffset = calculateKeyboardTargetOffset(
219
+ scrollOffsetAtKeyboardStart.get(),
220
+ vEffectiveKeyboardHeight,
221
+ vIsOpening,
222
+ progress
120
223
  );
121
224
  scrollOffsetY.set(targetOffset);
122
225
  animatedOffsetY.set(targetOffset);
123
226
  if (!horizontal) {
124
227
  const newInset = calculateKeyboardInset(event.height, safeAreaInsetBottom);
125
- keyboardInset.set({ bottom: newInset, top: 0 });
228
+ const topInset = calculateTopInset(
229
+ safeAreaInsetTop,
230
+ IsNewArchitecture,
231
+ vIsOpening ? vTopInset : 0
232
+ );
233
+ keyboardInset.set({
234
+ bottom: newInset,
235
+ // Add top padding only while opening to keep end-aligned items visible.
236
+ top: topInset
237
+ });
126
238
  }
127
239
  }
128
240
  },
@@ -132,12 +244,23 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
132
244
  const vMode = mode.get();
133
245
  mode.set("idle");
134
246
  if (vMode === "running") {
247
+ const progress = clampProgress(event.progress);
248
+ const vKeyboardHeight = keyboardHeight.get();
249
+ const vEffectiveKeyboardHeight = calculateEffectiveKeyboardHeight(
250
+ vKeyboardHeight,
251
+ contentLength.get(),
252
+ scrollLength.get(),
253
+ alignItemsAtEnd
254
+ );
255
+ const vAlignItemsPadding = alignItemsAtEndPadding.get();
256
+ const vTopInset = calculateEndPaddingInset(vEffectiveKeyboardHeight, vAlignItemsPadding);
257
+ const vIsOpening = isOpening.get();
135
258
  if (!wasInteractive) {
136
- const vIsOpening = isOpening.get();
137
- const vKeyboardHeight = keyboardHeight.get();
138
- const targetOffset = Math.max(
139
- 0,
140
- scrollOffsetAtKeyboardStart.get() + (vIsOpening ? vKeyboardHeight : -vKeyboardHeight) * (vIsOpening ? event.progress : 1 - event.progress)
259
+ const targetOffset = calculateKeyboardTargetOffset(
260
+ scrollOffsetAtKeyboardStart.get(),
261
+ vEffectiveKeyboardHeight,
262
+ vIsOpening,
263
+ progress
141
264
  );
142
265
  scrollOffsetY.set(targetOffset);
143
266
  animatedOffsetY.set(targetOffset);
@@ -147,7 +270,16 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
147
270
  isKeyboardOpen.set(event.height > 0);
148
271
  if (!horizontal) {
149
272
  const newInset = calculateKeyboardInset(event.height, safeAreaInsetBottom);
150
- keyboardInset.set({ bottom: newInset, top: 0 });
273
+ const topInset = calculateTopInset(
274
+ safeAreaInsetTop,
275
+ IsNewArchitecture,
276
+ event.height > 0 ? vTopInset : 0
277
+ );
278
+ keyboardInset.set({
279
+ bottom: newInset,
280
+ // Preserve end-aligned padding only while the keyboard is visible.
281
+ top: topInset
282
+ });
151
283
  if (newInset <= 0) {
152
284
  animatedOffsetY.set(scrollOffsetY.get());
153
285
  }
@@ -155,7 +287,7 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
155
287
  }
156
288
  }
157
289
  },
158
- [scrollViewRef, safeAreaInsetBottom]
290
+ [alignItemsAtEnd, safeAreaInsetBottom, scrollViewRef]
159
291
  );
160
292
  const animatedProps = useAnimatedProps(() => {
161
293
  "worklet";
@@ -193,6 +325,7 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
193
325
  ...rest,
194
326
  animatedProps,
195
327
  keyboardDismissMode: "interactive",
328
+ onMetricsChange: handleMetricsChange,
196
329
  onScroll: scrollHandler,
197
330
  ref: combinedRef,
198
331
  refScrollView: scrollViewRef,
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { Insets } from 'react-native';
3
+ import { ReanimatedScrollEvent } from 'react-native-reanimated/lib/typescript/hook/commonTypes';
4
+ import { LegendListRef } from '@legendapp/list';
5
+ import { AnimatedLegendListProps } from '@legendapp/list/reanimated';
6
+
7
+ declare const KeyboardAvoidingLegendList: <ItemT>(props: Omit<AnimatedLegendListProps<ItemT>, "onScroll" | "contentInset"> & {
8
+ onScroll?: (event: ReanimatedScrollEvent) => void;
9
+ contentInset?: Insets | undefined;
10
+ safeAreaInsets?: {
11
+ top: number;
12
+ bottom: number;
13
+ };
14
+ } & React.RefAttributes<LegendListRef>) => React.ReactNode;
15
+
16
+ export { KeyboardAvoidingLegendList, KeyboardAvoidingLegendList as LegendList };
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ import { Insets } from 'react-native';
3
+ import { ReanimatedScrollEvent } from 'react-native-reanimated/lib/typescript/hook/commonTypes';
4
+ import { LegendListRef } from '@legendapp/list';
5
+ import { AnimatedLegendListProps } from '@legendapp/list/reanimated';
6
+
7
+ declare const KeyboardAvoidingLegendList: <ItemT>(props: Omit<AnimatedLegendListProps<ItemT>, "onScroll" | "contentInset"> & {
8
+ onScroll?: (event: ReanimatedScrollEvent) => void;
9
+ contentInset?: Insets | undefined;
10
+ safeAreaInsets?: {
11
+ top: number;
12
+ bottom: number;
13
+ };
14
+ } & React.RefAttributes<LegendListRef>) => React.ReactNode;
15
+
16
+ export { KeyboardAvoidingLegendList, KeyboardAvoidingLegendList as LegendList };