dohooo / react-native-reanimated-carousel

🎠 React Native swiper/carousel component, fully implemented using reanimated v2, support to iOS/Android/Web. (Swiper/Carousel)
https://react-native-reanimated-carousel.vercel.app
MIT License
2.68k stars 310 forks source link

[Web] The accessibility not work correct with the button inside item #645

Open linhvovan29546 opened 1 month ago

linhvovan29546 commented 1 month ago

Describe the bug The keyboard accessibility on the web is not correctly.

To Reproduce Steps to reproduce the behavior:

  1. Go to my snack and run example
  2. Press the tab button until the last item is displayed.
  3. See error

Expected behavior

Screenshots

https://github.com/user-attachments/assets/1f36bd29-eac0-407c-8d8a-075736fbc793

Versions (please complete the following information):

Smartphone (please complete the following information):

Additional context

dosubot[bot] commented 1 month ago

Hello, @linhvovan29546! I'm here to assist you with any bugs, questions, or contributions you have. Let's work together to resolve the issue you're experiencing.

To resolve the keyboard accessibility issue with a button inside an item when using the "react-native-reanimated-carousel" library, you can use the accessible and accessibilityRole props provided by React Native. These props help in making the components accessible to keyboard navigation and screen readers.

Here's how you can modify the Item component to include these accessibility props:

const Item: React.FC<Props> = (props) => {
  const { animationValue, label, onPress } = props;

  const translateY = useSharedValue(0);

  const containerStyle = useAnimatedStyle(() => {
    const opacity = interpolate(
      animationValue.value,
      [-1, 0, 1],
      [0.5, 1, 0.5],
      Extrapolate.CLAMP,
    );

    return {
      opacity,
    };
  }, [animationValue]);

  const labelStyle = useAnimatedStyle(() => {
    const scale = interpolate(
      animationValue.value,
      [-1, 0, 1],
      [1, 1.25, 1],
      Extrapolate.CLAMP,
    );

    const color = interpolateColor(
      animationValue.value,
      [-1, 0, 1],
      ["#b6bbc0", "#0071fa", "#b6bbc0"],
    );

    return {
      transform: [{ scale }, { translateY: translateY.value }],
      color,
    };
  }, [animationValue, translateY]);

  const onPressIn = React.useCallback(() => {
    translateY.value = withTiming(-8, { duration: 250 });
  }, [translateY]);

  const onPressOut = React.useCallback(() => {
    translateY.value = withTiming(0, { duration: 250 });
  }, [translateY]);

  return (
    <Pressable
      onPress={onPress}
      onPressIn={onPressIn}
      onPressOut={onPressOut}
      accessible={true}
      accessibilityRole="button"
    >
      <Animated.View
        style={[
          {
            height: "100%",
            alignItems: "center",
            justifyContent: "center",
          },
          containerStyle,
        ]}
      >
        <Animated.Text
          style={[{ fontSize: 18, color: "#26292E" }, labelStyle]}
        >
          {label}
        </Animated.Text>
      </Animated.View>
    </Pressable>
  );
};

By adding accessible={true} and accessibilityRole="button" to the Pressable component, you ensure that the button inside the carousel item is accessible via keyboard navigation and screen readers [1].

To continue talking to Dosu, mention @dosu.