Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : add aria labelled as alias for accessibilityLabelledBy #34725

Closed
3 changes: 3 additions & 0 deletions Libraries/Components/TextInput/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,8 @@ function InternalTextInput(props: Props): React.Node {
} else if (Platform.OS === 'android') {
const style = [props.style];
const autoCapitalize = props.autoCapitalize || 'sentences';
const _accessibilityLabelledBy =
props?.['aria-labelledby'] ?? props?.accessibilityLabelledBy;
const placeholder = props.placeholder ?? '';
let children = props.children;
const childCount = React.Children.count(children);
Expand All @@ -1465,6 +1467,7 @@ function InternalTextInput(props: Props): React.Node {
{...eventHandlers}
accessible={accessible}
accessibilityState={_accessibilityState}
accessibilityLabelledBy={_accessibilityLabelledBy}
autoCapitalize={autoCapitalize}
submitBehavior={submitBehavior}
caretHidden={caretHidden}
Expand Down
48 changes: 28 additions & 20 deletions Libraries/Components/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,25 @@ const View: React.AbstractComponent<
(
{
accessibilityElementsHidden,
accessibilityLiveRegion,
'aria-live': ariaLive,
accessibilityLabel,
accessibilityLabelledBy,
accessibilityLiveRegion,
accessibilityRole,
'aria-label': ariaLabel,
accessibilityState,
accessibilityValue,
'aria-busy': ariaBusy,
'aria-checked': ariaChecked,
'aria-disabled': ariaDisabled,
'aria-expanded': ariaExpanded,
'aria-hidden': ariaHidden,
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
'aria-live': ariaLive,
'aria-selected': ariaSelected,
'aria-valuemax': ariaValueMax,
'aria-valuemin': ariaValueMin,
'aria-valuenow': ariaValueNow,
'aria-valuetext': ariaValueText,
focusable,
id,
importantForAccessibility,
Expand All @@ -49,14 +62,8 @@ const View: React.AbstractComponent<
}: ViewProps,
forwardedRef,
) => {
const {
accessibilityState,
'aria-busy': ariaBusy,
'aria-checked': ariaChecked,
'aria-disabled': ariaDisabled,
'aria-expanded': ariaExpanded,
'aria-selected': ariaSelected,
} = otherProps;
const _accessibilityLabelledBy =
ariaLabelledBy?.split(/\s*,\s*/g) ?? accessibilityLabelledBy;

const _accessibilityState = {
busy: ariaBusy ?? accessibilityState?.busy,
Expand All @@ -66,6 +73,13 @@ const View: React.AbstractComponent<
selected: ariaSelected ?? accessibilityState?.selected,
};

const _accessibilityValue = {
max: ariaValueMax ?? accessibilityValue?.max,
min: ariaValueMin ?? accessibilityValue?.min,
now: ariaValueNow ?? accessibilityValue?.now,
text: ariaValueText ?? accessibilityValue?.text,
};

// Map role values to AccessibilityRole values
const roleToAccessibilityRoleMapping = {
alert: 'alert',
Expand Down Expand Up @@ -134,20 +148,13 @@ const View: React.AbstractComponent<
treeitem: undefined,
};

const accessibilityValue = {
max: otherProps['aria-valuemax'] ?? otherProps.accessibilityValue?.max,
min: otherProps['aria-valuemin'] ?? otherProps.accessibilityValue?.min,
now: otherProps['aria-valuenow'] ?? otherProps.accessibilityValue?.now,
text: otherProps['aria-valuetext'] ?? otherProps.accessibilityValue?.text,
};
const restWithDefaultProps = {...otherProps, accessibilityValue};

const flattenedStyle = flattenStyle(style);
const newPointerEvents = flattenedStyle?.pointerEvents || pointerEvents;

return (
<TextAncestor.Provider value={false}>
<ViewNativeComponent
{...otherProps}
accessibilityLiveRegion={
ariaLive === 'off' ? 'none' : ariaLive ?? accessibilityLiveRegion
}
Expand All @@ -160,13 +167,14 @@ const View: React.AbstractComponent<
accessibilityElementsHidden={
ariaHidden ?? accessibilityElementsHidden
}
accessibilityLabelledBy={_accessibilityLabelledBy}
dakshbhardwaj marked this conversation as resolved.
Show resolved Hide resolved
accessibilityValue={_accessibilityValue}
importantForAccessibility={
ariaHidden === true
? 'no-hide-descendants'
: importantForAccessibility
}
nativeID={id ?? nativeID}
{...restWithDefaultProps}
style={style}
pointerEvents={newPointerEvents}
ref={forwardedRef}
Expand Down
7 changes: 7 additions & 0 deletions Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,13 @@ export type ViewProps = $ReadOnly<{|
*/
'aria-hidden'?: ?boolean,

/**
* It reperesents the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.
*
* @platform android
*/
'aria-labelledby'?: ?string,

/**
* Views that are only used to layout their children or otherwise don't draw
* anything may be automatically removed from the native hierarchy as an
Expand Down
4 changes: 3 additions & 1 deletion Libraries/Image/Image.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,11 @@ const BaseImage = (props: ImagePropsType, forwardedRef) => {
? loadingIndicatorSource.uri
: null,
ref: forwardedRef,
accessible: props.alt !== undefined ? true : props.accessible,
accessibilityLabel:
props['aria-label'] ?? props.accessibilityLabel ?? props.alt,
accessibilityLabelledBy:
props?.['aria-labelledby'] ?? props?.accessibilityLabelledBy,
accessible: props.alt !== undefined ? true : props.accessible,
accessibilityState: {
busy: props['aria-busy'] ?? props.accessibilityState?.busy,
checked: props['aria-checked'] ?? props.accessibilityState?.checked,
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Image/ImageProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ export type ImageProps = {|
*/
'aria-label'?: ?Stringish,

/**
* Reperesents the nativeID of the associated label. When the assistive technology focuses on the component with this props.
*
* @platform android
*/
'aria-labelledby'?: ?string,
/**
* The text that's read by the screen reader when the user interacts with
* the image.
Expand Down
8 changes: 8 additions & 0 deletions Libraries/Text/TextProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ export type TextProps = $ReadOnly<{|
'aria-disabled'?: ?boolean,
'aria-expanded'?: ?boolean,
'aria-selected'?: ?boolean,

/**
* Reperesents the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.
*
* @platform android
*/
'aria-labelledby'?: ?string,

children?: ?Node,

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1446,4 +1446,18 @@ exports.examples = [
);
},
},
{
title: 'TextInput with aria-labelledby attribute"',
render(): React.Element<typeof View> {
return (
<View>
<Text nativeID="testAriaLabelledBy">Phone Number</Text>
<TextInput
aria-labelledby={'testAriaLabelledBy'}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the support for this implemented in TextInput, Text, Image components?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@necolas I was checking this to update the docs and it seems that Text doesn't ever support accessibilityLabelledBy

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh good to know

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just opened a PR removing it, #35327

style={styles.default}
/>
</View>
);
},
},
];