react-native: [Android] textAlignVertical doesn't work on nested text
This issue has already been reported (#18790), but closed for “stalling”. As of React Native 0.63.3, the bug still exists.
Description
textAlignVertical
works fine when set on the top-most Text component. However, if you have any nested texts (a common use case), you can not override the alignVertical in the child Text component.
React Native version:
System: OS: Linux 5.4 Manjaro Linux CPU: (8) x64 Intel® Core™ i7-8809G CPU @ 3.10GHz Memory: 1.54 GB / 31.29 GB Shell: 5.8 - /bin/zsh Binaries: Node: 14.15.0 - /tmp/xfs-2fbb69bb/node Yarn: 2.2.2 - /tmp/xfs-2fbb69bb/yarn npm: 6.14.8 - /usr/bin/npm Watchman: 4.9.0 - /usr/bin/watchman SDKs: Android SDK: API Levels: 28, 29 Build Tools: 28.0.3, 29.0.0, 29.0.2, 29.0.3, 30.0.0, 30.0.1 System Images: android-22 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom Android NDK: Not Found IDEs: Android Studio: 4.1 AI-201.8743.12.41.6858069 Languages: Java: 1.8.0_265 - /usr/bin/javac Python: 3.8.6 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.13.1 => 16.13.1 react-native: ^0.63.3 => 0.63.3 npmGlobalPackages: react-native: Not Found
Steps To Reproduce
Create an app which renders the following component:
export default function App() {
return (
<Text>
<Text>This is text</Text>
<Text style={{textAlignVertical: 'top', fontSize: 10}}>sup!</Text>
</Text>
);
}
Expected Results
The “sup!” Text node should be aligned to the top edge of the line. Instead, “sup!” is aligned with the baseline:
Web (expected)
Android
Snack, code example, screenshot, or link to a repository:
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 18
- Comments: 25 (16 by maintainers)
Commits related to this issue
- Making links independently focusable by Talkback (#33215) Summary: This issue fixes [32004][23]. The Pull Request was previously published by [blavalla][10] with [31757][24]. >This is a follow-up on ... — committed to facebook/react-native by fabOnReact 2 years ago
- importantForAccessibility="no" does not allow screenreader focus on nested Text Components with accessibilityRole="link" or inline Images https://github.com/facebook/react-native/issues/30850#issueco... — committed to fabOnReact/react-native-website by fabOnReact 2 years ago
- Making links independently focusable by Talkback (#33215) Summary: This issue fixes [32004][23]. The Pull Request was previously published by [blavalla][10] with [31757][24]. >This is a follow-up on ... — committed to Saadnajmi/react-native-macos by fabOnReact 2 years ago
@fabriziobertoglio1987 Awesome! Thanks for your research. Looking forwards to your PR 🙂
@fabriziobertoglio1987 Any updates?
@fabriziobertoglio1987 That is promising! Although it would be more like super / sub support rather than a fix for this peculiar issue. But a very exciting new feature! Below just a recap on the distinction between super and top.
In CSS, top, bottom are quite different than sub and sup:
What that basically mean is that, if you have a sibling which expands the line box such as a big image,
top
would put the content aligned with the top of the image (which coincide with the line box) whilesuper
would only shift the content a little bit up from the baseline.See this JSFiddle
But honestly, I have no idea what are the specs of React Native inline layout! There certainly are models for native platforms.
Hello,
Thanks for the issue. I have been contributing to facebook/react-native for 4 years and specialize in the Text/TextInput components. I currently have 58 facebook/react-native PRs:
https://github.com/facebook/react-native/pulls?q=is%3Apr+author%3Afabriziobertoglio1987+
This is the suggested approach from the react-native core team (see this discussion):
I’m publishing several fixes for Text and TextInput component in a separate library react-native-improved.
The advantages would be:
What do you think about this? Should I keep working on this? Thanks
Still an issue
I was able to prepare a fix for this issue, the problem is that I don’t know how to pass the prop. The prop
textAlignVertical: 'super'
needs to be passed to thespan
(the nested/child<Text>sup!</Text>
) and not the parent androidTextView
(the parent react<Text>This is text</Text>
).The class that handle
TextView
attributes isReactTextAnchorViewManager
which for example applies the propTEXT_ALIGN_VERTICAL
and changes the alignment of the parentText
.https://github.com/facebook/react-native/blob/cf0a6e9e2734a5927b9dc08303c22477ad274150/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java#L72
while the second child/nexted text
<Text>This is text<Text>sup!</Text></Text>
is just part of the originalTextView
, but it is styled differently using an androidSuperscriptSpan
insted of for example CustomLetterSpacingSpanhttps://github.com/facebook/react-native/blob/cf0a6e9e2734a5927b9dc08303c22477ad274150/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L176-L180
This properties are applied by the ReactBaseTextShadowNode and are taked from the textAttributes properties listed below
https://github.com/facebook/react-native/blob/cf0a6e9e2734a5927b9dc08303c22477ad274150/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L323-L330
I still did not find the logic that adds this properties to the ReactBaseTextShadowNode, but I imagine may be in the ReactTextViewAnchorManager
I will have to further investigate were to add this property, probably I will have to investigate how the style properties are used to add the spans. Thanks a lot for the patience in adding this feature 🙏
@jsamr thanks a lot Jules Randolph for the sponsorship. I will give priority to this issue and publish a pull request. 🙏 ☮️ ❤️
each one of the below code-snippets adds a different text property to the
<image src="https://user-images.githubusercontent.com/24992535/108502357-f845c800-72b2-11eb-9b88-2f82226540a5.png" height="50" />Text
sup!
using the Android Spans API. Hopefully I will be able to use AlignmentSpan to add the required functionality…CLICK TO OPEN CODE SNIPPETS
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L174
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L178-L179
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L186
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L193
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L199-L207
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L210
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L213
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L220-L227
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L233
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L235
unluckily @hoda-oz is right
I have been reading https://github.com/facebook/react-native/pull/23195/files and https://github.com/facebook/react-native/pull/8619/files to understand how nested
<image src="https://user-images.githubusercontent.com/24992535/108385384-e6f5b080-720b-11eb-8e4e-513a3446a9aa.png" width="1000" />Text
are combined in oneTextView
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L42-L47
The code below loops the different text and probably is responsible for aggregating them in 1 TextView.
<image src="https://user-images.githubusercontent.com/24992535/108392715-45725d00-7213-11eb-9cab-d8b5e3cc5f7d.png" height="50" />https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L111-L112
each one of the below code-snippets adds a different text property to the
<image src="https://user-images.githubusercontent.com/24992535/108502357-f845c800-72b2-11eb-9b88-2f82226540a5.png" height="50" />Text
sup!
using the Android Spans API. Hopefully I will be able to use AlignmentSpan to add the required functionality…More code references
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L174
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L178-L179
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L186
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L193
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L199-L207
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L210
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L213
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L220-L227
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L233
https://github.com/facebook/react-native/blob/28fb41a0ab48cc01d606b64744c84e2ac3805f3f/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java#L235