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:
Родитель
d147bbbe84
Коммит
817948e0aa
|
@ -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>);
|
||||
|
|
Загрузка…
Ссылка в новой задаче