Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: experiments app #1391

Merged
merged 8 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions experiments-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/

# macOS
.DS_Store

# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
5 changes: 5 additions & 0 deletions experiments-app/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// added for Jest inline snapshots to not use default Prettier config
module.exports = {
singleQuote: true,
trailingComma: "es5"
}
30 changes: 30 additions & 0 deletions experiments-app/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"expo": {
"name": "experiments-app",
"slug": "experiments-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
Binary file added experiments-app/assets/adaptive-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added experiments-app/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added experiments-app/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added experiments-app/assets/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions experiments-app/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
4 changes: 4 additions & 0 deletions experiments-app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import registerRootComponent from 'expo/build/launch/registerRootComponent';
import App from './src/App';

registerRootComponent(App);
31 changes: 31 additions & 0 deletions experiments-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "experiments-app",
"private": true,
"description": "Expo app for conducting experiments of React Native behaviour.",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"typecheck": "tsc -noEmit",
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^6.9.12",
"add": "^2.0.6",
"expo": "~48.0.11",
"expo-status-bar": "~1.4.4",
"react": "18.2.0",
"react-native": "0.71.6",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.20.0",
"yarn": "^1.22.19"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/react": "~18.0.14",
"typescript": "^4.9.4"
}
}
31 changes: 31 additions & 0 deletions experiments-app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react';
import { StatusBar } from 'expo-status-bar';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { MainScreen } from './MainScreen';
import { experiments } from './experiments';

const Stack = createNativeStackNavigator();

export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="main"
component={MainScreen}
options={{ title: 'Experiments' }}
/>
{experiments.map((exp) => (
<Stack.Screen
key={exp.key}
name={exp.key}
component={exp.component}
options={{ title: exp.title }}
/>
))}
</Stack.Navigator>
<StatusBar style="auto" />
</NavigationContainer>
);
}
54 changes: 54 additions & 0 deletions experiments-app/src/Experiments/TextInputEventPropagation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';
import { StyleSheet, SafeAreaView, TextInput, Pressable } from 'react-native';
import { buildEventLogger } from '../utils/helpers';

const handlePressIn = buildEventLogger('TextInput.pressIn');
const handlePressOut = buildEventLogger('TextInput.pressOut');
const handleFocus = buildEventLogger('TextInput.focus');
const handleBlur = buildEventLogger('TextInput.blur');
const handleChange = buildEventLogger('TextInput.change');
const handleSubmitEditing = buildEventLogger('TextInput.submitEditing');

const handlePressablePress = buildEventLogger('Pressable.press');

export function TextInputEventPropagation() {
const [value, setValue] = React.useState('');

const handleChangeText = (value: string) => {
setValue(value);
console.log(`Event: changeText`, value);
};

return (
<SafeAreaView style={styles.container}>
<Pressable onPress={handlePressablePress}>
<TextInput
style={styles.textInput}
value={value}
editable={true}
onChangeText={handleChangeText}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
onFocus={handleFocus}
onBlur={handleBlur}
onChange={handleChange}
onSubmitEditing={handleSubmitEditing}
/>
</Pressable>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
textInput: {
backgroundColor: 'white',
margin: 20,
padding: 8,
fontSize: 18,
borderWidth: 1,
borderColor: 'grey',
},
});
50 changes: 50 additions & 0 deletions experiments-app/src/Experiments/TextInputEvents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as React from 'react';
import { StyleSheet, SafeAreaView, TextInput } from 'react-native';
import { buildEventLogger } from '../utils/helpers';

const handlePressIn = buildEventLogger('pressIn');
const handlePressOut = buildEventLogger('pressOut');
const handleFocus = buildEventLogger('focus');
const handleBlur = buildEventLogger('blur');
const handleChange = buildEventLogger('change');
const handleSubmitEditing = buildEventLogger('submitEditing');

export function TextInputEvents() {
const [value, setValue] = React.useState('');

const handleChangeText = (value: string) => {
setValue(value);
console.log(`Event: changeText`, value);
};

return (
<SafeAreaView style={styles.container}>
<TextInput
style={styles.textInput}
value={value}
editable={true}
onChangeText={handleChangeText}
onPressIn={handlePressIn}
onPressOut={handlePressOut}
onFocus={handleFocus}
onBlur={handleBlur}
onChange={handleChange}
onSubmitEditing={handleSubmitEditing}
/>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
textInput: {
backgroundColor: 'white',
margin: 20,
padding: 8,
fontSize: 18,
borderWidth: 1,
borderColor: 'grey',
},
});
51 changes: 51 additions & 0 deletions experiments-app/src/MainScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as React from 'react';
import {
StyleSheet,
SafeAreaView,
Text,
FlatList,
Pressable,
} from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { Experiment, experiments } from './experiments';

export function MainScreen() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={experiments}
renderItem={({ item }) => <ListItem item={item} />}
/>
</SafeAreaView>
);
}

interface ListItemProps {
item: Experiment;
}

function ListItem({ item }: ListItemProps) {
const navigation = useNavigation();

const handlePress = () => {
navigation.navigate(item.key);
};

return (
<Pressable style={styles.item} onPress={handlePress}>
<Text style={styles.itemTitle}>{item.title}</Text>
</Pressable>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
padding: 20,
},
itemTitle: {
fontSize: 20,
},
});
17 changes: 17 additions & 0 deletions experiments-app/src/experiments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TextInputEventPropagation } from './experiments/TextInputEventPropagation';
import { TextInputEvents } from './experiments/TextInputEvents';

export type Experiment = (typeof experiments)[number];

export const experiments = [
{
key: 'textInputEvents',
title: 'TextInput Events',
component: TextInputEvents,
},
{
key: 'textInputEventPropagation',
title: 'TextInput Event Propagation',
component: TextInputEventPropagation,
},
];
8 changes: 8 additions & 0 deletions experiments-app/src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { NativeSyntheticEvent } from 'react-native/types';

export function buildEventLogger(name: string) {
return (event: NativeSyntheticEvent<unknown>) => {
const eventData = event?.nativeEvent ?? event;
console.log(`Event: ${name}`, eventData);
};
}
6 changes: 6 additions & 0 deletions experiments-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}
Loading