Skip to content

anchoredEndSpace: list cannot be scrolled toward the end when the reserved end-space (spacer) size is > 0 #490

Description

@ptrnk0

Summary

In the repo's own AI Chat example, once a prompt is anchored to the top via anchoredEndSpace and the content below the anchor is shorter than the viewport, the list reserves a positive-size end spacer and then cannot be scrolled toward the end at all. The large empty end-space below the last message is unreachable by touch — swiping up does nothing. Scrolling up toward earlier history still works.

When the content below the anchor is taller than the viewport, the reserved spacer size is 0 and scrolling works normally — which points at the spacer itself as the cause.

Reproduced in the library's example app

  • Repo: LegendApp/legend-list @ v3.3.1 (commit 7ee7f11)
  • App: example/
  • Screen: AI Chat (example/screens/examples/AiChatExample.tsx, route slug ai-chat), list props in example/screens/examples/chatShared.tsx  getAiChatListProps
  • Component: KeyboardAwareLegendList (@legendapp/list/keyboard)

Relevant props (getAiChatListProps):

{
  anchoredEndSpace: anchorIndex !== undefined
    ? { anchorIndex, anchorMaxSize: 72, anchorOffset: 16 }
    : undefined,
  maintainVisibleContentPosition: true,
  initialScrollAtEnd: true,
  recycleItems: true,
  estimatedItemSize: 520,
  // note: no alignItemsAtEnd
}

anchorIndex is set to the index of the just-sent prompt so it pins to the top while the reply streams below (useAiChatExample.sendPrompt).

Steps to reproduce

  1. Run the example/ app on iOS and open the AI Chat example.
  2. Type any short prompt (e.g. Hello) and tap Send.
  3. The prompt pins to the top and a short Prompt received: … reply renders below it, leaving a large empty end-space below the last message.
  4. Try to scroll the list toward the end (swipe up), anywhere in the empty region.

Expected

The reserved end-space is part of the scrollable content, so the list should scroll — you should be able to drag the anchored message up / reach the spacer region, like any list with a large footer.

Actual

The list is frozen at the anchored offset. A swipe up of ~½ the screen height, starting from inside the empty region, produces zero movement. The empty end-space below the last message cannot be scrolled into or through. Only scrolling up toward earlier history works.

See the attached screen recording (from the example app).

Environment

  |   -- | -- @legendapp/list | 3.3.1 (commit 7ee7f11) example app expo | ~54.0.33 example app react-native | 0.81.5 (New Architecture) react | 19.1.0 react-native-reanimated | 4.3.0 react-native-keyboard-controller | ^1.21.7 Platform | iOS 26.5 simulator (iPhone 17 Pro Max)

Likely cause

The behavior tracks exactly with the spacer size computed in src/core/updateAnchoredEndSpace.ts:

nextSize = Math.max(0, state.scrollLength - contentBelowAnchor - anchorOffset)
  • contentBelowAnchor >= scrollLength  nextSize === 0  scrolls fine
  • contentBelowAnchor < scrollLength  nextSize > 0  frozen; cannot scroll toward the end

It looks like the anchored offset is being treated as the maximum scroll offset (the reserved spacer isn't included in the scrollable range), so once the anchor is pinned there's no way to scroll the content up into the reserved space.

Screen.Recording.2026-07-06.at.18.09.24.mov

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions