11import React , { useEffect } from 'react' ;
22import {
3+ AccessibilityRole ,
4+ AccessibilityState ,
5+ AccessibilityValue ,
36 Pressable ,
47 StyleSheet ,
58 Text ,
@@ -23,11 +26,20 @@ export interface TileProps {
2326 width : number ;
2427}
2528
26- interface SegmentedControlProps {
29+ export interface Segment {
30+ label : string ;
31+ accessibilityLabel ?: string ;
32+ accessibilityHint ?: string ;
33+ accessibilityRole ?: AccessibilityRole ;
34+ accessibilityState ?: AccessibilityState ;
35+ accessibilityValue ?: AccessibilityValue ;
36+ }
37+
38+ export interface SegmentedControlProps {
2739 /**
28- * The Segments Text Array
40+ * An array of Segments. Can be a mix of strings for the Segment labels, or an object with a `label` and accessibility props.
2941 */
30- segments : Array < string > ;
42+ segments : Array < string | Segment > ;
3143 /**
3244 * The Current Active Segment Index
3345 */
@@ -129,6 +141,14 @@ const SegmentedControl: React.FC<SegmentedControlProps> = ({
129141 const translateValue = width / segments . length ;
130142 const tabTranslateValue = useSharedValue ( 0 ) ;
131143
144+ // Transform and memoize all segments into a `Segment` array.
145+ // This allows for the segments to be transformed only when they change, and to be treated as `Segment` on render.
146+ const memoizedSegments = React . useMemo < Segment [ ] > ( ( ) => {
147+ return segments . map ( ( segment ) =>
148+ typeof segment === 'string' ? { label : segment } : segment
149+ ) ;
150+ } , [ segments ] ) ;
151+
132152 // useCallBack with an empty array as input, which will call inner lambda only once and memoize the reference for future calls
133153 const memoizedTabPressCallback = React . useCallback (
134154 ( index ) => {
@@ -225,12 +245,22 @@ const SegmentedControl: React.FC<SegmentedControlProps> = ({
225245 style = { [ styles . defaultSegmentedControlWrapper , segmentedControlWrapper ] }
226246 >
227247 { memoizedTile }
228- { segments . map ( ( segment , index ) => {
248+ { memoizedSegments . map ( ( segment , index ) => {
249+ const isSelected = currentIndex === index ;
250+ const { label, ...accessibilityProps } = segment ;
251+
229252 return (
230253 < Pressable
231254 onPress = { ( ) => memoizedTabPressCallback ( index ) }
232255 key = { index }
233256 style = { [ styles . touchableContainer , pressableWrapper ] }
257+ accessibilityState = { { selected : isSelected } }
258+ accessibilityHint = { ! isSelected ? `Selects ${ label } option` : '' }
259+ accessibilityLabel = { `${ label } , option, ${ index + 1 } of ${
260+ segments . length
261+ } `}
262+ accessibilityRole = "button"
263+ { ...accessibilityProps }
234264 >
235265 < View style = { styles . textWrapper } >
236266 < Text
@@ -240,9 +270,9 @@ const SegmentedControl: React.FC<SegmentedControlProps> = ({
240270 : finalisedInActiveTextStyle ,
241271 ] }
242272 >
243- { segment }
273+ { label }
244274 </ Text >
245- { badgeValues [ index ] && (
275+ { typeof badgeValues [ index ] === 'number' && (
246276 < View
247277 style = { [
248278 styles . defaultBadgeContainerStyle ,
0 commit comments