Reviewed By: sahrens

Differential Revision: D5929933

fbshipit-source-id: 16ef86c4ab444f740b2568ddb3af0ffd5ff0d02b
This commit is contained in:
Ramanpreet Nara 2017-10-18 19:30:02 -07:00 коммит произвёл Facebook Github Bot
Родитель 1a7abcf526
Коммит bc5083ac40
1 изменённых файлов: 342 добавлений и 68 удалений

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

@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
* *
* @flow * @flow
* @format
* @providesModule RTLExample * @providesModule RTLExample
*/ */
'use strict'; 'use strict';
@ -26,10 +27,10 @@ const {
TouchableWithoutFeedback, TouchableWithoutFeedback,
Switch, Switch,
View, View,
Button,
} = ReactNative; } = ReactNative;
const Platform = require('Platform'); const Platform = require('Platform');
const RNTesterPage = require('./RNTesterPage'); const RNTesterPage = require('./RNTesterPage');
const RNTesterBlock = require('./RNTesterBlock'); const RNTesterBlock = require('./RNTesterBlock');
@ -48,57 +49,46 @@ const IMAGE_SIZE = [IMAGE_DIMENSION, IMAGE_DIMENSION];
const IS_RTL = I18nManager.isRTL; const IS_RTL = I18nManager.isRTL;
function ListItem(props) { function ListItem(props) {
return ( return (
<View style={styles.row}> <View style={styles.row}>
<View style={styles.column1}> <View style={styles.column1}>
<Image <Image source={props.imageSource} style={styles.icon} />
source={props.imageSource} </View>
style={styles.icon} <View style={styles.column2}>
/> <View style={styles.textBox}>
</View> <Text>Text Text Text</Text>
<View style={styles.column2}> </View>
<View style={styles.textBox}> </View>
<Text> <View style={styles.column3}>
Text <View style={styles.smallButton}>
Text <Text style={styles.fontSizeSmall}>Button</Text>
Text </View>
</Text> </View>
</View> </View>
</View> );
<View style={styles.column3}>
<View style={styles.smallButton}>
<Text style={styles.fontSizeSmall}>
Button
</Text>
</View>
</View>
</View>
);
} }
function TextAlignmentExample(props) { function TextAlignmentExample(props) {
return ( return (
<RNTesterBlock <RNTesterBlock title={props.title} description={props.description}>
title={props.title} <View>
description={props.description}> <Text style={props.style}>
<View> Left-to-Right language without text alignment.
<Text style={props.style}> </Text>
Left-to-Right language without text alignment. <Text style={props.style}>
</Text> {'\u0645\u0646 \u0627\u0644\u064A\u0645\u064A\u0646 ' +
<Text style={props.style}> '\u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631 ' +
{'\u0645\u0646 \u0627\u0644\u064A\u0645\u064A\u0646 ' + '\u0627\u0644\u0644\u063A\u0629 \u062F\u0648\u0646 ' +
'\u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631 ' + '\u0645\u062D\u0627\u0630\u0627\u0629 \u0627\u0644\u0646\u0635'}
'\u0627\u0644\u0644\u063A\u0629 \u062F\u0648\u0646 ' + </Text>
'\u0645\u062D\u0627\u0630\u0627\u0629 \u0627\u0644\u0646\u0635'} <Text style={props.style}>
</Text> {'\u05DE\u05D9\u05DE\u05D9\u05DF \u05DC\u05E9\u05DE\u05D0\u05DC ' +
<Text style={props.style}> '\u05D4\u05E9\u05E4\u05D4 \u05D1\u05DC\u05D9 ' +
{'\u05DE\u05D9\u05DE\u05D9\u05DF \u05DC\u05E9\u05DE\u05D0\u05DC ' + '\u05D9\u05D9\u05E9\u05D5\u05E8 \u05D8\u05E7\u05E1\u05D8'}
'\u05D4\u05E9\u05E4\u05D4 \u05D1\u05DC\u05D9 ' + </Text>
'\u05D9\u05D9\u05E9\u05D5\u05E8 \u05D8\u05E7\u05E1\u05D8'} </View>
</Text> </RNTesterBlock>
</View> );
</RNTesterBlock>
);
} }
function AnimationBlock(props) { function AnimationBlock(props) {
@ -114,6 +104,276 @@ function AnimationBlock(props) {
); );
} }
type RTLSwitcherComponentState = {|
isRTL: boolean,
|};
function withRTLState(Component) {
return class extends React.Component<*, RTLSwitcherComponentState> {
constructor(...args) {
super(...args);
this.state = {
isRTL: IS_RTL,
};
}
render() {
const setRTL = isRTL => this.setState({isRTL: isRTL});
return <Component isRTL={this.state.isRTL} setRTL={setRTL} />;
}
};
}
const RTLToggler = ({isRTL, setRTL}) => {
if (Platform.OS === 'android') {
return <Text style={styles.rtlToggler}>{isRTL ? 'RTL' : 'LTR'}</Text>;
}
const toggleRTL = () => setRTL(!isRTL);
return (
<Button
onPress={toggleRTL}
title={isRTL ? 'RTL' : 'LTR'}
color="gray"
accessibilityLabel="Change layout direction"
/>
);
};
const PaddingExample = withRTLState(({isRTL, setRTL}) => {
const color = 'teal';
return (
<RNTesterBlock title={'Padding Start/End'}>
<Text style={styles.bold}>Styles</Text>
<Text>paddingStart: 50,</Text>
<Text>paddingEnd: 10</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<Text>The {color} is padding.</Text>
<View
style={{
backgroundColor: color,
paddingStart: 50,
paddingEnd: 10,
borderWidth: 1,
borderColor: color,
direction: isRTL ? 'rtl' : 'ltr',
}}>
<View
style={{
backgroundColor: 'white',
paddingTop: 5,
paddingBottom: 5,
borderLeftWidth: 1,
borderRightWidth: 1,
borderColor: 'gray',
}}>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</RNTesterBlock>
);
});
const MarginExample = withRTLState(({isRTL, setRTL}) => {
return (
<RNTesterBlock title={'Margin Start/End'}>
<Text style={styles.bold}>Styles</Text>
<Text>marginStart: 50,</Text>
<Text>marginEnd: 10</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<Text>The green is margin.</Text>
<View
style={{
backgroundColor: 'green',
borderWidth: 1,
borderColor: 'green',
direction: isRTL ? 'rtl' : 'ltr',
}}>
<View
style={{
backgroundColor: 'white',
paddingTop: 5,
paddingBottom: 5,
marginStart: 50,
marginEnd: 10,
borderLeftWidth: 1,
borderRightWidth: 1,
borderColor: 'gray',
}}>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</RNTesterBlock>
);
});
const PositionExample = withRTLState(({isRTL, setRTL}) => {
return (
<RNTesterBlock title={'Position Start/End'}>
<Text style={styles.bold}>Styles</Text>
<Text>start: 50</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<Text>The orange is position.</Text>
<View
style={{
backgroundColor: 'orange',
borderWidth: 1,
borderColor: 'orange',
direction: isRTL ? 'rtl' : 'ltr',
}}>
<View
style={{
backgroundColor: 'white',
start: 50,
borderColor: 'gray',
}}>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
<Text />
<Text style={styles.bold}>Styles</Text>
<Text>end: 50</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<Text>The orange is position.</Text>
<View
style={{
backgroundColor: 'orange',
borderWidth: 1,
borderColor: 'orange',
direction: isRTL ? 'rtl' : 'ltr',
}}>
<View
style={{
backgroundColor: 'white',
end: 50,
borderColor: 'gray',
}}>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</RNTesterBlock>
);
});
const BorderWidthExample = withRTLState(({isRTL, setRTL}) => {
return (
<RNTesterBlock title={'Border Width Start/End'}>
<Text style={styles.bold}>Styles</Text>
<Text>borderStartWidth: 10,</Text>
<Text>borderEndWidth: 50</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<View style={{direction: isRTL ? 'rtl' : 'ltr'}}>
<View
style={{
borderStartWidth: 10,
borderEndWidth: 50,
}}>
<View>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</View>
</RNTesterBlock>
);
});
const BorderColorExample = withRTLState(({isRTL, setRTL}) => {
return (
<RNTesterBlock title={'Border Color Start/End'}>
<Text style={styles.bold}>Styles</Text>
<Text>borderStartColor: 'red',</Text>
<Text>borderEndColor: 'green',</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<View style={{direction: isRTL ? 'rtl' : 'ltr'}}>
<View
style={{
borderStartColor: 'red',
borderEndColor: 'green',
borderLeftWidth: 20,
borderRightWidth: 20,
padding: 10,
}}>
<View>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</View>
</RNTesterBlock>
);
});
const BorderRadiiExample = withRTLState(({isRTL, setRTL}) => {
return (
<RNTesterBlock title={'Border Radii Start/End'}>
<Text style={styles.bold}>Styles</Text>
<Text>borderTopStartRadius: 10,</Text>
<Text>borderTopEndRadius: 20,</Text>
<Text>borderBottomStartRadius: 30,</Text>
<Text>borderBottomEndRadius: 40</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<View style={{direction: isRTL ? 'rtl' : 'ltr'}}>
<View
style={{
borderWidth: 10,
borderTopStartRadius: 10,
borderTopEndRadius: 20,
borderBottomStartRadius: 30,
borderBottomEndRadius: 40,
padding: 10,
}}>
<View>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</View>
</RNTesterBlock>
);
});
const BorderExample = withRTLState(({isRTL, setRTL}) => {
return (
<RNTesterBlock title={'Border '}>
<Text style={styles.bold}>Styles</Text>
<Text>borderStartColor: 'red',</Text>
<Text>borderEndColor: 'green',</Text>
<Text>borderStartWidth: 10,</Text>
<Text>borderEndWidth: 50,</Text>
<Text>borderTopStartRadius: 10,</Text>
<Text>borderTopEndRadius: 20,</Text>
<Text>borderBottomStartRadius: 30,</Text>
<Text>borderBottomEndRadius: 40</Text>
<Text />
<Text style={styles.bold}>Demo: </Text>
<View style={{direction: isRTL ? 'rtl' : 'ltr'}}>
<View
style={{
borderStartColor: 'red',
borderEndColor: 'green',
borderStartWidth: 10,
borderEndWidth: 50,
borderTopStartRadius: 10,
borderTopEndRadius: 20,
borderBottomStartRadius: 30,
borderBottomEndRadius: 40,
padding: 10,
}}>
<View>
<RTLToggler setRTL={setRTL} isRTL={isRTL} />
</View>
</View>
</View>
</RNTesterBlock>
);
});
class RTLExample extends React.Component<any, State> { class RTLExample extends React.Component<any, State> {
static title = 'RTLExample'; static title = 'RTLExample';
static description = 'Examples to show how to apply components to RTL layout.'; static description = 'Examples to show how to apply components to RTL layout.';
@ -127,9 +387,7 @@ class RTLExample extends React.Component<any, State> {
this._panResponder = PanResponder.create({ this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true, onStartShouldSetPanResponder: () => true,
onPanResponderGrant: this._onPanResponderGrant, onPanResponderGrant: this._onPanResponderGrant,
onPanResponderMove: Animated.event([ onPanResponderMove: Animated.event([null, {dx: pan.x, dy: pan.y}]),
null, {dx: pan.x, dy: pan.y},
]),
onPanResponderRelease: this._onPanResponderEnd, onPanResponderRelease: this._onPanResponderEnd,
onPanResponderTerminate: this._onPanResponderEnd, onPanResponderTerminate: this._onPanResponderEnd,
}); });
@ -149,9 +407,9 @@ class RTLExample extends React.Component<any, State> {
style={[ style={[
styles.container, styles.container,
// `direction` property is supported only on iOS now. // `direction` property is supported only on iOS now.
Platform.OS === 'ios' ? Platform.OS === 'ios'
{direction: this.state.isRTL ? 'rtl' : 'ltr'} : ? {direction: this.state.isRTL ? 'rtl' : 'ltr'}
null : null,
]} ]}
onLayout={this._onLayout}> onLayout={this._onLayout}>
<RNTesterPage title={'Right-to-Left (RTL) UI Layout'}> <RNTesterPage title={'Right-to-Left (RTL) UI Layout'}>
@ -164,21 +422,20 @@ class RTLExample extends React.Component<any, State> {
</RNTesterBlock> </RNTesterBlock>
<RNTesterBlock title={'Quickly Test RTL Layout'}> <RNTesterBlock title={'Quickly Test RTL Layout'}>
<View style={styles.flexDirectionRow}> <View style={styles.flexDirectionRow}>
<Text style={styles.switchRowTextView}> <Text style={styles.switchRowTextView}>forceRTL</Text>
forceRTL
</Text>
<View style={styles.switchRowSwitchView}> <View style={styles.switchRowSwitchView}>
<Switch <Switch
onValueChange={this._onDirectionChange} onValueChange={this._onDirectionChange}
style={styles.rightAlignStyle} style={styles.rightAlignStyle}
value={this.state.isRTL} /> value={this.state.isRTL}
/>
</View> </View>
</View> </View>
</RNTesterBlock> </RNTesterBlock>
<RNTesterBlock title={'A Simple List Item Layout'}> <RNTesterBlock title={'A Simple List Item Layout'}>
<View style={styles.list}> <View style={styles.list}>
<ListItem imageSource={require('./Thumbnails/like.png')}/> <ListItem imageSource={require('./Thumbnails/like.png')} />
<ListItem imageSource={require('./Thumbnails/poke.png')}/> <ListItem imageSource={require('./Thumbnails/poke.png')} />
</View> </View>
</RNTesterBlock> </RNTesterBlock>
<TextAlignmentExample <TextAlignmentExample
@ -236,12 +493,19 @@ class RTLExample extends React.Component<any, State> {
imgStyle={{ imgStyle={{
transform: [ transform: [
{translateX: this.state.linear}, {translateX: this.state.linear},
{scaleX: IS_RTL ? -1 : 1} {scaleX: IS_RTL ? -1 : 1},
] ],
}} }}
/> />
</View> </View>
</RNTesterBlock> </RNTesterBlock>
<PaddingExample />
<MarginExample />
<PositionExample />
<BorderWidthExample />
<BorderColorExample />
<BorderRadiiExample />
<BorderExample />
</RNTesterPage> </RNTesterPage>
</ScrollView> </ScrollView>
); );
@ -256,10 +520,11 @@ class RTLExample extends React.Component<any, State> {
_onDirectionChange = () => { _onDirectionChange = () => {
I18nManager.forceRTL(!this.state.isRTL); I18nManager.forceRTL(!this.state.isRTL);
this.setState({isRTL: !this.state.isRTL}); this.setState({isRTL: !this.state.isRTL});
Alert.alert('Reload this page', Alert.alert(
'Please reload this page to change the UI direction! ' + 'Reload this page',
'All examples in this app will be affected. ' + 'Please reload this page to change the UI direction! ' +
'Check them out to see what they look like in RTL layout.' 'All examples in this app will be affected. ' +
'Check them out to see what they look like in RTL layout.',
); );
}; };
@ -272,7 +537,7 @@ class RTLExample extends React.Component<any, State> {
}); });
const offset = IMAGE_SIZE[0] / SCALE / 2 + 10; const offset = IMAGE_SIZE[0] / SCALE / 2 + 10;
const toMaxDistance = const toMaxDistance =
(IS_RTL ? -1 : 1) * (this.state.windowWidth / 2 - offset); (IS_RTL ? -1 : 1) * (this.state.windowWidth / 2 - offset);
Animated.timing(this.state.linear, { Animated.timing(this.state.linear, {
toValue: this.state.toggleStatus[refName] ? toMaxDistance : 0, toValue: this.state.toggleStatus[refName] ? toMaxDistance : 0,
duration: 2000, duration: 2000,
@ -387,10 +652,10 @@ const styles = StyleSheet.create({
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
}, },
fontSizeSmall:{ fontSizeSmall: {
fontSize: 10, fontSize: 10,
}, },
fontSizeExtraSmall:{ fontSizeExtraSmall: {
fontSize: 8, fontSize: 8,
}, },
textAlignLeft: { textAlignLeft: {
@ -405,6 +670,15 @@ const styles = StyleSheet.create({
flexDirectionRow: { flexDirectionRow: {
flexDirection: 'row', flexDirection: 'row',
}, },
bold: {
fontWeight: 'bold',
},
rtlToggler: {
color: 'gray',
padding: 8,
textAlign: 'center',
fontWeight: '500',
},
}); });
module.exports = RTLExample; module.exports = RTLExample;