Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessibility issue with duplicate elements when loop is enabled #768

Open
oleksiizhuk opened this issue Jan 23, 2025 · 1 comment
Open
Labels
bug Something isn't working

Comments

@oleksiizhuk
Copy link

oleksiizhuk commented Jan 23, 2025

Problem
When using the react-native-reanimated-carousel library with the loop property enabled, the carousel creates duplicate elements to achieve the infinite scrolling effect. However, these duplicate elements are not properly hidden from accessibility services (e.g., screen readers like VoiceOver or TalkBack). This results in the following accessibility issues:

  1. Screen readers announce carousel items multiple times, including for invisible duplicates.
  2. The accessibilityElementsHidden property or similar methods do not correctly hide non-visible elements, causing confusion for users relying on accessibility tools.

Steps to Reproduce

  1. Create a carousel with
  2. 2 or more items. Enable the loop property.
  3. Use a screen reader (VoiceOver on iOS or TalkBack on Android) to navigate through the carousel.
  4. Notice that:
  • Items are announced multiple times (including duplicates).
  • Invisible duplicates are not properly excluded from the accessibility tree.

Expected Behavior
When loop is enabled:

  • Only the currently visible carousel item should be focusable and announced by the screen reader.
  • Duplicated invisible elements (used for looping) should be excluded from the accessibility tree

Actual Behavior
When loop is enabled:

  • Screen readers announce invisible duplicated elements.
  • This creates duplicate announcements for users relying on accessibility tools, leading to a confusing user experience.

Code Example

<Carousel
  loop
  onScrollEnd={(index) => console.log(`Scrolled to index ${index}`)}
  data={[
    { id: 1, cardName: 'Card 1' },
    { id: 2, cardName: 'Card 2' },
  ]}
  renderItem={({ item, index }) => (
    <View
      style={{ height: 200, width: 300, justifyContent: 'center', alignItems: 'center' }}
      accessibilityElementsHidden={index !== carouselRef.current?.getCurrentIndex()}
      importantForAccessibility={index === carouselRef.current?.getCurrentIndex() ? 'yes' : 'no-hide-descendants'}
    >
      <Text>{item.cardName}</Text>
    </View>
  )}
  width={300}
  height={200}
/>
Screen.Recording.2025-01-23.at.12.33.00.mov
@dosubot dosubot bot added the bug Something isn't working label Jan 23, 2025
Copy link

dosubot bot commented Jan 23, 2025

Hey @oleksiizhuk! I'm here to help you with any bugs, questions, or contributions. Let's tackle this issue together!

I found a similar open issue regarding accessibility concerns with duplicate elements when the loop property is enabled in the react-native-reanimated-carousel. The suggested workaround involves using the accessibilityElementsHidden property to hide non-visible elements from screen readers. Here's the proposed solution:

<Carousel
  {...}
  ref={carouselRef}
  renderItem={({ index }) => (
    <View
      accessibilityElementsHidden={
        index !== carouselRef.current?.getCurrentIndex()
      }>
      <Image  />
    </View>
  )}
/>

This approach was tested on iOS and reportedly works well [1].

To continue talking to Dosu, mention @dosu.


Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Other

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant