Skip to content

Commit 2e25079

Browse files
committed
fix(image): match legacy Android accessibility handling
1 parent d013256 commit 2e25079

3 files changed

Lines changed: 31 additions & 8 deletions

File tree

packages/react-native-boost/src/plugin/__tests__/parity/parity.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ const IMAGE_CASES = [
129129
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} tintColor={null} style={{ tintColor: "red" }} />',
130130
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} crossOrigin="use-credentials" referrerPolicy="origin" />',
131131
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} alt="Logo" />',
132+
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} alt={null} aria-label="Logo" />',
133+
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} accessible={null} />',
132134
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} aria-label="Logo" accessibilityLabel="Fallback" />',
133135
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} aria-hidden={true} accessible={true} />',
134136
'<Image source={{ uri: "logo.png", width: 16, height: 16 }} aria-busy={true} accessibilityState={{ selected: true }} />',

packages/react-native-boost/src/runtime/__tests__/index.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,26 @@ describe('processImageAccessibilityProps', () => {
472472
expect(processImageAccessibilityProps({ alt: undefined, accessible: false }).accessible).toBe(false);
473473
});
474474

475+
describe('Android null handling follows the installed RN version', () => {
476+
afterEach(restorePlatformMock);
477+
478+
it.each([
479+
[84, { accessibilityLabel: 'Label', accessible: true }],
480+
[85, { accessibilityLabel: 'Label' }],
481+
])('handles a null alt on RN 0.%i', async (minor, expected) => {
482+
const runtime = await loadRuntime(minor);
483+
expect(runtime.processImageAccessibilityProps({ 'alt': null, 'aria-label': 'Label' })).toEqual(expected);
484+
});
485+
486+
it.each([
487+
[84, { accessible: null }],
488+
[85, {}],
489+
])('handles a null accessible prop on RN 0.%i', async (minor, expected) => {
490+
const runtime = await loadRuntime(minor);
491+
expect(runtime.processImageAccessibilityProps({ accessible: null })).toEqual(expected);
492+
});
493+
});
494+
475495
it('uses aria-hidden to force accessible off on iOS while preserving importantForAccessibility', () => {
476496
Platform.OS = 'ios';
477497
expect(

packages/react-native-boost/src/runtime/index.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,7 @@ export function processImageAccessibilityProps(props: Record<string, any>): Reco
544544
result.accessibilityLabelledBy = accessibilityLabelledBy;
545545
}
546546

547-
// The two wrappers resolve `accessible` with DIFFERENT nullish semantics: iOS computes
548-
// `ariaHidden !== true && (alt !== undefined ? true : accessible)`, while Android (RN >= 0.85)
549-
// skips a nullish `alt`/`accessible` entirely (`!= null`), so an `alt={null}` forces `accessible`
550-
// on iOS only.
547+
// RN 0.85 changed Android from undefined checks to nullish checks.
551548
if (Platform.OS === 'ios') {
552549
if (ariaHidden === true) {
553550
result.accessible = false;
@@ -556,10 +553,14 @@ export function processImageAccessibilityProps(props: Record<string, any>): Reco
556553
} else if (accessible !== undefined) {
557554
result.accessible = accessible;
558555
}
559-
} else if (alt != null) {
560-
result.accessible = true;
561-
} else if (accessible != null) {
562-
result.accessible = accessible;
556+
} else {
557+
const minor = getReactNativeMinor();
558+
const usesUndefinedChecks = minor !== null && minor <= 84;
559+
if (usesUndefinedChecks ? alt !== undefined : alt != null) {
560+
result.accessible = true;
561+
} else if (usesUndefinedChecks ? accessible !== undefined : accessible != null) {
562+
result.accessible = accessible;
563+
}
563564
}
564565

565566
if (ariaHidden === true && Platform.OS !== 'ios') {

0 commit comments

Comments
 (0)