Shopify / Shopify/flash-list

Android: TalkBack navigates inverted lists in reverse order

Open
#2,381 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
7.2k
Forks
393
Avg merge
1d 3h
Merged PRs (30d)
1

Description

Description

On Android, TalkBack navigates a vertical FlashList with inverted={true} in the opposite direction from the visual and chronological order of its items.

This affects chat-like lists: the standard TalkBack gesture for moving to the next element focuses the previous message, while the gesture for moving to the previous element focuses the next message. The same list has the expected accessibility traversal order on iOS.

Current behavior

With TalkBack enabled on Android:

  • Swiping right to move to the next accessibility element focuses the previous message.
  • Swiping left to move to the previous accessibility element focuses the next message.
  • Users must reverse the normal TalkBack gestures to read the conversation in visual order.

Recording:

https://github.com/user-attachments/assets/1fd0218d-7452-4eaf-8cd8-ced34accae5f

Expected behavior

TalkBack traversal should follow the list's visual order:

  • The next gesture should focus the next visible message.
  • The previous gesture should focus the previous visible message.

Setting inverted={true} should reverse the list visually without reversing the semantic accessibility traversal exposed to TalkBack.

Reproduction

Expo Snack or minimal reproduction link:

https://snack.expo.dev/@sharabai/flashlist-reverted-list-accessibility-issue?platform=android

TalkBack cannot be tested in Snack's embedded preview. Run the Snack through Expo Go on an Android emulator or a physical Android device:

  1. Enable TalkBack on the Android emulator or physical device.
  2. Open the Snack in Expo Go.
  3. Focus a message in the inverted list.
  4. Swipe right to move to the next accessibility element.
  5. Observe that TalkBack focuses the previous visible message instead of the next one.
  6. Swipe left to move to the previous accessibility element.
  7. Observe that TalkBack focuses the next visible message instead of the previous one.

TalkBack navigates the inverted list in the direction opposite to its visual order.

Platform

  • iOS
  • Android
  • Web (if applicable)

Environment

React Native info output:
The original recording was captured in Expensify/App. Full `npx react-native info`
output was not captured with the report.

FlashList version: 2.3.0

Additional context

  • The issue is reproducible in Expensify staging and production.
  • iOS does not exhibit the reversed screen-reader traversal.
  • Sorting the rendered items so that their React/Fiber order matches their visual order did not fix Android TalkBack traversal. React Native DevTools confirmed that the elements were sorted correctly, but TalkBack still moved through them in the wrong direction. This suggests the issue is not caused solely by recycled items being out of order in the React tree.
  • FlashList implements Android inversion with a rotate(180deg) transform on the list and counter-transforms on its items. The Android accessibility traversal generated for this transformed hierarchy appears not to match the resulting visual order.
  • This fails WCAG 2.2 SC 1.3.2 (Meaningful Sequence) and SC 2.4.3 (Focus Order), because chronological message order is meaningful and sequential focus does not preserve it.
  • The current workaround is to use the opposite TalkBack gestures, which is confusing and contrary to normal screen-reader navigation.
  • Original downstream report: https://github.com/Expensify/App/issues/94165

Checklist

  • I've searched existing issues and couldn't find a duplicate
  • I've provided a minimal reproduction (Expo Snack preferred)
  • I'm using the latest version of @shopify/flash-list
  • I've included all required information above

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Android implementation of FlashList's inverted={true} behavior and reproduce the traversal using the linked Expo Snack in Expo Go with TalkBack enabled. Trace how the rotate(180deg) list and counter-transformed items are exposed to accessibility, then verify that next and previous gestures follow visual message order on an Android emulator or device.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, react-native, typescript
Domain
accessibility, mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.