mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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 - https://github.com/facebook/react-native/issues/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: https://github.com/facebook/react-native/pull/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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
0aa1aa6cc2
commit
35dd86180b
@@ -19,6 +19,7 @@ import StyleSheet, {
|
||||
import type {ImageSource} from '../../Image/ImageSource';
|
||||
import type {ViewProps} from '../View/ViewPropTypes';
|
||||
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
|
||||
import type {AccessibilityState} from '../View/ViewAccessibility';
|
||||
|
||||
type Event = SyntheticEvent<
|
||||
$ReadOnly<{|
|
||||
@@ -131,6 +132,11 @@ type Props = $ReadOnly<{|
|
||||
* Used to locate this view in UI automation tests.
|
||||
*/
|
||||
testID?: ?string,
|
||||
|
||||
/**
|
||||
Indicates to accessibility services that UI Component is in a specific State.
|
||||
*/
|
||||
accessibilityState?: ?AccessibilityState,
|
||||
|}>;
|
||||
|
||||
/**
|
||||
@@ -200,7 +206,6 @@ const Slider = (
|
||||
const style = StyleSheet.compose(styles.slider, props.style);
|
||||
|
||||
const {
|
||||
disabled = false,
|
||||
value = 0.5,
|
||||
minimumValue = 0,
|
||||
maximumValue = 1,
|
||||
@@ -230,9 +235,16 @@ const Slider = (
|
||||
}
|
||||
: null;
|
||||
|
||||
const disabled =
|
||||
props.disabled === true || props.accessibilityState?.disabled === true;
|
||||
const accessibilityState = disabled
|
||||
? {...props.accessibilityState, disabled: true}
|
||||
: props.accessibilityState;
|
||||
|
||||
return (
|
||||
<SliderNativeComponent
|
||||
{...localProps}
|
||||
accessibilityState={accessibilityState}
|
||||
// TODO: Reconcile these across the two platforms.
|
||||
enabled={!disabled}
|
||||
disabled={disabled}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import ReactTestRenderer from 'react-test-renderer';
|
||||
import Slider from '../Slider/Slider';
|
||||
|
||||
describe('<Slider />', () => {
|
||||
it('should render as expected', () => {
|
||||
expect(ReactTestRenderer.create(<Slider />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should set disabled as false', () => {
|
||||
// Slider component should set disabled prop as false by default
|
||||
expect(ReactTestRenderer.create(<Slider />)).toMatchSnapshot();
|
||||
expect(
|
||||
ReactTestRenderer.create(
|
||||
<Slider accessibilityState={{disabled: false}} />,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
it('should set disabled as true', () => {
|
||||
expect(ReactTestRenderer.create(<Slider disabled />)).toMatchSnapshot();
|
||||
expect(
|
||||
ReactTestRenderer.create(
|
||||
<Slider accessibilityState={{disabled: true}} />,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Slider /> should render as expected 1`] = `
|
||||
<RCTSlider
|
||||
disabled={false}
|
||||
enabled={true}
|
||||
maximumValue={1}
|
||||
minimumValue={0}
|
||||
onChange={null}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onSlidingComplete={null}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onValueChange={null}
|
||||
step={0}
|
||||
style={
|
||||
Object {
|
||||
"height": 40,
|
||||
}
|
||||
}
|
||||
value={0.5}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`<Slider /> should set disabled as false 1`] = `
|
||||
<RCTSlider
|
||||
disabled={false}
|
||||
enabled={true}
|
||||
maximumValue={1}
|
||||
minimumValue={0}
|
||||
onChange={null}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onSlidingComplete={null}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onValueChange={null}
|
||||
step={0}
|
||||
style={
|
||||
Object {
|
||||
"height": 40,
|
||||
}
|
||||
}
|
||||
value={0.5}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`<Slider /> should set disabled as false 2`] = `
|
||||
<RCTSlider
|
||||
accessibilityState={
|
||||
Object {
|
||||
"disabled": false,
|
||||
}
|
||||
}
|
||||
disabled={false}
|
||||
enabled={true}
|
||||
maximumValue={1}
|
||||
minimumValue={0}
|
||||
onChange={null}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onSlidingComplete={null}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onValueChange={null}
|
||||
step={0}
|
||||
style={
|
||||
Object {
|
||||
"height": 40,
|
||||
}
|
||||
}
|
||||
value={0.5}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`<Slider /> should set disabled as true 1`] = `
|
||||
<RCTSlider
|
||||
accessibilityState={
|
||||
Object {
|
||||
"disabled": true,
|
||||
}
|
||||
}
|
||||
disabled={true}
|
||||
enabled={false}
|
||||
maximumValue={1}
|
||||
minimumValue={0}
|
||||
onChange={null}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onSlidingComplete={null}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onValueChange={null}
|
||||
step={0}
|
||||
style={
|
||||
Object {
|
||||
"height": 40,
|
||||
}
|
||||
}
|
||||
value={0.5}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`<Slider /> should set disabled as true 2`] = `
|
||||
<RCTSlider
|
||||
accessibilityState={
|
||||
Object {
|
||||
"disabled": true,
|
||||
}
|
||||
}
|
||||
disabled={true}
|
||||
enabled={false}
|
||||
maximumValue={1}
|
||||
minimumValue={0}
|
||||
onChange={null}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onSlidingComplete={null}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onValueChange={null}
|
||||
step={0}
|
||||
style={
|
||||
Object {
|
||||
"height": 40,
|
||||
}
|
||||
}
|
||||
value={0.5}
|
||||
/>
|
||||
`;
|
||||
@@ -22,6 +22,7 @@ const {
|
||||
TouchableWithoutFeedback,
|
||||
Alert,
|
||||
StyleSheet,
|
||||
Slider,
|
||||
Platform,
|
||||
} = require('react-native');
|
||||
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
@@ -696,6 +697,38 @@ class AccessibilityActionsExample extends React.Component<{}> {
|
||||
}
|
||||
}
|
||||
|
||||
function SliderAccessibilityExample(): React.Node {
|
||||
return (
|
||||
<View>
|
||||
<RNTesterBlock
|
||||
title="Disabled Slider via disabled"
|
||||
description="Verify with TalkBack/VoiceOver announces Slider as disabled">
|
||||
<Slider value={25} maximumValue={100} minimumValue={0} disabled />
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock
|
||||
title="Disabled Slider via accessibiltyState"
|
||||
description="Verify with TalkBack/VoiceOver announces Slider as disabled">
|
||||
<Slider
|
||||
value={75}
|
||||
maximumValue={100}
|
||||
minimumValue={0}
|
||||
accessibilityState={{disabled: true}}
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
<RNTesterBlock
|
||||
title="Selected Slider"
|
||||
description="Verify with TalkBack/VoiceOver announces Slider as selected">
|
||||
<Slider
|
||||
value={75}
|
||||
maximumValue={100}
|
||||
minimumValue={0}
|
||||
accessibilityState={{selected: true}}
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
type FakeSliderExampleState = {
|
||||
current: number,
|
||||
textualValue: 'center' | 'left' | 'right',
|
||||
@@ -970,6 +1003,12 @@ exports.examples = [
|
||||
return <AccessibilityActionsExample />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Slider Accessibility Examples',
|
||||
render(): React.Element<typeof SliderAccessibilityExample> {
|
||||
return <SliderAccessibilityExample />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Fake Slider Example',
|
||||
render(): React.Element<typeof FakeSliderExample> {
|
||||
|
||||
Reference in New Issue
Block a user