Accessibility on react native nested text components - react-native

From what I understand to create links in inline text the solution is too use nested text components like so (ps i know that using click me as a link is bad style I'm just trying to highlight the main issue)
<Text>
To find out more
<Text onClick={() => console.log('link was pressed')} accessibilityRole="button">
Click me
</Text>
</Text>
The onClick works but the accessibilityRole does not appear to work.

Related

Accessibility for Nested Text in react native

I am trying to implement Accessibility for react native application. I have 2 nested Text Tags, If I enable the accessibility for all Text Tags, It is highlighting the first Text Tag.
I enabled in all 2 Text tags, but only first Text tag is visible for Accessibility
<Text accessible={true} accessibilityLabel={'Hello'} >Hello
<Text accessible={true} accessibilityLabel={'Stack Devs!'}>Stack Devs!
</Text>
</Text>
I need to make the second Text accessible. As of now only first Text is accessible
I had same problem recently. Only proper way to do it on RN, is to have the whole string in one property:
<Text accessible={true} accessibilityLabel={'Hello Stack Devs!'}>
{'Hello'}
<Text>{'Stack Devs!'}</Text>
</Text>

Nesting View components inside Text components not working react-native 0.60-RC

I am using react-native v0.60.0 RC 0 and on the github release it says the following:
"Enable views to be nested within Text component"
The above does not work for me. The text inside the nested View is not showing up.
My code:
<Text>
<View>
<Text>Hello world!</Text>
</View>
</Text>
This doesn't show anything on screen.

How to define a click area on a button with react native?

I'm currently developing an app using react native and I'm using react-navigation to navigate between screens, using buttons in my header (back arrow for example).
It's working well, however even if my icon is the right size it seems like the click area is really narrow and I struggle with it.
Do you know how I could define a click zone on my button for it to be clicked easier? I've tried the hitslop prop but it's not working for me (maybe it's been deprecated?).
Here is my button:
var backArrow =
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Ionicons name="ios-arrow-back" size={22} color="#ff8c00" />
</TouchableOpacity>
I'm using Expo and testing on an iPhone 6s Plus.
Wrapping the Ionicons in a TouchableOpacity will only provide a clickable area as large as the Ionicons component. You can increase the size of the clickable area with the following structure:
<TouchableOpacity>
<View>
<Ionicons />
</View>
</TouchableOpacity>
by styling the View to be as large as you require it.

Including markup for React Native Component Tags inside a Text Element

I've been trying to include code examples in a style guide for a React Native project and have had trouble finding a way to include the tags without React Native trying to render them itself.
I was hoping to simulate something sort of like Stackoverflow does with it's codeblocks like this:
// Example code for implementing custom button:
<CustomButton
color="primary"
title="Submit"
/>
So my code that breaks looks something like this:
<View>
<Text>
// Example code for implementing custom button:
<CustomButton
color="primary"
title="Submit"
/>
</Text>
</View>
Because React Native tries to render the Button and throws errors.
Is there something similar to HTML's <code> tag inside of React Native or some custom way of achieving the same functionality?
One way to make this work is storing the text as a string in some variable and just rendering that inside the container:
let codeBlock = "<CustButton \n\tcolor=\"primary\" \n\ttitle=\"Placeholder\" \n/>"
<View>
<Text>
// Example code for implementing custom button:
{codeBlock}
</Text>
</View>
with jsx-to-string, you can
<View>
<Text>
{jsxToString(
<CustomButton color="primary" title="Submit" />
)}
</Text>
</View>
This way you can reuse your jsx object easily instead of convert to string manually.

React Native Touchable is disabling ScrollView

I'm new to React Native, so am probably asking something very obvious, but please help.
I have a view wrapped in a touchable, so that the whole area responds to tapping. Then have a ScrollView nested inside the view. The overall structure is something like this:
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<Text>Hello, here is a very long text that needs scrolling.</Text>
<ScrollView>
</View>
</TouchableWithoutFeedback>
When this compiles and runs, the tapping is detected, but the scroll view doesn't scroll at all. I made the above code short and simple, but each component has the proper styling and I can see everything rendering fine and the long text is cutoff at the bottom of the ScrollView. Please help.
Thank you!
This is what worked for me:
<TouchableWithoutFeedback onPress={...}>
<View>
<ScrollView>
<View onStartShouldSetResponder={() => true}>
// Scrollable content
</View>
</ScrollView>
</View>
</TouchableWithoutFeedback>
The onStartShouldSetResponder prop stops the touch event propagation towards the TouchableWithoutFeedback element.
I'm using this structure it's working for me:
<TouchableWithoutFeedback onPress={() => {}}>
{other content}
<View onStartShouldSetResponder={() => true}>
<ScrollView>
{scrollable content}
</ScrollView>
</View>
</TouchableWithoutFeedback>
You can have a scrollView or FlatList inside a TouchableWithoutFeedback. Tho you shouldn't but some times you have no other choice to go. Taking a good look at this questions and answer validates that.
close react native modal by clicking on overlay,
how to dismiss modal by tapping screen in react native.
For the Question, The only way you can make it work (atleast that i know of), or the simplest way is to add a TouchableOpacity around Text in your code like this,
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<TouchableOpacity>
<Text>Hello, here is a very long text that needs scrolling.</Text>
</TouchableOpacity>
<ScrollView>
</View>
</TouchableWithoutFeedback>
Note: TouchableOpacity is a wrapper for making Views respond properly to touches so automatically you can style it the way you would have styled your View Component then set some of its special props to whatever you want e.g activeOpacity etc. Moreso you can use TouchableHighlight it works, but it receives one child element i.e you enclose all your component inside a parent one.
I'm using this structure it's working for me:
<TouchableOpacity>
{other content}
<ScrollView>
<TouchableOpacity activeOpacity={1}>
{scrollable content}
</TouchableOpacity>
</ScrollView>
I found that for my situation the other examples did not work as they disabled the ability to click or disabled the ability to scroll. I instead used:
<FlatList
data={[{key: text1 }, { key: text2 } ...]}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={this.onPressContent}>
<Text style={styles.text}>{item.key}</Text>
</TouchableWithoutFeedback>
)}
/>
I happend to need to multiple chunks but you could use single element in the data array for one piece of text.
This let the press event to fire as well as let the text scroll.
Trying to use a ScrollView component inside a TouchableWithoutFeedback component can cause some unexpected behavior because the TouchableWithoutFeedback component is designed to capture user gestures and trigger an action, but the ScrollView component is designed to allow users to scroll through content.Here is what the official docs say
Do not use unless you have a very good reason. All elements that
respond to press should have a visual feedback when touched.
TouchableWithoutFeedback supports only one child. If you wish to have
several child components, wrap them in a View. Importantly,
TouchableWithoutFeedback works by cloning its child and applying
responder props to it. It is therefore required that any intermediary
components pass through those props to the underlying React Native
component.
Thats write , you cannot have a scroll view inside the TouchableWithoutFeedback, it the property of react native that it will disable it, you can instead have your scroll view outside the TouchableWithoutFeedback tab and add the other contents that you want upon the click inside a view tag.
You can also use the Touchable Highlights instead, if the TouchableWithoutFeedback does not works.