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

Fixed alignItems: baseline for <Text> elements on Android #31575

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.facebook.yoga.YogaConstants;
import com.facebook.yoga.YogaDirection;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaBaselineFunction;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNode;
Expand Down Expand Up @@ -159,6 +160,20 @@ public long measure(
}
};

private final YogaBaselineFunction mTextBaselineFunction =
new YogaBaselineFunction() {
@Override
public float baseline(YogaNode node, float width, float height) {
Spannable text =
Assertions.assertNotNull(
mPreparedSpannableText,
"Spannable element has not been prepared in onBeforeLayout");

Layout layout = measureSpannedText(text, width, YogaMeasureMode.EXACTLY);
return layout.getLineBaseline(layout.getLineCount() - 1);
}
};

public ReactTextShadowNode() {
this(null);
}
Expand All @@ -171,6 +186,7 @@ public ReactTextShadowNode(@Nullable ReactTextViewManagerCallback reactTextViewM
private void initMeasureFunction() {
if (!isVirtual()) {
setMeasureFunction(mTextMeasureFunction);
setBaselineFunction(mTextBaselineFunction);
}
}

Expand Down
62 changes: 62 additions & 0 deletions packages/rn-tester/js/examples/Text/TextExample.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,62 @@ const styles = StyleSheet.create({
alignSelf: 'center',
},
});

class TextBaseLineLayoutExample extends React.Component<*, *> {
render() {
const texts = [];
for (let i = 9; i >= 0; i--) {
texts.push(
<Text key={i} style={{fontSize: 8 + i * 5, maxWidth: 20, backgroundColor: '#eee'}}>
{i}
</Text>,
);
}

const marker = (
<View style={{width: 20, height: 20, backgroundColor: 'gray'}} />
);
const subtitleStyle = {fontSize: 16, marginTop: 8, fontWeight: 'bold'};

return (
<View>
<Text style={subtitleStyle}>{'Nested <Text/>s:'}</Text>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
{marker}
<Text>{texts}</Text>
{marker}
</View>

<Text style={subtitleStyle}>{'Array of <Text/>s in <View>:'}</Text>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
{marker}
{texts}
{marker}
</View>

<Text style={subtitleStyle}>{'Interleaving <View> and <Text>:'}</Text>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
{marker}
<Text selectable={true}>
Some text.
<View
style={{
flexDirection: 'row',
alignItems: 'baseline',
backgroundColor: '#eee',
}}>
{marker}
<Text>Text inside View.</Text>
{marker}
</View>
</Text>
{marker}
</View>
</View>
);
}
}

exports.title = 'Text';
exports.documentationURL = 'https://reactnative.dev/docs/text';
exports.category = 'Basic';
Expand All @@ -889,4 +945,10 @@ exports.examples = [
return <TextExample />;
},
},
{
title: "Text `alignItems: 'baseline'` style",
render: function(): React.Node {
return <TextBaseLineLayoutExample />;
},
},
];