Add "Text Styles" TextInput Example

Summary:
This adds a series of examples for TextInput styles to screenshot test, specifically the ones which are projected to Android as spans. This will be used in refactoring to verify we do not change visual output.

Changelog:
[Internal][Added] - Add "Text Styles" TextInput Example

Reviewed By: cortinico

Differential Revision: D43158004

fbshipit-source-id: adaecf0e37941e66e280db282e2631a95b08b27a
This commit is contained in:
Nick Gerleman 2023-02-21 15:03:14 -08:00 коммит произвёл Facebook GitHub Bot
Родитель d147bbbe84
Коммит 817948e0aa
2 изменённых файлов: 258 добавлений и 12 удалений

Просмотреть файл

@ -18,6 +18,7 @@ import type {PressEvent} from 'react-native/Libraries/Types/CoreEventTypes';
type Props = $ReadOnly<{|
testID?: string,
textTestID?: string,
children?: React.Node,
onPress?: ?(event: PressEvent) => mixed,
|}>;
@ -30,7 +31,7 @@ class RNTesterButton extends React.Component<Props> {
onPress={this.props.onPress}
style={styles.button}
underlayColor="grey">
<Text>{this.props.children}</Text>
<Text testID={this.props.textTestID}>{this.props.children}</Text>
</TouchableHighlight>
);
}

Просмотреть файл

