diff --git a/src/index.tsx b/src/index.tsx index 39abb17a..768b1ddd 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,8 @@ import React, { useEffect } from 'react'; import { + AccessibilityRole, + AccessibilityState, + AccessibilityValue, Pressable, StyleSheet, Text, @@ -14,11 +17,20 @@ import Animated, { } from 'react-native-reanimated'; import { widthPercentageToDP } from 'react-native-responsive-screen'; -interface SegmentedControlProps { +export interface Segment { + label: string; + accessibilityLabel?: string; + accessibilityHint?: string; + accessibilityRole?: AccessibilityRole; + accessibilityState?: AccessibilityState; + accessibilityValue?: AccessibilityValue; +} + +export interface SegmentedControlProps { /** - * The Segments Text Array + * An array of Segments. Can be a mix of strings for the Segment labels, or an object with a `label` and accessibility props. */ - segments: Array; + segments: Array; /** * The Current Active Segment Index */ @@ -115,6 +127,14 @@ const SegmentedControl: React.FC = ({ const translateValue = width / segments.length; const tabTranslateValue = useSharedValue(0); + // Transform and memoize all segments into a `Segment` array. + // This allows for the segments to be transformed only when they change, and to be treated as `Segment` on render. + const memoizedSegments = React.useMemo(() => { + return segments.map((segment) => + typeof segment === 'string' ? { label: segment } : segment + ); + }, [segments]); + // useCallBack with an empty array as input, which will call inner lambda only once and memoize the reference for future calls const memoizedTabPressCallback = React.useCallback( (index) => { @@ -193,12 +213,22 @@ const SegmentedControl: React.FC = ({ tabTranslateAnimatedStyles, ]} /> - {segments.map((segment, index) => { + {memoizedSegments.map((segment, index) => { + const isSelected = currentIndex === index; + const { label, ...accessibilityProps } = segment; + return ( memoizedTabPressCallback(index)} key={index} style={[styles.touchableContainer, pressableWrapper]} + accessibilityState={{ selected: isSelected }} + accessibilityHint={!isSelected ? `Selects ${label} option` : ''} + accessibilityLabel={`${label}, option, ${index + 1} of ${ + segments.length + }`} + accessibilityRole="button" + {...accessibilityProps} > = ({ : finalisedInActiveTextStyle, ]} > - {segment} + {label} {badgeValues[index] && (