From 09b5a05cc64177288814a46614cd72913ab1484a Mon Sep 17 00:00:00 2001 From: Gustavo Parreira Date: Thu, 5 May 2022 11:36:10 +0100 Subject: [PATCH 1/4] feat: allow for a mix of strings and objects in segments array --- src/index.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 39abb17a..000f06e8 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 */ From fe6dc958f45973923b446aa67cd99f85df716436 Mon Sep 17 00:00:00 2001 From: Gustavo Parreira Date: Thu, 5 May 2022 11:37:16 +0100 Subject: [PATCH 2/4] feat: transforming segments prop into an array of Segment, and memoizing it --- src/index.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/index.tsx b/src/index.tsx index 000f06e8..dd4f4b0d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -127,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) => { From 1e9ceafca3bfd30eab480e897b169b6287828737 Mon Sep 17 00:00:00 2001 From: Gustavo Parreira Date: Thu, 5 May 2022 11:38:11 +0100 Subject: [PATCH 3/4] feat: render Segment label and set default accessibility prop values --- src/index.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index dd4f4b0d..a42e5b97 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -213,12 +213,21 @@ 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" > = ({ : finalisedInActiveTextStyle, ]} > - {segment} + {label} {badgeValues[index] && ( Date: Thu, 5 May 2022 11:39:05 +0100 Subject: [PATCH 4/4] feat: overriding accessibility props by spreading the defined values in each Segment --- src/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.tsx b/src/index.tsx index a42e5b97..768b1ddd 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -228,6 +228,7 @@ const SegmentedControl: React.FC = ({ segments.length }`} accessibilityRole="button" + {...accessibilityProps} >