Skip to content

Commit 377df0e

Browse files
authored
Merge pull request #2 from medicbleep/feat/segment-accessibility
2 parents ca5a74e + 3f37abb commit 377df0e

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

src/index.tsx

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import React, { useEffect } from 'react';
22
import {
3+
AccessibilityRole,
4+
AccessibilityState,
5+
AccessibilityValue,
36
Pressable,
47
StyleSheet,
58
Text,
@@ -14,11 +17,20 @@ import Animated, {
1417
} from 'react-native-reanimated';
1518
import { widthPercentageToDP } from 'react-native-responsive-screen';
1619

17-
interface SegmentedControlProps {
20+
export interface Segment {
21+
label: string;
22+
accessibilityLabel?: string;
23+
accessibilityHint?: string;
24+
accessibilityRole?: AccessibilityRole;
25+
accessibilityState?: AccessibilityState;
26+
accessibilityValue?: AccessibilityValue;
27+
}
28+
29+
export interface SegmentedControlProps {
1830
/**
19-
* The Segments Text Array
31+
* An array of Segments. Can be a mix of strings for the Segment labels, or an object with a `label` and accessibility props.
2032
*/
21-
segments: Array<string>;
33+
segments: Array<string | Segment>;
2234
/**
2335
* The Current Active Segment Index
2436
*/
@@ -115,6 +127,14 @@ const SegmentedControl: React.FC<SegmentedControlProps> = ({
115127
const translateValue = width / segments.length;
116128
const tabTranslateValue = useSharedValue(0);
117129

130+
// Transform and memoize all segments into a `Segment` array.
131+
// This allows for the segments to be transformed only when they change, and to be treated as `Segment` on render.
132+
const memoizedSegments = React.useMemo<Segment[]>(() => {
133+
return segments.map((segment) =>
134+
typeof segment === 'string' ? { label: segment } : segment
135+
);
136+
}, [segments]);
137+
118138
// useCallBack with an empty array as input, which will call inner lambda only once and memoize the reference for future calls
119139
const memoizedTabPressCallback = React.useCallback(
120140
(index) => {
@@ -193,12 +213,22 @@ const SegmentedControl: React.FC<SegmentedControlProps> = ({
193213
tabTranslateAnimatedStyles,
194214
]}
195215
/>
196-
{segments.map((segment, index) => {
216+
{memoizedSegments.map((segment, index) => {
217+
const isSelected = currentIndex === index;
218+
const { label, ...accessibilityProps } = segment;
219+
197220
return (
198221
<Pressable
199222
onPress={() => memoizedTabPressCallback(index)}
200223
key={index}
201224
style={[styles.touchableContainer, pressableWrapper]}
225+
accessibilityState={{ selected: isSelected }}
226+
accessibilityHint={!isSelected ? `Selects ${label} option` : ''}
227+
accessibilityLabel={`${label}, option, ${index + 1} of ${
228+
segments.length
229+
}`}
230+
accessibilityRole="button"
231+
{...accessibilityProps}
202232
>
203233
<View style={styles.textWrapper}>
204234
<Text
@@ -208,7 +238,7 @@ const SegmentedControl: React.FC<SegmentedControlProps> = ({
208238
: finalisedInActiveTextStyle,
209239
]}
210240
>
211-
{segment}
241+
{label}
212242
</Text>
213243
{typeof badgeValues[index] === 'number' && (
214244
<View

0 commit comments

Comments
 (0)