@ -10,17 +10,20 @@
'use strict';
const React = require('react');
const {
import * as React from 'react';
import {useContext, useState} from 'react';
import {
Button,
Platform,
Text,
TextInput,
View,
StyleSheet,
} = require('react-native');
} from 'react-native';
import type {TextStyle} from 'react-native/Libraries/StyleSheet/StyleSheet';
import RNTesterButton from '../../components/RNTesterButton';
import {RNTesterThemeContext} from '../../components/RNTesterTheme';
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
const styles = StyleSheet.create({
@ -49,9 +52,10 @@ const styles = StyleSheet.create({
},
label: {
width: 115,
alignItems: 'flex-end',
textAlign: 'right',
marginRight: 10,
paddingTop: 2,
fontSize: 12,
},
inputContainer: {
flex: 1,
@ -80,15 +84,20 @@ const styles = StyleSheet.create({
fontSize: 13,
padding: 4,
},
screenshotArea: {
position: 'absolute',
top: -5,
left: 120,
right: -5,
bottom: -5,
},
});
class WithLabel extends React.Component<$FlowFixMeProps> {
render(): React.Node {
return (
<View style={styles.labelContainer}>
<View style={styles.label}>
<Text>{this.props.label}</Text>
</View>
<Text style={styles.label}>{this.props.label}</Text>
<View style={styles.inputContainer}>{this.props.children}</View>
</View>
);
@ -592,6 +601,239 @@ function UncontrolledExample() {
);
}
const TextStylesExample = React.memo(() => {
const theme = useContext(RNTesterThemeContext);
return (
<TextStylesContainer
examples={[
{
name: 'backgroundColor',
textStyles: [
{backgroundColor: theme.SystemBackgroundColor},
{backgroundColor: 'red'},
{backgroundColor: 'orange'},
{backgroundColor: 'yellow'},
{backgroundColor: 'green'},
{backgroundColor: 'blue'},
],
},
{
name: 'color',
textStyles: [
{color: theme.LabelColor},
{color: 'red'},
{color: 'orange'},
{color: 'yellow'},
{color: 'green'},
{color: 'blue'},
],
},
{
name: 'fontFamily',
textStyles: [
{fontFamily: 'sans-serif'},
{fontFamily: 'serif'},
{fontFamily: 'monospace'},
],
},
{
name: 'fontSize',
textStyles: [
{fontSize: 8},
{fontSize: 10},
{fontSize: 12},
{fontSize: 14},
{fontSize: 16},
{fontSize: 18},
],
},
{
name: 'fontStyle',
textStyles: [{fontStyle: 'normal'}, {fontStyle: 'italic'}],
},
{
name: 'fontWeight',
textStyles: [
{fontWeight: 'normal'},
{fontWeight: 'bold'},
{fontWeight: '200'},
{fontWeight: '400'},
{fontWeight: '600'},
{fontWeight: '800'},
],
},
{
name: 'letterSpacing',
textStyles: [
{letterSpacing: 0},
{letterSpacing: 1},
{letterSpacing: 2},
{letterSpacing: 3},
{letterSpacing: 4},
{letterSpacing: 5},
],
},
{
name: 'lineHeight',
multiline: true,
textStyles: [
{lineHeight: 4},
{lineHeight: 8},
{lineHeight: 16},
{lineHeight: 24},
],
},
{
name: 'textDecorationLine',
textStyles: [
{textDecorationLine: 'none'},
{textDecorationLine: 'underline'},
{textDecorationLine: 'line-through'},
{textDecorationLine: 'underline line-through'},
],
},
{
name: 'textShadow',
textStyles: [
{
textShadowColor: 'black',
textShadowOffset: {width: 0, height: 0},
textShadowRadius: 0,
},
{
textShadowColor: 'black',
textShadowOffset: {width: 0, height: 0},
textShadowRadius: 5,
},
{
textShadowColor: 'red',
textShadowOffset: {width: 0, height: 0},
textShadowRadius: 5,
},
{
textShadowColor: 'blue',
textShadowOffset: {width: 0, height: -5},
textShadowRadius: 5,
},
{
textShadowColor: 'green',
textShadowOffset: {width: 0, height: 5},
textShadowRadius: 5,
},
{
textShadowColor: 'orange',
textShadowOffset: {width: 10, height: 0},
textShadowRadius: 5,
},
],
},
]}
/>
);
});
type TextStylesContainerProps = {
examples: $ReadOnlyArray<{
name: string,
textStyles: $ReadOnlyArray<TextStyle>,
multiline?: boolean,
}>,
};
function TextStylesContainer({examples}: TextStylesContainerProps) {
const [offset, setOffset] = useState(0);
const MAX_CYCLES = 6;
return (
<View>
<RNTesterButton
testID="cycle-styles"
textTestID="cycle-styles-label"
onPress={() => setOffset((offset + 1) % MAX_CYCLES)}>
Cycle {offset + 1}/{MAX_CYCLES}
</RNTesterButton>
<View>
<View testID="styles-screenshot-area" style={styles.screenshotArea} />
{examples.map(({name, multiline, textStyles}) => (
<WithLabel label={name} key={name}>
{multiline ? (
<MultilineStyledTextInput
name={name}
textStyles={textStyles}
styleOffset={offset}
/>
) : (
<StyledTextInput
name={name}
textStyles={textStyles}
styleOffset={offset}
/>
)}
</WithLabel>
))}
</View>
</View>
);
}
type StyledTextInputProps = {
name: string,
textStyles: $ReadOnlyArray<TextStyle>,
styleOffset: number,
};
function StyledTextInput({
name,
textStyles,
styleOffset,
}: StyledTextInputProps) {
return (
<TextInput
style={[
styles.default,
textStyles[(0 + styleOffset) % textStyles.length],
]}
testID={`style-${name}`}>
<Text>He</Text>
<Text style={textStyles[(1 + styleOffset) % textStyles.length]}>ll</Text>
<Text style={textStyles[(2 + styleOffset) % textStyles.length]}>
o,
<Text style={textStyles[(0 + styleOffset) % textStyles.length]}> </Text>
</Text>
<Text style={textStyles[(3 + styleOffset) % textStyles.length]}>Wo</Text>
<Text style={textStyles[(4 + styleOffset) % textStyles.length]}>rl</Text>
<Text style={textStyles[(5 + styleOffset) % textStyles.length]}>d!</Text>
</TextInput>
);
}
function MultilineStyledTextInput({
name,
textStyles,
styleOffset,
}: StyledTextInputProps) {
return (
<TextInput
multiline={true}
style={[
styles.default,
textStyles[(0 + styleOffset) % textStyles.length],
]}
testID={`style-${name}`}>
<Text>Hel{'\n'}</Text>
<Text style={textStyles[(1 + styleOffset) % textStyles.length]}>
lo {'\n'}
</Text>
<Text style={textStyles[(2 + styleOffset) % textStyles.length]}>
Wor{'\n'}
</Text>
<Text style={textStyles[(3 + styleOffset) % textStyles.length]}>ld!</Text>
</TextInput>
);
}
module.exports = ([
{
title: 'Auto-focus',
@ -867,8 +1109,11 @@ module.exports = ([
{
title: 'Uncontrolled component with layout changes',
name: 'uncontrolledComponent',
render: function (): React.Node {
return <UncontrolledExample />;
},
render: () => <UncontrolledExample />,
},
{
title: 'Text styles',
name: 'textStyles',
render: () => <TextStylesExample />,
},
]: Array<RNTesterModuleExample>);