diff --git a/RNTester/js/RTLExample.js b/RNTester/js/RTLExample.js
index 96fe2fc8a2ac24..a58b744709ab46 100644
--- a/RNTester/js/RTLExample.js
+++ b/RNTester/js/RTLExample.js
@@ -16,9 +16,7 @@ const {
Animated,
I18nManager,
Image,
- PanResponder,
PixelRatio,
- ScrollView,
StyleSheet,
Text,
TouchableWithoutFeedback,
@@ -28,14 +26,20 @@ const {
} = ReactNative;
const Platform = require('Platform');
-const RNTesterPage = require('./RNTesterPage');
-const RNTesterBlock = require('./RNTesterBlock');
-
type State = {
toggleStatus: any,
pan: Object,
linear: Object,
isRTL: boolean,
+};
+
+type RTLToggleState = {
+ isRTL: boolean,
+};
+
+type AnimationState = {
+ toggleStatus: any,
+ linear: Object,
windowWidth: number,
};
@@ -65,10 +69,11 @@ function ListItem(props) {
);
}
-function TextAlignmentExample(props) {
+const TextAlignmentExample = withRTLState(({isRTL, setRTL, ...props}) => {
return (
-
-
+
+
+
Left-to-Right language without text alignment.
@@ -84,9 +89,37 @@ function TextAlignmentExample(props) {
'\u05D9\u05D9\u05E9\u05D5\u05E8 \u05D8\u05E7\u05E1\u05D8'}
-
+
);
-}
+});
+
+const IconsExample = withRTLState(({isRTL, setRTL}) => {
+ return (
+
+
+
+
+
+
+ Without directional meaning
+
+
+
+
+
+ With directional meaning
+
+
+
+
+ );
+});
function AnimationBlock(props) {
return (
@@ -116,7 +149,9 @@ function withRTLState(Component) {
render() {
const setRTL = isRTL => this.setState({isRTL: isRTL});
- return ;
+ return (
+
+ );
}
};
}
@@ -137,11 +172,124 @@ const RTLToggler = ({isRTL, setRTL}) => {
);
};
+class RTLToggleExample extends React.Component {
+ constructor(props: Object) {
+ super(props);
+
+ this.state = {
+ isRTL: IS_RTL,
+ };
+ }
+
+ render() {
+ return (
+
+
+
+ {this.state.isRTL ? 'Right-to-Left' : 'Left-to-Right'}
+
+
+
+ forceRTL
+
+
+
+
+
+ );
+ }
+
+ _onDirectionChange = () => {
+ I18nManager.forceRTL(!this.state.isRTL);
+ this.setState({isRTL: !this.state.isRTL});
+ Alert.alert(
+ 'Reload this page',
+ 'Please reload this page to change the UI direction! ' +
+ 'All examples in this app will be affected. ' +
+ 'Check them out to see what they look like in RTL layout.',
+ );
+ };
+}
+
+const SimpleListItemExample = withRTLState(({isRTL, setRTL}) => {
+ return (
+
+
+
+
+
+
+
+ );
+});
+
+const AnimationContainer = withRTLState(({isRTL, setRTL}) => {
+ return ;
+});
+
+class AnimationExample extends React.Component {
+ constructor(props: Object) {
+ super(props);
+
+ this.state = {
+ toggleStatus: {},
+ linear: new Animated.Value(0),
+ windowWidth: 0,
+ };
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+ );
+ }
+
+ _onLayout = (e: Object) => {
+ this.setState({
+ windowWidth: e.nativeEvent.layout.width,
+ });
+ };
+
+ _linearTap = (e: Object) => {
+ this.setState({
+ toggleStatus: {
+ ...this.state.toggleStatus,
+ [e]: !this.state.toggleStatus[e],
+ },
+ });
+ const offset = IMAGE_SIZE[0] / SCALE / 2 + 10;
+ const toMaxDistance =
+ (this.props.isRTL ? -1 : 1) * (this.state.windowWidth / 2 - offset);
+ Animated.timing(this.state.linear, {
+ toValue: this.state.toggleStatus[e] ? toMaxDistance : 0,
+ duration: 2000,
+ useNativeDriver: true,
+ }).start();
+ };
+}
+
const PaddingExample = withRTLState(({isRTL, setRTL}) => {
const color = 'teal';
return (
-
+
Styles
paddingStart: 50,
paddingEnd: 10
@@ -169,13 +317,13 @@ const PaddingExample = withRTLState(({isRTL, setRTL}) => {
-
+
);
});
const MarginExample = withRTLState(({isRTL, setRTL}) => {
return (
-
+
Styles
marginStart: 50,
marginEnd: 10
@@ -203,13 +351,13 @@ const MarginExample = withRTLState(({isRTL, setRTL}) => {
-
+
);
});
const PositionExample = withRTLState(({isRTL, setRTL}) => {
return (
-
+
Styles
start: 50
@@ -253,19 +401,19 @@ const PositionExample = withRTLState(({isRTL, setRTL}) => {
-
+
);
});
const BorderWidthExample = withRTLState(({isRTL, setRTL}) => {
return (
-
+
Styles
borderStartWidth: 10,
borderEndWidth: 50
Demo:
-
+
{
-
+
);
});
const BorderColorExample = withRTLState(({isRTL, setRTL}) => {
return (
-
+
Styles
borderStartColor: 'red',
borderEndColor: 'green',
Demo:
-
+
{
-
+
);
});
const BorderRadiiExample = withRTLState(({isRTL, setRTL}) => {
return (
-
+
Styles
borderTopStartRadius: 10,
borderTopEndRadius: 20,
@@ -316,7 +464,7 @@ const BorderRadiiExample = withRTLState(({isRTL, setRTL}) => {
borderBottomEndRadius: 40
Demo:
-
+
{
-
+
);
});
const BorderExample = withRTLState(({isRTL, setRTL}) => {
return (
-
+
Styles
borderStartColor: 'red',
borderEndColor: 'green',
@@ -349,7 +497,7 @@ const BorderExample = withRTLState(({isRTL, setRTL}) => {
borderBottomEndRadius: 40
Demo:
-
+
{
-
+
);
});
-class RTLExample extends React.Component {
- _panResponder: Object;
-
- constructor(props: Object) {
- super(props);
- const pan = new Animated.ValueXY();
-
- this._panResponder = PanResponder.create({
- onStartShouldSetPanResponder: () => true,
- onPanResponderGrant: this._onPanResponderGrant,
- onPanResponderMove: Animated.event([null, {dx: pan.x, dy: pan.y}]),
- onPanResponderRelease: this._onPanResponderEnd,
- onPanResponderTerminate: this._onPanResponderEnd,
- });
-
- this.state = {
- toggleStatus: {},
- pan,
- linear: new Animated.Value(0),
- isRTL: IS_RTL,
- windowWidth: 0,
- };
- }
-
- render() {
- return (
-
-
-
-
-
- {this.state.isRTL ? 'Right-to-Left' : 'Left-to-Right'}
-
-
-
-
-
- forceRTL
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Without directional meaning
-
-
-
-
-
- With directional meaning
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-
- _onLayout = (e: Object) => {
- this.setState({
- windowWidth: e.nativeEvent.layout.width,
- });
- };
-
- _onDirectionChange = () => {
- I18nManager.forceRTL(!this.state.isRTL);
- this.setState({isRTL: !this.state.isRTL});
- Alert.alert(
- 'Reload this page',
- 'Please reload this page to change the UI direction! ' +
- 'All examples in this app will be affected. ' +
- 'Check them out to see what they look like in RTL layout.',
- );
- };
-
- _linearTap = (e: Object) => {
- this.setState({
- toggleStatus: {
- ...this.state.toggleStatus,
- [e]: !this.state.toggleStatus[e],
- },
- });
- const offset = IMAGE_SIZE[0] / SCALE / 2 + 10;
- const toMaxDistance =
- (IS_RTL ? -1 : 1) * (this.state.windowWidth / 2 - offset);
- Animated.timing(this.state.linear, {
- toValue: this.state.toggleStatus[e] ? toMaxDistance : 0,
- duration: 2000,
- useNativeDriver: true,
- }).start();
- };
-
- _onPanResponderGrant = (e: Object, gestureState: Object) => {
- this.state.pan.stopAnimation(value => {
- this.state.pan.setOffset(value);
- });
- };
-
- _onPanResponderEnd = (e: Object, gestureState: Object) => {
- this.state.pan.flattenOffset();
- Animated.sequence([
- Animated.decay(this.state.pan, {
- velocity: {x: gestureState.vx, y: gestureState.vy},
- deceleration: 0.995,
- }),
- Animated.spring(this.state.pan, {toValue: {x: 0, y: 0}}),
- ]).start();
- };
-}
+const directionStyle = isRTL =>
+ Platform.OS === 'ios' ? {direction: isRTL ? 'rtl' : 'ltr'} : null;
const styles = StyleSheet.create({
container: {
@@ -567,6 +532,7 @@ const styles = StyleSheet.create({
backgroundColor: '#f8f8f8',
borderWidth: 0.5,
borderColor: 'black',
+ marginBottom: 15,
},
directionText: {
padding: 10,
@@ -679,9 +645,105 @@ exports.title = 'RTLExample';
exports.description = 'Examples to show how to apply components to RTL layout.';
exports.examples = [
{
- title: 'Simple RTL',
- render: function(): React.Element {
- return ;
+ title: 'Current Layout Direction',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'A Simple List Item Layout',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Default Text Alignment',
+ description:
+ 'In iOS, it depends on active language. ' +
+ 'In Android, it depends on the text content.',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: "Using textAlign: 'left'",
+ description:
+ 'In iOS/Android, text alignment flips regardless of ' +
+ 'languages or text content.',
+ render: function(): React.Element {
+ return (
+
+ );
+ },
+ },
+ {
+ title: "Using textAlign: 'right'",
+ description:
+ 'In iOS/Android, text alignment flips regardless of ' +
+ 'languages or text content.',
+ render: function(): React.Element {
+ return (
+
+ );
+ },
+ },
+ {
+ title: 'Working With Icons',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Controlling Animation',
+ description: 'Animation direction according to layout',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Padding Start/End',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Margin Start/End',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Position Start/End',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Border Width Start/End',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Border Color Start/End',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Border Radii Start/End',
+ render: function(): React.Element {
+ return ;
+ },
+ },
+ {
+ title: 'Border',
+ render: function(): React.Element {
+ return ;
},
},
];