Files
react-native/packages/rn-tester/js/examples/TextInput/TextInputExample.android.js
T
Rickard ZrinskiandFacebook GitHub Bot 97cf42f979 Fix maxFontSizeMultiplier prop on Text and TextInput components in new architecture (#47614)
Summary:
The `maxFontSizeMultiplier` prop for `Text` and `TextInput` was not handled in Fabric / New Architecture as documented in https://github.com/facebook/react-native/issues/47499.

bypass-github-export-checks

## Changelog:

[GENERAL] [FIXED] - Fix `maxFontSizeMultiplier` prop on `Text` and `TextInput` components in Fabric / New Architecture

Pull Request resolved: https://github.com/facebook/react-native/pull/47614

Test Plan:
I have not added any automated tests for this change but try to do so if requested. I have however added examples to RN Tester for both the Text and TextInput components, as well as compared the behaviour with Paper / Old Architecture. Both on version 0.76.

Noticed now I didn't do exactly the same steps in both videos, oops! Be aware that reapplying changes made in the Settings are currently half-broken on the new architecture, thus I'm restarting the app on Android and iOS. But this issue is unrelated to my changes. I've tested on main branch and it has the same issue.

Here are comparison videos between Paper and Fabric on iOS *after* I've made my fix.

### Text
| Paper  | Fabric |
| ------------- | ------------- |
| <video src="https://github.com/user-attachments/assets/f4fd009f-aa6d-41ab-92fa-8dcf1e351ba1" /> | <video src="https://github.com/user-attachments/assets/fda42cc6-34c2-42a7-a6e2-028e7c866075" /> |

### TextInput
| Paper  | Fabric |
| ------------- | ------------- |
| <video src="https://github.com/user-attachments/assets/59b59f7b-25d2-4b5b-a8e2-d2054cc6390b" /> | <video src="https://github.com/user-attachments/assets/72068566-8f2a-4463-874c-45a6f5b63b0d" /> |

Reviewed By: Abbondanzo

Differential Revision: D65953019

Pulled By: cipolleschi

fbshipit-source-id: 90c3c7e236229e9ad9bd346941fafe4af8a9d9fc
2025-01-29 09:27:44 -08:00

461 lines
12 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
*/
'use strict';
import type {
RNTesterModule,
RNTesterModuleExample,
} from '../../types/RNTesterTypes';
import ExampleTextInput from './ExampleTextInput';
import TextInputSharedExamples from './TextInputSharedExamples';
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
const ToggleDefaultPaddingExample = (): React.Node => {
const [hasPadding, setHasPadding] = React.useState(false);
return (
<View>
<ExampleTextInput style={hasPadding ? {padding: 0} : null} />
<Text onPress={() => setHasPadding(!hasPadding)}>Toggle padding</Text>
</View>
);
};
const styles = StyleSheet.create({
multiline: {
height: 60,
fontSize: 16,
},
singleLine: {
fontSize: 16,
},
singleLineWithHeightTextInput: {
height: 30,
},
wrappedText: {
maxWidth: 300,
},
});
const examples: Array<RNTesterModuleExample> = [
...TextInputSharedExamples,
{
title: 'Colors and text inputs',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
style={[styles.singleLine]}
defaultValue="Default color text"
/>
<ExampleTextInput
style={[styles.singleLine, {color: 'green'}]}
defaultValue="Green Text"
/>
<ExampleTextInput
placeholder="Default placeholder text color"
style={styles.singleLine}
/>
<ExampleTextInput
placeholder="Red placeholder text color"
placeholderTextColor="red"
style={styles.singleLine}
/>
<ExampleTextInput
placeholder="Default underline color"
style={styles.singleLine}
/>
<ExampleTextInput
placeholder="Blue underline color"
style={styles.singleLine}
underlineColorAndroid="blue"
/>
<ExampleTextInput
defaultValue="Same BackgroundColor as View "
style={[
styles.singleLine,
{backgroundColor: 'rgba(100, 100, 100, 0.3)'},
]}>
<Text style={{backgroundColor: 'rgba(100, 100, 100, 0.3)'}}>
Darker backgroundColor
</Text>
</ExampleTextInput>
<ExampleTextInput
defaultValue="Selection Color is red"
selectionColor={'red'}
style={styles.singleLine}
/>
<ExampleTextInput
defaultValue="Selection handles are red"
selectionHandleColor={'red'}
style={styles.singleLine}
/>
<ExampleTextInput
defaultValue="Cursor Color is red"
cursorColor={'red'}
style={styles.singleLine}
/>
</View>
);
},
},
{
title: 'Font Weight',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
defaultValue="Font Weight (default)"
style={[styles.singleLine]}
/>
{[
'normal',
'bold',
'900',
800,
'700',
'600',
'500',
'400',
'300',
'200',
'100',
].map(fontWeight => (
<ExampleTextInput
defaultValue={`Font Weight (${fontWeight})`}
key={fontWeight}
style={[styles.singleLine, {fontWeight}]}
/>
))}
</View>
);
},
},
{
title: 'Text input, themes and heights',
render: function (): React.Node {
return (
<ExampleTextInput
placeholder="If you set height, beware of padding set from themes"
style={[styles.singleLineWithHeightTextInput]}
/>
);
},
},
{
title: 'letterSpacing',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
style={[styles.singleLine, {letterSpacing: 0}]}
placeholder="letterSpacing = 0"
/>
<ExampleTextInput
style={[styles.singleLine, {letterSpacing: 2}]}
placeholder="letterSpacing = 2"
/>
<ExampleTextInput
style={[styles.singleLine, {letterSpacing: 9}]}
placeholder="letterSpacing = 9"
/>
<ExampleTextInput
style={[styles.singleLine, {letterSpacing: -1}]}
placeholder="letterSpacing = -1"
/>
</View>
);
},
},
{
title: 'Passwords',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
defaultValue="iloveturtles"
secureTextEntry={true}
style={styles.singleLine}
/>
<ExampleTextInput
secureTextEntry={true}
style={[styles.singleLine, {color: 'red'}]}
placeholder="color is supported too"
placeholderTextColor="red"
/>
</View>
);
},
},
{
title: 'Editable',
render: function (): React.Node {
return (
<ExampleTextInput
defaultValue="Can't touch this! (>'-')> ^(' - ')^ <('-'<) (>'-')> ^(' - ')^"
editable={false}
style={styles.singleLine}
/>
);
},
},
{
title: 'Multiline',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
autoCorrect={true}
placeholder="multiline, aligned top-left"
placeholderTextColor="red"
multiline={true}
style={[
styles.multiline,
{textAlign: 'left', textAlignVertical: 'top'},
]}
/>
<ExampleTextInput
autoCorrect={true}
placeholder="multiline, aligned center"
placeholderTextColor="green"
multiline={true}
style={[
styles.multiline,
{textAlign: 'center', textAlignVertical: 'center'},
]}
/>
<ExampleTextInput
autoCorrect={true}
multiline={true}
style={[
styles.multiline,
{color: 'blue'},
{textAlign: 'right', textAlignVertical: 'bottom'},
]}>
<Text style={styles.multiline}>
multiline with children, aligned bottom-right
</Text>
</ExampleTextInput>
</View>
);
},
},
{
title: 'Editable and Read only',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
placeholder="editable text input using editable prop"
editable
/>
<ExampleTextInput
placeholder="uneditable text input using editable prop"
editable={false}
/>
<ExampleTextInput
placeholder="editable text input using readOnly prop"
readOnly={false}
/>
<ExampleTextInput
placeholder="uneditable text input using readOnly prop"
readOnly
/>
</View>
);
},
},
{
title: 'Fixed number of lines',
platform: 'android',
render: function (): React.Node {
return (
<View style={styles.wrappedText}>
<ExampleTextInput
numberOfLines={2}
multiline={true}
placeholder="Two line input using numberOfLines prop"
/>
<ExampleTextInput
numberOfLines={5}
multiline={true}
placeholder="Five line input using numberOfLines prop"
/>
<ExampleTextInput
rows={2}
multiline={true}
placeholder="Two line input using rows prop"
/>
<ExampleTextInput
rows={5}
multiline={true}
placeholder="Five line input using rows prop"
/>
</View>
);
},
},
{
title: 'allowFontScaling attribute',
render: function (): React.Node {
return (
<View>
<Text>
By default, text will respect Text Size accessibility setting on
Android. It means that all font sizes will be increased or decreased
depending on the value of the Text Size setting in the OS's Settings
app.
</Text>
<ExampleTextInput
placeholder="allowFontScaling = false"
allowFontScaling={false}
/>
<ExampleTextInput
style={{marginTop: 10}}
placeholder="allowFontScaling = false"
allowFontScaling={true}
/>
</View>
);
},
},
{
title: 'maxFontSizeMultiplier attribute',
name: 'maxFontSizeMultiplier',
render(): React.Node {
return (
<View testID={'max-font-size-multiplier'}>
<Text>
When allowFontScaling is enabled, you can use the
maxFontSizeMultiplier prop to set an upper limit on how much the
font size will be scaled.
</Text>
<ExampleTextInput
allowFontScaling={true}
maxFontSizeMultiplier={1}
placeholder="This text will not scale up (max 1x)"
style={{marginTop: 10}}
testID={'non-scalable-text-input'}
/>
<ExampleTextInput
allowFontScaling={true}
maxFontSizeMultiplier={1.5}
placeholder="This text will scale up (max 1.5x)"
style={{marginTop: 10}}
testID={'scalable-text-input'}
/>
</View>
);
},
},
{
title: 'Text Auto Complete',
render: function (): React.Node {
return (
<View>
<ExampleTextInput autoComplete="country" placeholder="country" />
<ExampleTextInput
autoComplete="postal-address-country"
placeholder="postal-address-country"
/>
<ExampleTextInput
autoComplete="one-time-code"
placeholder="one-time-code"
/>
<ExampleTextInput autoComplete="sms-otp" placeholder="sms-otp" />
</View>
);
},
},
{
title: 'Return key',
render: function (): React.Node {
const returnKeyTypes = [
'none',
'go',
'search',
'send',
'done',
'previous',
'next',
];
const returnKeyLabels = ['Compile', 'React Native'];
const returnKeyExamples = returnKeyTypes.map(type => {
return (
<ExampleTextInput
key={type}
returnKeyType={type}
placeholder={'returnKeyType: ' + type}
style={styles.singleLine}
/>
);
});
const types = returnKeyLabels.map(type => {
return (
<ExampleTextInput
key={type}
returnKeyLabel={type}
placeholder={'returnKeyLabel: ' + type}
style={styles.singleLine}
/>
);
});
return (
<View>
{returnKeyExamples}
{types}
</View>
);
},
},
{
title: 'Inline Images',
render: function (): React.Node {
return (
<View>
<ExampleTextInput
inlineImageLeft="ic_menu_black_24dp"
placeholder="This has drawableLeft set"
style={styles.singleLine}
/>
<ExampleTextInput
inlineImageLeft="ic_menu_black_24dp"
inlineImagePadding={30}
placeholder="This has drawableLeft and drawablePadding set"
style={styles.singleLine}
/>
<ExampleTextInput
placeholder="This does not have drawable props set"
style={styles.singleLine}
/>
</View>
);
},
},
{
title: 'Toggle Default Padding',
render: function (): React.Node {
return <ToggleDefaultPaddingExample />;
},
},
];
module.exports = ({
displayName: (undefined: ?string),
title: 'TextInput',
documentationURL: 'https://reactnative.dev/docs/textinput',
category: 'Basic',
description: 'Single and multi-line text inputs.',
examples,
}: RNTesterModule);