@legendapp/list 3.0.0-beta.36 → 3.0.0-beta.38

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/index.native.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as React2 from 'react';
2
- import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, memo, forwardRef, useContext } from 'react';
3
- import { Animated, View as View$1, Text as Text$1, Platform, StyleSheet as StyleSheet$1, RefreshControl, Dimensions, unstable_batchedUpdates } from 'react-native';
2
+ import React2__default, { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, useContext } from 'react';
3
+ import * as ReactNative from 'react-native';
4
+ import { Animated, View as View$1, Text as Text$1, Platform, StyleSheet as StyleSheet$1, RefreshControl, Dimensions } from 'react-native';
4
5
  import { useSyncExternalStore } from 'use-sync-external-store/shim';
5
6
 
6
7
  // src/components/LegendList.tsx
@@ -320,7 +321,7 @@ function useValue$(key, params) {
320
321
  }, []);
321
322
  return animValue;
322
323
  }
323
- var typedMemo = memo;
324
+ var typedMemo = React2.memo;
324
325
  var getComponent = (Component) => {
325
326
  if (React2.isValidElement(Component)) {
326
327
  return Component;
@@ -612,8 +613,8 @@ function useOnLayoutSync({
612
613
  }
613
614
  var Platform2 = Platform;
614
615
  var PlatformAdjustBreaksScroll = Platform2.OS === "android";
615
- var typedForwardRef = forwardRef;
616
- var typedMemo2 = memo;
616
+ var typedForwardRef = React2.forwardRef;
617
+ var typedMemo2 = React2.memo;
617
618
 
618
619
  // src/utils/isInMVCPActiveMode.native.ts
619
620
  function isInMVCPActiveMode(state) {
@@ -891,7 +892,7 @@ function SnapWrapper({ ScrollComponent, ...props }) {
891
892
  return /* @__PURE__ */ React2.createElement(ScrollComponent, { ...props, snapToOffsets });
892
893
  }
893
894
  var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
894
- const ref = refView != null ? refView : useRef();
895
+ const ref = refView != null ? refView : useRef(null);
895
896
  const { onLayout } = useOnLayoutSync({ onLayoutChange, ref });
896
897
  return /* @__PURE__ */ React2.createElement(View$1, { ...rest, onLayout, ref });
897
898
  };
@@ -918,8 +919,8 @@ var ListComponent = typedMemo2(function ListComponent2({
918
919
  updateItemSize: updateItemSize2,
919
920
  refScrollView,
920
921
  renderScrollComponent,
922
+ onLayoutFooter,
921
923
  scrollAdjustHandler,
922
- onLayoutHeader,
923
924
  snapToIndices,
924
925
  stickyHeaderConfig,
925
926
  stickyHeaderIndices,
@@ -943,6 +944,21 @@ var ListComponent = typedMemo2(function ListComponent2({
943
944
  set$(ctx, "footerSize", 0);
944
945
  }
945
946
  }, [ListHeaderComponent, ListFooterComponent, ctx]);
947
+ const onLayoutHeader = useCallback(
948
+ (rect) => {
949
+ const size = rect[horizontal ? "width" : "height"];
950
+ set$(ctx, "headerSize", size);
951
+ },
952
+ [ctx, horizontal]
953
+ );
954
+ const onLayoutFooterInternal = useCallback(
955
+ (rect, fromLayoutEffect) => {
956
+ const size = rect[horizontal ? "width" : "height"];
957
+ set$(ctx, "footerSize", size);
958
+ onLayoutFooter == null ? void 0 : onLayoutFooter(rect, fromLayoutEffect);
959
+ },
960
+ [ctx, horizontal, onLayoutFooter]
961
+ );
946
962
  return /* @__PURE__ */ React2.createElement(
947
963
  SnapOrScroll,
948
964
  {
@@ -978,17 +994,7 @@ var ListComponent = typedMemo2(function ListComponent2({
978
994
  waitForInitialLayout
979
995
  }
980
996
  ),
981
- ListFooterComponent && /* @__PURE__ */ React2.createElement(
982
- LayoutView,
983
- {
984
- onLayoutChange: (layout) => {
985
- const size = layout[horizontal ? "width" : "height"];
986
- set$(ctx, "footerSize", size);
987
- },
988
- style: ListFooterComponentStyle
989
- },
990
- getComponent(ListFooterComponent)
991
- ),
997
+ ListFooterComponent && /* @__PURE__ */ React2.createElement(LayoutView, { onLayoutChange: onLayoutFooterInternal, style: ListFooterComponentStyle }, getComponent(ListFooterComponent)),
992
998
  IS_DEV && ENABLE_DEVMODE
993
999
  );
994
1000
  });
@@ -996,19 +1002,12 @@ var ListComponent = typedMemo2(function ListComponent2({
996
1002
  // src/core/calculateOffsetForIndex.ts
997
1003
  function calculateOffsetForIndex(ctx, index) {
998
1004
  const state = ctx.state;
999
- let position = 0;
1000
- if (index !== void 0) {
1001
- position = state.positions[index] || 0;
1002
- const paddingTop = peek$(ctx, "stylePaddingTop");
1003
- if (paddingTop) {
1004
- position += paddingTop;
1005
- }
1006
- const headerSize = peek$(ctx, "headerSize");
1007
- if (headerSize) {
1008
- position += headerSize;
1009
- }
1010
- }
1011
- return position;
1005
+ return index !== void 0 ? state.positions[index] || 0 : 0;
1006
+ }
1007
+
1008
+ // src/core/getTopOffsetAdjustment.ts
1009
+ function getTopOffsetAdjustment(ctx) {
1010
+ return (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
1012
1011
  }
1013
1012
 
1014
1013
  // src/utils/getId.ts
@@ -1116,10 +1115,20 @@ function calculateOffsetWithOffsetPosition(ctx, offsetParam, params) {
1116
1115
  if (viewOffset) {
1117
1116
  offset -= viewOffset;
1118
1117
  }
1118
+ if (index !== void 0) {
1119
+ const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
1120
+ if (topOffsetAdjustment) {
1121
+ offset += topOffsetAdjustment;
1122
+ }
1123
+ }
1119
1124
  if (viewPosition !== void 0 && index !== void 0) {
1120
1125
  const itemSize = getItemSize(ctx, getId(state, index), index, state.props.data[index]);
1121
1126
  const trailingInset = getContentInsetEnd(state);
1122
1127
  offset -= viewPosition * (state.scrollLength - trailingInset - itemSize);
1128
+ if (index === state.props.data.length - 1) {
1129
+ const footerSize = peek$(ctx, "footerSize") || 0;
1130
+ offset += footerSize;
1131
+ }
1123
1132
  }
1124
1133
  return offset;
1125
1134
  }
@@ -1573,7 +1582,8 @@ function ensureInitialAnchor(ctx) {
1573
1582
  return;
1574
1583
  }
1575
1584
  const availableSpace = Math.max(0, scrollLength - size);
1576
- const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1585
+ const topOffsetAdjustment = getTopOffsetAdjustment(ctx);
1586
+ const desiredOffset = calculateOffsetForIndex(ctx, anchor.index) + topOffsetAdjustment - ((_a3 = anchor.viewOffset) != null ? _a3 : 0) - ((_b = anchor.viewPosition) != null ? _b : 0) * availableSpace;
1577
1587
  const clampedDesiredOffset = clampScrollOffset(ctx, desiredOffset, anchor);
1578
1588
  const delta = clampedDesiredOffset - scroll;
1579
1589
  if (Math.abs(delta) <= INITIAL_ANCHOR_TOLERANCE) {
@@ -2290,6 +2300,8 @@ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
2290
2300
  const cb = ctx.mapViewabilityCallbacks.get(key);
2291
2301
  cb == null ? void 0 : cb(viewToken);
2292
2302
  }
2303
+ var unstableBatchedUpdates = ReactNative.unstable_batchedUpdates;
2304
+ var batchedUpdates = typeof unstableBatchedUpdates === "function" ? unstableBatchedUpdates : (fn) => fn();
2293
2305
 
2294
2306
  // src/utils/checkAllSizesKnown.ts
2295
2307
  function isNullOrUndefined2(value) {
@@ -2542,7 +2554,7 @@ function handleStickyRecycling(ctx, stickyArray, scroll, drawDistance, currentSt
2542
2554
  }
2543
2555
  function calculateItemsInView(ctx, params = {}) {
2544
2556
  const state = ctx.state;
2545
- unstable_batchedUpdates(() => {
2557
+ batchedUpdates(() => {
2546
2558
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2547
2559
  const {
2548
2560
  columns,
@@ -3481,20 +3493,69 @@ function createColumnWrapperStyle(contentContainerStyle) {
3481
3493
  }
3482
3494
  }
3483
3495
 
3496
+ // src/utils/hasActiveMVCPAnchorLock.ts
3497
+ function hasActiveMVCPAnchorLock(state) {
3498
+ const lock = state.mvcpAnchorLock;
3499
+ if (!lock) {
3500
+ return false;
3501
+ }
3502
+ if (Date.now() > lock.expiresAt) {
3503
+ state.mvcpAnchorLock = void 0;
3504
+ return false;
3505
+ }
3506
+ return true;
3507
+ }
3508
+
3484
3509
  // src/utils/createImperativeHandle.ts
3485
3510
  function createImperativeHandle(ctx) {
3486
3511
  const state = ctx.state;
3512
+ const IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS = 800;
3513
+ const IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES = 2;
3514
+ let imperativeScrollToken = 0;
3515
+ const isSettlingAfterDataChange = () => !!state.didDataChange || !!state.didColumnsChange || state.queuedMVCPRecalculate !== void 0 || state.ignoreScrollFromMVCP !== void 0 || hasActiveMVCPAnchorLock(state);
3516
+ const runWhenSettled = (token, run) => {
3517
+ const startedAt = Date.now();
3518
+ let stableFrames = 0;
3519
+ const check = () => {
3520
+ if (token !== imperativeScrollToken) {
3521
+ return;
3522
+ }
3523
+ if (isSettlingAfterDataChange()) {
3524
+ stableFrames = 0;
3525
+ } else {
3526
+ stableFrames += 1;
3527
+ }
3528
+ const timedOut = Date.now() - startedAt >= IMPERATIVE_SCROLL_SETTLE_MAX_WAIT_MS;
3529
+ if (stableFrames >= IMPERATIVE_SCROLL_SETTLE_STABLE_FRAMES || timedOut) {
3530
+ run();
3531
+ return;
3532
+ }
3533
+ requestAnimationFrame(check);
3534
+ };
3535
+ requestAnimationFrame(check);
3536
+ };
3487
3537
  const runScrollWithPromise = (run) => new Promise((resolve) => {
3488
3538
  var _a3;
3539
+ const token = ++imperativeScrollToken;
3489
3540
  (_a3 = state.pendingScrollResolve) == null ? void 0 : _a3.call(state);
3490
3541
  state.pendingScrollResolve = resolve;
3491
- const didStartScroll = run();
3492
- if (!didStartScroll || !state.scrollingTo) {
3493
- if (state.pendingScrollResolve === resolve) {
3494
- state.pendingScrollResolve = void 0;
3542
+ const runNow = () => {
3543
+ if (token !== imperativeScrollToken) {
3544
+ return;
3545
+ }
3546
+ const didStartScroll = run();
3547
+ if (!didStartScroll || !state.scrollingTo) {
3548
+ if (state.pendingScrollResolve === resolve) {
3549
+ state.pendingScrollResolve = void 0;
3550
+ }
3551
+ resolve();
3495
3552
  }
3496
- resolve();
3553
+ };
3554
+ if (isSettlingAfterDataChange()) {
3555
+ runWhenSettled(token, runNow);
3556
+ return;
3497
3557
  }
3558
+ runNow();
3498
3559
  });
3499
3560
  const scrollIndexIntoView = (options) => {
3500
3561
  if (state) {
@@ -3804,7 +3865,7 @@ var LegendList = typedMemo2(
3804
3865
  })
3805
3866
  );
3806
3867
  var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
3807
- var _a3, _b, _c, _d;
3868
+ var _a3, _b, _c, _d, _e;
3808
3869
  const {
3809
3870
  alignItemsAtEnd = false,
3810
3871
  alwaysRender,
@@ -3893,7 +3954,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3893
3954
  const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
3894
3955
  maintainVisibleContentPositionProp
3895
3956
  );
3896
- const [renderNum, setRenderNum] = useState(0);
3897
3957
  const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState, viewPosition: 1 } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? {
3898
3958
  index: initialScrollIndexProp.index || 0,
3899
3959
  viewOffset: initialScrollIndexProp.viewOffset || (initialScrollIndexProp.viewPosition === 1 ? -stylePaddingBottomState : 0),
@@ -3934,7 +3994,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3934
3994
  );
3935
3995
  }
3936
3996
  const useWindowScrollResolved = Platform2.OS === "web" && !!useWindowScroll && !renderScrollComponent;
3937
- const refState = useRef();
3997
+ const refState = useRef(void 0);
3938
3998
  const hasOverrideItemLayout = !!overrideItemLayout;
3939
3999
  const prevHasOverrideItemLayout = useRef(hasOverrideItemLayout);
3940
4000
  if (!refState.current) {
@@ -4098,6 +4158,11 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4098
4158
  true
4099
4159
  );
4100
4160
  }
4161
+ const resolveInitialScrollOffset = useCallback((initialScroll) => {
4162
+ const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
4163
+ const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
4164
+ return clampScrollOffset(ctx, resolvedOffset, initialScroll);
4165
+ }, []);
4101
4166
  const initialContentOffset = useMemo(() => {
4102
4167
  var _a4;
4103
4168
  let value;
@@ -4115,9 +4180,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4115
4180
  if (initialScroll.contentOffset !== void 0) {
4116
4181
  value = initialScroll.contentOffset;
4117
4182
  } else {
4118
- const baseOffset = initialScroll.index !== void 0 ? calculateOffsetForIndex(ctx, initialScroll.index) : 0;
4119
- const resolvedOffset = calculateOffsetWithOffsetPosition(ctx, baseOffset, initialScroll);
4120
- const clampedOffset = clampScrollOffset(ctx, resolvedOffset, initialScroll);
4183
+ const clampedOffset = resolveInitialScrollOffset(initialScroll);
4121
4184
  const updatedInitialScroll = { ...initialScroll, contentOffset: clampedOffset };
4122
4185
  refState.current.initialScroll = updatedInitialScroll;
4123
4186
  state.initialScroll = updatedInitialScroll;
@@ -4131,7 +4194,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4131
4194
  setInitialRenderState(ctx, { didInitialScroll: true });
4132
4195
  }
4133
4196
  return value;
4134
- }, [renderNum]);
4197
+ }, []);
4135
4198
  if (isFirstLocal || didDataChangeLocal || numColumnsProp !== peek$(ctx, "numColumns")) {
4136
4199
  refState.current.lastBatchingAction = Date.now();
4137
4200
  if (!keyExtractorProp && !isFirstLocal && didDataChangeLocal) {
@@ -4145,32 +4208,45 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4145
4208
  set$(ctx, "totalSize", 0);
4146
4209
  }
4147
4210
  }
4148
- const onLayoutHeader = useCallback((rect, fromLayoutEffect) => {
4149
- const { initialScroll } = refState.current;
4150
- const size = rect[horizontal ? "width" : "height"];
4151
- set$(ctx, "headerSize", size);
4152
- if ((initialScroll == null ? void 0 : initialScroll.index) !== void 0) {
4153
- if (IsNewArchitecture && Platform2.OS !== "android") {
4154
- if (fromLayoutEffect) {
4155
- setRenderNum((v) => v + 1);
4156
- }
4157
- } else {
4158
- setTimeout(doInitialScroll, 17);
4159
- }
4160
- }
4161
- }, []);
4162
4211
  const doInitialScroll = useCallback(() => {
4163
4212
  const { initialScroll, didFinishInitialScroll, queuedInitialLayout, scrollingTo } = state;
4164
4213
  if (initialScroll && !queuedInitialLayout && !didFinishInitialScroll && !scrollingTo) {
4214
+ const offset = resolveInitialScrollOffset(initialScroll);
4215
+ const updatedInitialScroll = { ...initialScroll, contentOffset: offset };
4216
+ refState.current.initialScroll = updatedInitialScroll;
4217
+ state.initialScroll = updatedInitialScroll;
4165
4218
  scrollTo(ctx, {
4166
4219
  animated: false,
4167
- index: initialScroll == null ? void 0 : initialScroll.index,
4220
+ index: initialScroll.index,
4168
4221
  isInitialScroll: true,
4169
- offset: initialContentOffset,
4222
+ offset,
4170
4223
  precomputedWithViewOffset: true
4171
4224
  });
4172
4225
  }
4173
- }, [initialContentOffset]);
4226
+ }, []);
4227
+ const onLayoutFooter = useCallback(
4228
+ (layout) => {
4229
+ if (!initialScrollAtEnd) {
4230
+ return;
4231
+ }
4232
+ const { initialScroll } = state;
4233
+ if (!initialScroll) {
4234
+ return;
4235
+ }
4236
+ const lastIndex = Math.max(0, dataProp.length - 1);
4237
+ if (initialScroll.index !== lastIndex || initialScroll.viewPosition !== 1) {
4238
+ return;
4239
+ }
4240
+ const footerSize = layout[horizontal ? "width" : "height"];
4241
+ const viewOffset = -stylePaddingBottomState - footerSize;
4242
+ if (initialScroll.viewOffset !== viewOffset) {
4243
+ const updatedInitialScroll = { ...initialScroll, viewOffset };
4244
+ refState.current.initialScroll = updatedInitialScroll;
4245
+ state.initialScroll = updatedInitialScroll;
4246
+ }
4247
+ },
4248
+ [dataProp.length, horizontal, initialScrollAtEnd, stylePaddingBottomState]
4249
+ );
4174
4250
  const onLayoutChange = useCallback((layout) => {
4175
4251
  doInitialScroll();
4176
4252
  handleLayout(ctx, layout, setCanRender);
@@ -4270,6 +4346,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4270
4346
  []
4271
4347
  );
4272
4348
  const onScrollHandler = useStickyScrollHandler(stickyHeaderIndices, horizontal, ctx, fns.onScroll);
4349
+ const refreshControlElement = refreshControl;
4273
4350
  return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
4274
4351
  ListComponent,
4275
4352
  {
@@ -4284,13 +4361,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4284
4361
  ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
4285
4362
  ListHeaderComponent,
4286
4363
  onLayout,
4287
- onLayoutHeader,
4364
+ onLayoutFooter,
4288
4365
  onMomentumScrollEnd: fns.onMomentumScrollEnd,
4289
4366
  onScroll: onScrollHandler,
4290
4367
  recycleItems,
4291
- refreshControl: refreshControl ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControl, {
4292
- progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
4293
- }) : refreshControl : onRefresh && /* @__PURE__ */ React2.createElement(
4368
+ refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React2.cloneElement(refreshControlElement, {
4369
+ progressViewOffset: ((_d = refreshControlElement.props.progressViewOffset) != null ? _d : 0) + stylePaddingTopState
4370
+ }) : refreshControlElement : onRefresh && /* @__PURE__ */ React2.createElement(
4294
4371
  RefreshControl,
4295
4372
  {
4296
4373
  onRefresh,
@@ -4300,7 +4377,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
4300
4377
  ),
4301
4378
  refScrollView: combinedRef,
4302
4379
  renderScrollComponent,
4303
- scrollAdjustHandler: (_d = refState.current) == null ? void 0 : _d.scrollAdjustHandler,
4380
+ scrollAdjustHandler: (_e = refState.current) == null ? void 0 : _e.scrollAdjustHandler,
4304
4381
  scrollEventThrottle: 0,
4305
4382
  snapToIndices,
4306
4383
  stickyHeaderIndices,
@@ -0,0 +1,204 @@
1
+ import * as React from 'react';
2
+ import { ScrollViewComponent, ScrollResponderMixin, Insets as Insets$1, ScrollViewProps } from 'react-native';
3
+ import { KeyboardChatScrollViewProps } from 'react-native-keyboard-controller';
4
+ import { AnimatedLegendListProps } from '@legendapp/list/reanimated';
5
+
6
+ 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}`;
7
+ type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
8
+ type ListenerTypeValueMap = {
9
+ activeStickyIndex: number;
10
+ animatedScrollY: any;
11
+ debugComputedScroll: number;
12
+ debugRawScroll: number;
13
+ extraData: any;
14
+ footerSize: number;
15
+ headerSize: number;
16
+ lastItemKeys: string[];
17
+ lastPositionUpdate: number;
18
+ maintainVisibleContentPosition: MaintainVisibleContentPositionNormalized;
19
+ numColumns: number;
20
+ numContainers: number;
21
+ numContainersPooled: number;
22
+ otherAxisSize: number;
23
+ readyToRender: boolean;
24
+ scrollAdjust: number;
25
+ scrollAdjustPending: number;
26
+ scrollAdjustUserOffset: number;
27
+ scrollSize: {
28
+ width: number;
29
+ height: number;
30
+ };
31
+ snapToOffsets: number[];
32
+ stylePaddingTop: number;
33
+ totalSize: number;
34
+ } & {
35
+ [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
36
+ } & {
37
+ [K in ListenerType as K extends `containerItemData${number}` ? K : never]: any;
38
+ } & {
39
+ [K in ListenerType as K extends `containerPosition${number}` ? K : never]: number;
40
+ } & {
41
+ [K in ListenerType as K extends `containerColumn${number}` ? K : never]: number;
42
+ } & {
43
+ [K in ListenerType as K extends `containerSpan${number}` ? K : never]: number;
44
+ } & {
45
+ [K in ListenerType as K extends `containerSticky${number}` ? K : never]: boolean;
46
+ };
47
+
48
+ interface Insets {
49
+ top: number;
50
+ left: number;
51
+ bottom: number;
52
+ right: number;
53
+ }
54
+ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
55
+ data: boolean;
56
+ size: boolean;
57
+ shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
58
+ }
59
+ type LegendListState = {
60
+ activeStickyIndex: number;
61
+ contentLength: number;
62
+ data: readonly any[];
63
+ elementAtIndex: (index: number) => any;
64
+ end: number;
65
+ endBuffered: number;
66
+ isAtEnd: boolean;
67
+ isAtStart: boolean;
68
+ listen: <T extends LegendListListenerType>(listenerType: T, callback: (value: ListenerTypeValueMap[T]) => void) => () => void;
69
+ listenToPosition: (key: string, callback: (value: number) => void) => () => void;
70
+ positionAtIndex: (index: number) => number;
71
+ positionByKey: (key: string) => number | undefined;
72
+ scroll: number;
73
+ scrollLength: number;
74
+ scrollVelocity: number;
75
+ sizeAtIndex: (index: number) => number;
76
+ sizes: Map<string, number>;
77
+ start: number;
78
+ startBuffered: number;
79
+ };
80
+ type LegendListRef$1 = {
81
+ /**
82
+ * Displays the scroll indicators momentarily.
83
+ */
84
+ flashScrollIndicators(): void;
85
+ /**
86
+ * Returns the native ScrollView component reference.
87
+ */
88
+ getNativeScrollRef(): any;
89
+ /**
90
+ * Returns the scroll responder instance for handling scroll events.
91
+ */
92
+ getScrollableNode(): any;
93
+ /**
94
+ * Returns the ScrollResponderMixin for advanced scroll handling.
95
+ */
96
+ getScrollResponder(): any;
97
+ /**
98
+ * Returns the internal state of the scroll virtualization.
99
+ */
100
+ getState(): LegendListState;
101
+ /**
102
+ * Scrolls a specific index into view.
103
+ * @param params - Parameters for scrolling.
104
+ * @param params.animated - If true, animates the scroll. Default: true.
105
+ * @param params.index - The index to scroll to.
106
+ */
107
+ scrollIndexIntoView(params: {
108
+ animated?: boolean | undefined;
109
+ index: number;
110
+ }): Promise<void>;
111
+ /**
112
+ * Scrolls a specific index into view.
113
+ * @param params - Parameters for scrolling.
114
+ * @param params.animated - If true, animates the scroll. Default: true.
115
+ * @param params.item - The item to scroll to.
116
+ */
117
+ scrollItemIntoView(params: {
118
+ animated?: boolean | undefined;
119
+ item: any;
120
+ }): Promise<void>;
121
+ /**
122
+ * Scrolls to the end of the list.
123
+ * @param options - Options for scrolling.
124
+ * @param options.animated - If true, animates the scroll. Default: true.
125
+ * @param options.viewOffset - Offset from the target position.
126
+ */
127
+ scrollToEnd(options?: {
128
+ animated?: boolean | undefined;
129
+ viewOffset?: number | undefined;
130
+ }): Promise<void>;
131
+ /**
132
+ * Scrolls to a specific index in the list.
133
+ * @param params - Parameters for scrolling.
134
+ * @param params.animated - If true, animates the scroll. Default: true.
135
+ * @param params.index - The index to scroll to.
136
+ * @param params.viewOffset - Offset from the target position.
137
+ * @param params.viewPosition - Position of the item in the viewport (0 to 1).
138
+ */
139
+ scrollToIndex(params: {
140
+ animated?: boolean | undefined;
141
+ index: number;
142
+ viewOffset?: number | undefined;
143
+ viewPosition?: number | undefined;
144
+ }): Promise<void>;
145
+ /**
146
+ * Scrolls to a specific item in the list.
147
+ * @param params - Parameters for scrolling.
148
+ * @param params.animated - If true, animates the scroll. Default: true.
149
+ * @param params.item - The item to scroll to.
150
+ * @param params.viewOffset - Offset from the target position.
151
+ * @param params.viewPosition - Position of the item in the viewport (0 to 1).
152
+ */
153
+ scrollToItem(params: {
154
+ animated?: boolean | undefined;
155
+ item: any;
156
+ viewOffset?: number | undefined;
157
+ viewPosition?: number | undefined;
158
+ }): Promise<void>;
159
+ /**
160
+ * Scrolls to a specific offset in pixels.
161
+ * @param params - Parameters for scrolling.
162
+ * @param params.offset - The pixel offset to scroll to.
163
+ * @param params.animated - If true, animates the scroll. Default: true.
164
+ */
165
+ scrollToOffset(params: {
166
+ offset: number;
167
+ animated?: boolean | undefined;
168
+ }): Promise<void>;
169
+ /**
170
+ * Sets or adds to the offset of the visible content anchor.
171
+ * @param value - The offset to set or add.
172
+ * @param animated - If true, uses Animated to animate the change.
173
+ */
174
+ setVisibleContentAnchorOffset(value: number | ((val: number) => number)): void;
175
+ /**
176
+ * Sets whether scroll processing is enabled.
177
+ * @param enabled - If true, scroll processing is enabled.
178
+ */
179
+ setScrollProcessingEnabled(enabled: boolean): void;
180
+ /**
181
+ * Clears internal virtualization caches.
182
+ * @param options - Cache clearing options.
183
+ * @param options.mode - `sizes` clears measurement caches. `full` also clears key/position caches.
184
+ */
185
+ clearCaches(options?: {
186
+ mode?: "sizes" | "full";
187
+ }): void;
188
+ /**
189
+ * Reports an externally measured content inset. Pass null/undefined to clear.
190
+ * Values are merged on top of props/animated/native insets.
191
+ */
192
+ reportContentInset(inset?: Partial<Insets> | null): void;
193
+ };
194
+
195
+ type LegendListRef = Omit<LegendListRef$1, "getNativeScrollRef" | "getScrollResponder" | "reportContentInset"> & {
196
+ getNativeScrollRef(): React.ElementRef<typeof ScrollViewComponent>;
197
+ getScrollResponder(): ScrollResponderMixin;
198
+ reportContentInset(inset?: Partial<Insets$1> | null): void;
199
+ };
200
+
201
+ type KeyboardChatScrollViewPropsUnique = Omit<KeyboardChatScrollViewProps, keyof ScrollViewProps | "inverted" | "ScrollViewComponent">;
202
+ declare const KeyboardAvoidingLegendList: <ItemT>(props: Omit<AnimatedLegendListProps<ItemT>, "renderScrollComponent"> & KeyboardChatScrollViewPropsUnique & React.RefAttributes<LegendListRef>) => React.ReactNode;
203
+
204
+ export { KeyboardAvoidingLegendList };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var reactNativeKeyboardController = require('react-native-keyboard-controller');
5
+ var reanimated = require('@legendapp/list/reanimated');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
26
+
27
+ // src/integrations/keyboard-test.tsx
28
+ var typedForwardRef = React.forwardRef;
29
+ var KeyboardAvoidingLegendList = typedForwardRef(function KeyboardAvoidingLegendList2(props, forwardedRef) {
30
+ const memoList = React.useCallback((listProps) => /* @__PURE__ */ React__namespace.createElement(reactNativeKeyboardController.KeyboardChatScrollView, { ...listProps }), []);
31
+ return /* @__PURE__ */ React__namespace.createElement(reanimated.AnimatedLegendList, { ref: forwardedRef, renderScrollComponent: memoList, ...props });
32
+ });
33
+
34
+ exports.KeyboardAvoidingLegendList = KeyboardAvoidingLegendList;
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import { useCallback, forwardRef } from 'react';
3
+ import { KeyboardChatScrollView } from 'react-native-keyboard-controller';
4
+ import { AnimatedLegendList } from '@legendapp/list/reanimated';
5
+
6
+ // src/integrations/keyboard-test.tsx
7
+ var typedForwardRef = forwardRef;
8
+ var KeyboardAvoidingLegendList = typedForwardRef(function KeyboardAvoidingLegendList2(props, forwardedRef) {
9
+ const memoList = useCallback((listProps) => /* @__PURE__ */ React.createElement(KeyboardChatScrollView, { ...listProps }), []);
10
+ return /* @__PURE__ */ React.createElement(AnimatedLegendList, { ref: forwardedRef, renderScrollComponent: memoList, ...props });
11
+ });
12
+
13
+ export { KeyboardAvoidingLegendList };
package/keyboard.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as React$1 from 'react';
1
+ import * as React from 'react';
2
2
  import { ScrollViewComponent, ScrollResponderMixin, Insets as Insets$1 } from 'react-native';
3
3
  import { ScrollEvent, ScrollHandlerProcessed } from 'react-native-reanimated';
4
4
  import { AnimatedLegendListProps } from '@legendapp/list/reanimated';
@@ -204,6 +204,6 @@ declare const KeyboardAvoidingLegendList: <ItemT>(props: Omit<AnimatedLegendList
204
204
  onScroll?: KeyboardOnScrollHandler;
205
205
  contentInset?: Insets$1 | undefined;
206
206
  safeAreaInsetBottom?: number;
207
- } & React$1.RefAttributes<LegendListRef>) => React$1.ReactNode;
207
+ } & React.RefAttributes<LegendListRef>) => React.ReactElement | null;
208
208
 
209
209
  export { KeyboardAvoidingLegendList };