Skip to content

Commit 35dd861

Browse files
Sladyn Nunesfacebook-github-bot
Sladyn Nunes
authored andcommitted
Fix/30842 - Add accessibilityState prop in slider (#31145)
Summary: Accessibility service does not announce "selected" on accessibilityState = {selected: true} of the Button Component. Issue link - #30956 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [General] [Added] - Add accessibilityState prop to Slider component Pull Request resolved: #31145 Test Plan: Verified accessibility states are read by voiceover and talkback. Some state values aren't handled by iOS and have been identified. Added snapshot tests to test accessibilityState.disabled = disabled values `js1 test Slider-test` Reviewed By: yungsters Differential Revision: D28337723 Pulled By: lunaleaps fbshipit-source-id: 72a54d8d9dcf1fafb9785c81da99f32a21f3df00
1 parent 0aa1aa6 commit 35dd861

File tree

4 files changed

+210
-1
lines changed

4 files changed

+210
-1
lines changed

Libraries/Components/Slider/Slider.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import StyleSheet, {
1919
import type {ImageSource} from '../../Image/ImageSource';
2020
import type {ViewProps} from '../View/ViewPropTypes';
2121
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
22+
import type {AccessibilityState} from '../View/ViewAccessibility';
2223

2324
type Event = SyntheticEvent<
2425
$ReadOnly<{|
@@ -131,6 +132,11 @@ type Props = $ReadOnly<{|
131132
* Used to locate this view in UI automation tests.
132133
*/
133134
testID?: ?string,
135+
136+
/**
137+
Indicates to accessibility services that UI Component is in a specific State.
138+
*/
139+
accessibilityState?: ?AccessibilityState,
134140
|}>;
135141

136142
/**
@@ -200,7 +206,6 @@ const Slider = (
200206
const style = StyleSheet.compose(styles.slider, props.style);
201207

202208
const {
203-
disabled = false,
204209
value = 0.5,
205210
minimumValue = 0,
206211
maximumValue = 1,
@@ -230,9 +235,16 @@ const Slider = (
230235
}
231236
: null;
232237

238+
const disabled =
239+
props.disabled === true || props.accessibilityState?.disabled === true;
240+
const accessibilityState = disabled
241+
? {...props.accessibilityState, disabled: true}
242+
: props.accessibilityState;
243+
233244
return (
234245
<SliderNativeComponent
235246
{...localProps}
247+
accessibilityState={accessibilityState}
236248
// TODO: Reconcile these across the two platforms.
237249
enabled={!disabled}
238250
disabled={disabled}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
* @format
9+
*/
10+
11+
import * as React from 'react';
12+
import ReactTestRenderer from 'react-test-renderer';
13+
import Slider from '../Slider/Slider';
14+
15+
describe('<Slider />', () => {
16+
it('should render as expected', () => {
17+
expect(ReactTestRenderer.create(<Slider />)).toMatchSnapshot();
18+
});
19+
20+
it('should set disabled as false', () => {
21+
// Slider component should set disabled prop as false by default
22+
expect(ReactTestRenderer.create(<Slider />)).toMatchSnapshot();
23+
expect(
24+
ReactTestRenderer.create(
25+
<Slider accessibilityState={{disabled: false}} />,
26+
),
27+
).toMatchSnapshot();
28+
});
29+
it('should set disabled as true', () => {
30+
expect(ReactTestRenderer.create(<Slider disabled />)).toMatchSnapshot();
31+
expect(
32+
ReactTestRenderer.create(
33+
<Slider accessibilityState={{disabled: true}} />,
34+
),
35+
).toMatchSnapshot();
36+
});
37+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`<Slider /> should render as expected 1`] = `
4+
<RCTSlider
5+
disabled={false}
6+
enabled={true}
7+
maximumValue={1}
8+
minimumValue={0}
9+
onChange={null}
10+
onResponderTerminationRequest={[Function]}
11+
onSlidingComplete={null}
12+
onStartShouldSetResponder={[Function]}
13+
onValueChange={null}
14+
step={0}
15+
style={
16+
Object {
17+
"height": 40,
18+
}
19+
}
20+
value={0.5}
21+
/>
22+
`;
23+
24+
exports[`<Slider /> should set disabled as false 1`] = `
25+
<RCTSlider
26+
disabled={false}
27+
enabled={true}
28+
maximumValue={1}
29+
minimumValue={0}
30+
onChange={null}
31+
onResponderTerminationRequest={[Function]}
32+
onSlidingComplete={null}
33+
onStartShouldSetResponder={[Function]}
34+
onValueChange={null}
35+
step={0}
36+
style={
37+
Object {
38+
"height": 40,
39+
}
40+
}
41+
value={0.5}
42+
/>
43+
`;
44+
45+
exports[`<Slider /> should set disabled as false 2`] = `
46+
<RCTSlider
47+
accessibilityState={
48+
Object {
49+
"disabled": false,
50+
}
51+
}
52+
disabled={false}
53+
enabled={true}
54+
maximumValue={1}
55+
minimumValue={0}
56+
onChange={null}
57+
onResponderTerminationRequest={[Function]}
58+
onSlidingComplete={null}
59+
onStartShouldSetResponder={[Function]}
60+
onValueChange={null}
61+
step={0}
62+
style={
63+
Object {
64+
"height": 40,
65+
}
66+
}
67+
value={0.5}
68+
/>
69+
`;
70+
71+
exports[`<Slider /> should set disabled as true 1`] = `
72+
<RCTSlider
73+
accessibilityState={
74+
Object {
75+
"disabled": true,
76+
}
77+
}
78+
disabled={true}
79+
enabled={false}
80+
maximumValue={1}
81+
minimumValue={0}
82+
onChange={null}
83+
onResponderTerminationRequest={[Function]}
84+
onSlidingComplete={null}
85+
onStartShouldSetResponder={[Function]}
86+
onValueChange={null}
87+
step={0}
88+
style={
89+
Object {
90+
"height": 40,
91+
}
92+
}
93+
value={0.5}
94+
/>
95+
`;
96+
97+
exports[`<Slider /> should set disabled as true 2`] = `
98+
<RCTSlider
99+
accessibilityState={
100+
Object {
101+
"disabled": true,
102+
}
103+
}
104+
disabled={true}
105+
enabled={false}
106+
maximumValue={1}
107+
minimumValue={0}
108+
onChange={null}
109+
onResponderTerminationRequest={[Function]}
110+
onSlidingComplete={null}
111+
onStartShouldSetResponder={[Function]}
112+
onValueChange={null}
113+
step={0}
114+
style={
115+
Object {
116+
"height": 40,
117+
}
118+
}
119+
value={0.5}
120+
/>
121+
`;

packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js

+39
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const {
2222
TouchableWithoutFeedback,
2323
Alert,
2424
StyleSheet,
25+
Slider,
2526
Platform,
2627
} = require('react-native');
2728
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
@@ -696,6 +697,38 @@ class AccessibilityActionsExample extends React.Component<{}> {
696697
}
697698
}
698699

700+
function SliderAccessibilityExample(): React.Node {
701+
return (
702+
<View>
703+
<RNTesterBlock
704+
title="Disabled Slider via disabled"
705+
description="Verify with TalkBack/VoiceOver announces Slider as disabled">
706+
<Slider value={25} maximumValue={100} minimumValue={0} disabled />
707+
</RNTesterBlock>
708+
<RNTesterBlock
709+
title="Disabled Slider via accessibiltyState"
710+
description="Verify with TalkBack/VoiceOver announces Slider as disabled">
711+
<Slider
712+
value={75}
713+
maximumValue={100}
714+
minimumValue={0}
715+
accessibilityState={{disabled: true}}
716+
/>
717+
</RNTesterBlock>
718+
<RNTesterBlock
719+
title="Selected Slider"
720+
description="Verify with TalkBack/VoiceOver announces Slider as selected">
721+
<Slider
722+
value={75}
723+
maximumValue={100}
724+
minimumValue={0}
725+
accessibilityState={{selected: true}}
726+
/>
727+
</RNTesterBlock>
728+
</View>
729+
);
730+
}
731+
699732
type FakeSliderExampleState = {
700733
current: number,
701734
textualValue: 'center' | 'left' | 'right',
@@ -970,6 +1003,12 @@ exports.examples = [
9701003
return <AccessibilityActionsExample />;
9711004
},
9721005
},
1006+
{
1007+
title: 'Slider Accessibility Examples',
1008+
render(): React.Element<typeof SliderAccessibilityExample> {
1009+
return <SliderAccessibilityExample />;
1010+
},
1011+
},
9731012
{
9741013
title: 'Fake Slider Example',
9751014
render(): React.Element<typeof FakeSliderExample> {

0 commit comments

Comments
 (0)