Skip to content

Commit 14f6ccc

Browse files
authored
Fix accessible prop for Image (#2327)
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The four fields below are mandatory. --> <!-- This fork of react-native provides React Native for macOS for the community. It also contains some changes that are required for usage internal to Microsoft. We are working on reducing the diff between Facebook's public version of react-native and our microsoft/react-native-macos fork. Long term, we want this fork to only contain macOS concerns and have the other iOS and Android concerns contributed upstream. If you are making a new change then one of the following should be done: - Consider if it is possible to achieve the desired behavior without making a change to microsoft/react-native-macos. Often a change can be made in a layer above in facebook/react-native instead. - Create a corresponding PR against [facebook/react-native](https://github.com/facebook/react-native) **Note:** Ideally you would wait for Facebook feedback before submitting to Microsoft, since we want to ensure that this fork doesn't deviate from upstream. --> ## Summary: Problem: Setting the accessible prop to false on RN Image does not remove the image from the accessibility tree on macOS. This is because the accessible prop is mapped to the accessibilityElement property but is set on NSImageView which has no effect. Instead, the accessibilityElement prop should be set on NSImageCell. Solution: Add a way to retrieve NSImageCell from NSImageView and map RN's accessible prop to the accessibilityElement property on it. ## Test Plan: Added a toggle to the 'Accessibility' test example in ImageExamples.js to test the value of the accessible prop. Hovered over the image with Accessibility Inspector and verified that the image is not found when accessible is false. Also verified by turning on VoiceOver and confirmed the image did not get read when the accessible prop is false. accessible prop is true: <img width="1279" alt="Screenshot 2025-01-07 at 11 19 22 AM" src="https://github.com/user-attachments/assets/5b5abe39-f671-4f63-8931-fb0b454ecb3a" /> accessible prop is false: <img width="1277" alt="Screenshot 2025-01-07 at 11 20 29 AM" src="https://github.com/user-attachments/assets/f5704a5f-1416-4559-89d1-b11d80b43b48" />
2 parents ff2292f + ac96486 commit 14f6ccc

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

packages/react-native/Libraries/Image/RCTImageView.mm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,11 @@ - (RCTPlatformView *)reactAccessibilityElement
629629
return _imageView;
630630
}
631631

632+
- (NSCell *)reactAccessibilityElementCell
633+
{
634+
return _imageView.cell;
635+
}
636+
632637
- (NSColor *)tintColor
633638
{
634639
return _imageView.tintColor;

packages/react-native/Libraries/Image/RCTImageViewManager.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ - (RCTPlatformView *)view // [macOS]
3030
return [[RCTImageView alloc] initWithBridge:self.bridge];
3131
}
3232

33+
#if TARGET_OS_OSX // [macOS
34+
// setting accessibilityElement on NSImageView has no effect, must be set on NSImageCell
35+
RCT_REMAP_VIEW_PROPERTY(accessible, reactAccessibilityElementCell.accessibilityElement, BOOL)
36+
#endif // macOS]
3337
RCT_EXPORT_VIEW_PROPERTY(blurRadius, CGFloat)
3438
RCT_EXPORT_VIEW_PROPERTY(capInsets, UIEdgeInsets)
3539
RCT_REMAP_VIEW_PROPERTY(defaultSource, defaultImage, UIImage)

packages/rn-tester/js/examples/Image/ImageExample.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {
2020
Image,
2121
ImageBackground,
2222
StyleSheet,
23+
Switch, // [macOS]
2324
Text,
2425
View,
2526
} = require('react-native');
@@ -625,6 +626,21 @@ class VectorDrawableExample extends React.Component<
625626
}
626627
}
627628

629+
// [macOS add switch to toggle the value of the accessible prop
630+
const AccessibilityExample = () => {
631+
const [isAccessible, setIsAccessible] = React.useState(true);
632+
return (
633+
<>
634+
<View style={styles.switch}>
635+
<Text>Set acccessible:</Text>
636+
<Switch value={isAccessible} onValueChange={setIsAccessible} />
637+
</View>
638+
<Image accessible={isAccessible} source={fullImage} style={styles.base} />
639+
</>
640+
);
641+
};
642+
// macOS]
643+
628644
const fullImage: ImageSource = {
629645
uri: IMAGE2,
630646
};
@@ -850,6 +866,12 @@ const styles = StyleSheet.create({
850866
experimental_boxShadow: '80px 0px 10px 0px hotpink',
851867
transform: 'rotate(-15deg)',
852868
},
869+
// [macOS
870+
switch: {
871+
flexDirection: 'row',
872+
alignItems: 'center',
873+
},
874+
// macOS]
853875
});
854876

855877
exports.displayName = (undefined: ?string);
@@ -1527,14 +1549,16 @@ exports.examples = [
15271549
);
15281550
},
15291551
},
1552+
// [macOS
15301553
{
15311554
title: 'Accessibility',
15321555
description:
1533-
('If the `accessible` (boolean) prop is set to True, the image will be indicated as an accessbility element.': string),
1556+
('If the `accessible` (boolean) prop is set to True, the image will be indicated as an accessbility element. If the `accessible` (boolean) prop is set to False, the image will not be indicated as an accessbility element.': string),
15341557
render: function (): React.Node {
1535-
return <Image accessible source={fullImage} style={styles.base} />;
1558+
return <AccessibilityExample />;
15361559
},
15371560
},
1561+
// macOS]
15381562
{
15391563
title: 'Accessibility Label',
15401564
description:

0 commit comments

Comments
 (0)