Skip to content

Commit

Permalink
feat: added aria-live as a alias for accessibility-live-region (#34555)
Browse files Browse the repository at this point in the history
Summary:
This adds `aria-live` alias for `accessibilityLiveRegion`, it unifies aria-live and accessibilityLiveRegion and also maps `aria-live='off'` to `accessibilityLiveRegion='none'` as requested on #34424

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[General][Added] - Added aria-live alias for accessibilityLiveRegion.

Pull Request resolved: #34555

Test Plan:
```js
<View aria-live="polite">
  <Text>Clicked {this.state.count} times</Text>
</View>

<View aria-live="off">
  <Text>Clicked {this.state.count} times</Text>
</View>
```

Reviewed By: cipolleschi

Differential Revision: D39206291

Pulled By: jacdebug

fbshipit-source-id: fd2019e7047ff7ff6133fed39f1a70b5a9396f89
  • Loading branch information
mayank-96 authored and facebook-github-bot committed Sep 8, 2022
1 parent 0e8050d commit 7ea54a4
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 7 deletions.
8 changes: 7 additions & 1 deletion Libraries/Components/Pressable/Pressable.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type Props = $ReadOnly<{|
* this accessibility element are hidden.
*/
'aria-hidden'?: ?boolean,
'aria-live'?: ?('polite' | 'assertive' | 'off'),
focusable?: ?boolean,
importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'),
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
Expand Down Expand Up @@ -190,10 +191,11 @@ type Props = $ReadOnly<{|
* LTI update could not be added via codemod */
function Pressable(props: Props, forwardedRef): React.Node {
const {
accessible,
accessibilityState,
'aria-live': ariaLive,
android_disableSound,
android_ripple,
accessible,
'aria-busy': ariaBusy,
'aria-checked': ariaChecked,
'aria-disabled': ariaDisabled,
Expand Down Expand Up @@ -238,10 +240,14 @@ function Pressable(props: Props, forwardedRef): React.Node {
_accessibilityState =
disabled != null ? {..._accessibilityState, disabled} : _accessibilityState;

const accessibilityLiveRegion =
ariaLive === 'off' ? 'none' : ariaLive ?? props.accessibilityLiveRegion;

const restPropsWithDefaults: React.ElementConfig<typeof View> = {
...restProps,
...android_rippleConfig?.viewProps,
accessible: accessible !== false,
accessibilityLiveRegion,
accessibilityState: _accessibilityState,
focusable: focusable !== false,
hitSlop,
Expand Down
7 changes: 5 additions & 2 deletions Libraries/Components/Touchable/TouchableBounce.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ class TouchableBounce extends React.Component<Props, State> {
// adopting `Pressability`, so preserve that behavior.
const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} =
this.state.pressability.getEventHandlers();

const accessibilityLiveRegion =
this.props['aria-live'] === 'off'
? 'none'
: this.props['aria-live'] ?? this.props.accessibilityLiveRegion;
const _accessibilityState = {
busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy,
checked:
Expand All @@ -155,12 +158,12 @@ class TouchableBounce extends React.Component<Props, State> {
accessibilityActions={this.props.accessibilityActions}
onAccessibilityAction={this.props.onAccessibilityAction}
accessibilityValue={this.props.accessibilityValue}
accessibilityLiveRegion={accessibilityLiveRegion}
importantForAccessibility={
this.props['aria-hidden'] === true
? 'no-hide-descendants'
: this.props.importantForAccessibility
}
accessibilityLiveRegion={this.props.accessibilityLiveRegion}
accessibilityViewIsModal={this.props.accessibilityViewIsModal}
accessibilityElementsHidden={
this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden
Expand Down
7 changes: 5 additions & 2 deletions Libraries/Components/Touchable/TouchableHighlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,10 @@ class TouchableHighlight extends React.Component<Props, State> {
disabled: this.props.disabled,
}
: this.props.accessibilityState;

const accessibilityLiveRegion =
this.props['aria-live'] === 'off'
? 'none'
: this.props['aria-live'] ?? this.props.accessibilityLiveRegion;
return (
<View
accessible={this.props.accessible !== false}
Expand All @@ -307,7 +310,7 @@ class TouchableHighlight extends React.Component<Props, State> {
? 'no-hide-descendants'
: this.props.importantForAccessibility
}
accessibilityLiveRegion={this.props.accessibilityLiveRegion}
accessibilityLiveRegion={accessibilityLiveRegion}
accessibilityViewIsModal={this.props.accessibilityViewIsModal}
accessibilityElementsHidden={
this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden
Expand Down
7 changes: 6 additions & 1 deletion Libraries/Components/Touchable/TouchableNativeFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,11 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
}
: _accessibilityState;

const accessibilityLiveRegion =
this.props['aria-live'] === 'off'
? 'none'
: this.props['aria-live'] ?? this.props.accessibilityLiveRegion;

return React.cloneElement(
element,
{
Expand All @@ -296,7 +301,7 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
this.props['aria-hidden'] === true
? 'no-hide-descendants'
: this.props.importantForAccessibility,
accessibilityLiveRegion: this.props.accessibilityLiveRegion,
accessibilityLiveRegion: accessibilityLiveRegion,
accessibilityViewIsModal: this.props.accessibilityViewIsModal,
accessibilityElementsHidden:
this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden,
Expand Down
7 changes: 6 additions & 1 deletion Libraries/Components/Touchable/TouchableOpacity.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ class TouchableOpacity extends React.Component<Props, State> {
}
: _accessibilityState;

const accessibilityLiveRegion =
this.props['aria-live'] === 'off'
? 'none'
: this.props['aria-live'] ?? this.props.accessibilityLiveRegion;

return (
<Animated.View
accessible={this.props.accessible !== false}
Expand All @@ -251,7 +256,7 @@ class TouchableOpacity extends React.Component<Props, State> {
? 'no-hide-descendants'
: this.props.importantForAccessibility
}
accessibilityLiveRegion={this.props.accessibilityLiveRegion}
accessibilityLiveRegion={accessibilityLiveRegion}
accessibilityViewIsModal={this.props.accessibilityViewIsModal}
accessibilityElementsHidden={
this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden
Expand Down
9 changes: 9 additions & 0 deletions Libraries/Components/Touchable/TouchableWithoutFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Props = $ReadOnly<{|
'aria-expanded'?: ?boolean,
'aria-selected'?: ?boolean,
'aria-hidden'?: ?boolean,
'aria-live'?: ?('polite' | 'assertive' | 'off'),
children?: ?React.Node,
delayLongPress?: ?number,
delayPressIn?: ?number,
Expand Down Expand Up @@ -82,6 +83,7 @@ type State = $ReadOnly<{|

const PASSTHROUGH_PROPS = [
'accessibilityActions',
'accessibilityElementsHidden',
'accessibilityHint',
'accessibilityLanguage',
'accessibilityIgnoresInvertColors',
Expand All @@ -91,6 +93,7 @@ const PASSTHROUGH_PROPS = [
'accessibilityValue',
'accessibilityViewIsModal',
'hitSlop',
'importantForAccessibility',
'nativeID',
'onAccessibilityAction',
'onBlur',
Expand All @@ -107,6 +110,8 @@ class TouchableWithoutFeedback extends React.Component<Props, State> {
render(): React.Node {
const element = React.Children.only(this.props.children);
const children = [element.props.children];
const ariaLive = this.props['aria-live'];

if (__DEV__) {
if (element.type === View) {
children.push(
Expand Down Expand Up @@ -151,6 +156,10 @@ class TouchableWithoutFeedback extends React.Component<Props, State> {
this.props['aria-hidden'] === true
? 'no-hide-descendants'
: this.props.importantForAccessibility,
accessibilityLiveRegion:
ariaLive === 'off'
? 'none'
: ariaLive ?? this.props.accessibilityLiveRegion,
};
for (const prop of PASSTHROUGH_PROPS) {
if (this.props[prop] !== undefined) {
Expand Down
5 changes: 5 additions & 0 deletions Libraries/Components/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const View: React.AbstractComponent<
(
{
accessibilityElementsHidden,
accessibilityLiveRegion,
'aria-live': ariaLive,
accessibilityRole,
'aria-hidden': ariaHidden,
focusable,
Expand Down Expand Up @@ -135,6 +137,9 @@ const View: React.AbstractComponent<
return (
<TextAncestor.Provider value={false}>
<ViewNativeComponent
accessibilityLiveRegion={
ariaLive === 'off' ? 'none' : ariaLive ?? accessibilityLiveRegion
}
focusable={tabIndex !== undefined ? !tabIndex : focusable}
accessibilityState={_accessibilityState}
accessibilityRole={
Expand Down
10 changes: 10 additions & 0 deletions Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,16 @@ type AndroidViewProps = $ReadOnly<{|
*/
accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'),

/**
* Indicates to accessibility services whether the user should be notified
* when this view changes. Works for Android API >= 19 only.
*
* @platform android
*
* See https://reactnative.dev/docs/view#accessibilityliveregion
*/
'aria-live'?: ?('polite' | 'assertive' | 'off'),

/**
* Controls how view is important for accessibility which is if it
* fires accessibility events and if it is reported to accessibility services
Expand Down

0 comments on commit 7ea54a4

Please sign in to comment.