Add prettier

This commit is contained in:
Gabriel Brown 2025-01-28 08:45:02 -06:00
parent db606f2e2a
commit 5a821fc6b5
16 changed files with 115 additions and 81 deletions

8
.prettierrc Normal file
View File

@ -0,0 +1,8 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"jsxSingleQuote": true,
"trailingComma": "all"
}

View File

@ -25,19 +25,20 @@ export default function TabLayout() {
}, },
default: {}, default: {},
}), }),
}}> }}
>
<Tabs.Screen <Tabs.Screen
name="index" name='index'
options={{ options={{
title: 'Home', title: 'Home',
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />, tabBarIcon: ({ color }) => <IconSymbol size={28} name='house.fill' color={color} />,
}} }}
/> />
<Tabs.Screen <Tabs.Screen
name="explore" name='explore'
options={{ options={{
title: 'Explore', title: 'Explore',
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />, tabBarIcon: ({ color }) => <IconSymbol size={28} name='paperplane.fill' color={color} />,
}} }}
/> />
</Tabs> </Tabs>

View File

@ -14,78 +14,79 @@ export default function TabTwoScreen() {
headerImage={ headerImage={
<IconSymbol <IconSymbol
size={310} size={310}
color="#808080" color='#808080'
name="chevron.left.forwardslash.chevron.right" name='chevron.left.forwardslash.chevron.right'
style={styles.headerImage} style={styles.headerImage}
/> />
}> }
>
<ThemedView style={styles.titleContainer}> <ThemedView style={styles.titleContainer}>
<ThemedText type="title">Explore</ThemedText> <ThemedText type='title'>Explore</ThemedText>
</ThemedView> </ThemedView>
<ThemedText>This app includes example code to help you get started.</ThemedText> <ThemedText>This app includes example code to help you get started.</ThemedText>
<Collapsible title="File-based routing"> <Collapsible title='File-based routing'>
<ThemedText> <ThemedText>
This app has two screens:{' '} This app has two screens:{' '}
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '} <ThemedText type='defaultSemiBold'>app/(tabs)/index.tsx</ThemedText> and{' '}
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText> <ThemedText type='defaultSemiBold'>app/(tabs)/explore.tsx</ThemedText>
</ThemedText> </ThemedText>
<ThemedText> <ThemedText>
The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '} The layout file in <ThemedText type='defaultSemiBold'>app/(tabs)/_layout.tsx</ThemedText>{' '}
sets up the tab navigator. sets up the tab navigator.
</ThemedText> </ThemedText>
<ExternalLink href="https://docs.expo.dev/router/introduction"> <ExternalLink href='https://docs.expo.dev/router/introduction'>
<ThemedText type="link">Learn more</ThemedText> <ThemedText type='link'>Learn more</ThemedText>
</ExternalLink> </ExternalLink>
</Collapsible> </Collapsible>
<Collapsible title="Android, iOS, and web support"> <Collapsible title='Android, iOS, and web support'>
<ThemedText> <ThemedText>
You can open this project on Android, iOS, and the web. To open the web version, press{' '} You can open this project on Android, iOS, and the web. To open the web version, press{' '}
<ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project. <ThemedText type='defaultSemiBold'>w</ThemedText> in the terminal running this project.
</ThemedText> </ThemedText>
</Collapsible> </Collapsible>
<Collapsible title="Images"> <Collapsible title='Images'>
<ThemedText> <ThemedText>
For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '} For static images, you can use the <ThemedText type='defaultSemiBold'>@2x</ThemedText> and{' '}
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for <ThemedText type='defaultSemiBold'>@3x</ThemedText> suffixes to provide files for
different screen densities different screen densities
</ThemedText> </ThemedText>
<Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} /> <Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
<ExternalLink href="https://reactnative.dev/docs/images"> <ExternalLink href='https://reactnative.dev/docs/images'>
<ThemedText type="link">Learn more</ThemedText> <ThemedText type='link'>Learn more</ThemedText>
</ExternalLink> </ExternalLink>
</Collapsible> </Collapsible>
<Collapsible title="Custom fonts"> <Collapsible title='Custom fonts'>
<ThemedText> <ThemedText>
Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '} Open <ThemedText type='defaultSemiBold'>app/_layout.tsx</ThemedText> to see how to load{' '}
<ThemedText style={{ fontFamily: 'SpaceMono' }}> <ThemedText style={{ fontFamily: 'SpaceMono' }}>
custom fonts such as this one. custom fonts such as this one.
</ThemedText> </ThemedText>
</ThemedText> </ThemedText>
<ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font"> <ExternalLink href='https://docs.expo.dev/versions/latest/sdk/font'>
<ThemedText type="link">Learn more</ThemedText> <ThemedText type='link'>Learn more</ThemedText>
</ExternalLink> </ExternalLink>
</Collapsible> </Collapsible>
<Collapsible title="Light and dark mode components"> <Collapsible title='Light and dark mode components'>
<ThemedText> <ThemedText>
This template has light and dark mode support. The{' '} This template has light and dark mode support. The{' '}
<ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect <ThemedText type='defaultSemiBold'>useColorScheme()</ThemedText> hook lets you inspect
what the user's current color scheme is, and so you can adjust UI colors accordingly. what the user's current color scheme is, and so you can adjust UI colors accordingly.
</ThemedText> </ThemedText>
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/"> <ExternalLink href='https://docs.expo.dev/develop/user-interface/color-themes/'>
<ThemedText type="link">Learn more</ThemedText> <ThemedText type='link'>Learn more</ThemedText>
</ExternalLink> </ExternalLink>
</Collapsible> </Collapsible>
<Collapsible title="Animations"> <Collapsible title='Animations'>
<ThemedText> <ThemedText>
This template includes an example of an animated component. The{' '} This template includes an example of an animated component. The{' '}
<ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses <ThemedText type='defaultSemiBold'>components/HelloWave.tsx</ThemedText> component uses
the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '} the powerful <ThemedText type='defaultSemiBold'>react-native-reanimated</ThemedText>{' '}
library to create a waving hand animation. library to create a waving hand animation.
</ThemedText> </ThemedText>
{Platform.select({ {Platform.select({
ios: ( ios: (
<ThemedText> <ThemedText>
The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '} The <ThemedText type='defaultSemiBold'>components/ParallaxScrollView.tsx</ThemedText>{' '}
component provides a parallax effect for the header image. component provides a parallax effect for the header image.
</ThemedText> </ThemedText>
), ),

View File

@ -14,40 +14,41 @@ export default function HomeScreen() {
source={require('@/assets/images/partial-react-logo.png')} source={require('@/assets/images/partial-react-logo.png')}
style={styles.reactLogo} style={styles.reactLogo}
/> />
}> }
>
<ThemedView style={styles.titleContainer}> <ThemedView style={styles.titleContainer}>
<ThemedText type="title">Welcome!</ThemedText> <ThemedText type='title'>Welcome!</ThemedText>
<HelloWave /> <HelloWave />
</ThemedView> </ThemedView>
<ThemedView style={styles.stepContainer}> <ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 1: Try it</ThemedText> <ThemedText type='subtitle'>Step 1: Try it</ThemedText>
<ThemedText> <ThemedText>
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes. Edit <ThemedText type='defaultSemiBold'>app/(tabs)/index.tsx</ThemedText> to see changes.
Press{' '} Press{' '}
<ThemedText type="defaultSemiBold"> <ThemedText type='defaultSemiBold'>
{Platform.select({ {Platform.select({
ios: 'cmd + d', ios: 'cmd + d',
android: 'cmd + m', android: 'cmd + m',
web: 'F12' web: 'F12',
})} })}
</ThemedText>{' '} </ThemedText>{' '}
to open developer tools. to open developer tools.
</ThemedText> </ThemedText>
</ThemedView> </ThemedView>
<ThemedView style={styles.stepContainer}> <ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 2: Explore</ThemedText> <ThemedText type='subtitle'>Step 2: Explore</ThemedText>
<ThemedText> <ThemedText>
Tap the Explore tab to learn more about what's included in this starter app. Tap the Explore tab to learn more about what's included in this starter app.
</ThemedText> </ThemedText>
</ThemedView> </ThemedView>
<ThemedView style={styles.stepContainer}> <ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText> <ThemedText type='subtitle'>Step 3: Get a fresh start</ThemedText>
<ThemedText> <ThemedText>
When you're ready, run{' '} When you're ready, run{' '}
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '} <ThemedText type='defaultSemiBold'>npm run reset-project</ThemedText> to get a fresh{' '}
<ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '} <ThemedText type='defaultSemiBold'>app</ThemedText> directory. This will move the current{' '}
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '} <ThemedText type='defaultSemiBold'>app</ThemedText> to{' '}
<ThemedText type="defaultSemiBold">app-example</ThemedText>. <ThemedText type='defaultSemiBold'>app-example</ThemedText>.
</ThemedText> </ThemedText>
</ThemedView> </ThemedView>
</ParallaxScrollView> </ParallaxScrollView>

View File

@ -9,9 +9,9 @@ export default function NotFoundScreen() {
<> <>
<Stack.Screen options={{ title: 'Oops!' }} /> <Stack.Screen options={{ title: 'Oops!' }} />
<ThemedView style={styles.container}> <ThemedView style={styles.container}>
<ThemedText type="title">This screen doesn't exist.</ThemedText> <ThemedText type='title'>This screen doesn't exist.</ThemedText>
<Link href="/" style={styles.link}> <Link href='/' style={styles.link}>
<ThemedText type="link">Go to home screen!</ThemedText> <ThemedText type='link'>Go to home screen!</ThemedText>
</Link> </Link>
</ThemedView> </ThemedView>
</> </>

View File

@ -30,10 +30,10 @@ export default function RootLayout() {
return ( return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
<Stack> <Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name='(tabs)' options={{ headerShown: false }} />
<Stack.Screen name="+not-found" /> <Stack.Screen name='+not-found' />
</Stack> </Stack>
<StatusBar style="auto" /> <StatusBar style='auto' />
</ThemeProvider> </ThemeProvider>
); );
} }

View File

@ -16,16 +16,17 @@ export function Collapsible({ children, title }: PropsWithChildren & { title: st
<TouchableOpacity <TouchableOpacity
style={styles.heading} style={styles.heading}
onPress={() => setIsOpen((value) => !value)} onPress={() => setIsOpen((value) => !value)}
activeOpacity={0.8}> activeOpacity={0.8}
>
<IconSymbol <IconSymbol
name="chevron.right" name='chevron.right'
size={18} size={18}
weight="medium" weight='medium'
color={theme === 'light' ? Colors.light.icon : Colors.dark.icon} color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }} style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
/> />
<ThemedText type="defaultSemiBold">{title}</ThemedText> <ThemedText type='defaultSemiBold'>{title}</ThemedText>
</TouchableOpacity> </TouchableOpacity>
{isOpen && <ThemedView style={styles.content}>{children}</ThemedView>} {isOpen && <ThemedView style={styles.content}>{children}</ThemedView>}
</ThemedView> </ThemedView>

View File

@ -8,7 +8,7 @@ type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: string };
export function ExternalLink({ href, ...rest }: Props) { export function ExternalLink({ href, ...rest }: Props) {
return ( return (
<Link <Link
target="_blank" target='_blank'
{...rest} {...rest}
href={href} href={href}
onPress={async (event) => { onPress={async (event) => {

View File

@ -16,7 +16,7 @@ export function HelloWave() {
useEffect(() => { useEffect(() => {
rotationAnimation.value = withRepeat( rotationAnimation.value = withRepeat(
withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })), withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })),
4 // Run the animation 4 times 4, // Run the animation 4 times
); );
}, []); }, []);

View File

@ -34,7 +34,7 @@ export default function ParallaxScrollView({
translateY: interpolate( translateY: interpolate(
scrollOffset.value, scrollOffset.value,
[-HEADER_HEIGHT, 0, HEADER_HEIGHT], [-HEADER_HEIGHT, 0, HEADER_HEIGHT],
[-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75] [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75],
), ),
}, },
{ {
@ -50,13 +50,15 @@ export default function ParallaxScrollView({
ref={scrollRef} ref={scrollRef}
scrollEventThrottle={16} scrollEventThrottle={16}
scrollIndicatorInsets={{ bottom }} scrollIndicatorInsets={{ bottom }}
contentContainerStyle={{ paddingBottom: bottom }}> contentContainerStyle={{ paddingBottom: bottom }}
>
<Animated.View <Animated.View
style={[ style={[
styles.header, styles.header,
{ backgroundColor: headerBackgroundColor[colorScheme] }, { backgroundColor: headerBackgroundColor[colorScheme] },
headerAnimatedStyle, headerAnimatedStyle,
]}> ]}
>
{headerImage} {headerImage}
</Animated.View> </Animated.View>
<ThemedView style={styles.content}>{children}</ThemedView> <ThemedView style={styles.content}>{children}</ThemedView>

View File

@ -18,7 +18,7 @@ export function IconSymbol({
<SymbolView <SymbolView
weight={weight} weight={weight}
tintColor={color} tintColor={color}
resizeMode="scaleAspectFit" resizeMode='scaleAspectFit'
name={name} name={name}
style={[ style={[
{ {

View File

@ -8,7 +8,7 @@ export default function BlurTabBarBackground() {
<BlurView <BlurView
// System chrome material automatically adapts to the system's theme // System chrome material automatically adapts to the system's theme
// and matches the native tab bar appearance on iOS. // and matches the native tab bar appearance on iOS.
tint="systemChromeMaterial" tint='systemChromeMaterial'
intensity={100} intensity={100}
style={StyleSheet.absoluteFill} style={StyleSheet.absoluteFill}
/> />

View File

@ -8,7 +8,7 @@ import { useColorScheme } from '@/hooks/useColorScheme';
export function useThemeColor( export function useThemeColor(
props: { light?: string; dark?: string }, props: { light?: string; dark?: string },
colorName: keyof typeof Colors.light & keyof typeof Colors.dark colorName: keyof typeof Colors.light & keyof typeof Colors.dark,
) { ) {
const theme = useColorScheme() ?? 'light'; const theme = useColorScheme() ?? 'light';
const colorFromProps = props[theme]; const colorFromProps = props[theme];

17
package-lock.json generated
View File

@ -44,6 +44,7 @@
"@types/react-test-renderer": "^18.3.0", "@types/react-test-renderer": "^18.3.0",
"jest": "^29.2.1", "jest": "^29.2.1",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"prettier": "^3.4.2",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
@ -11826,6 +11827,22 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/prettier": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/pretty-bytes": { "node_modules/pretty-bytes": {
"version": "5.6.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",

View File

@ -10,7 +10,9 @@
"ios": "expo start --ios", "ios": "expo start --ios",
"web": "expo start --web", "web": "expo start --web",
"test": "jest --watchAll", "test": "jest --watchAll",
"lint": "expo lint" "lint": "expo lint",
"format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache"
}, },
"jest": { "jest": {
"preset": "jest-expo" "preset": "jest-expo"
@ -22,14 +24,17 @@
"expo": "~52.0.28", "expo": "~52.0.28",
"expo-blur": "~14.0.3", "expo-blur": "~14.0.3",
"expo-constants": "~17.0.5", "expo-constants": "~17.0.5",
"expo-dev-client": "~5.0.10",
"expo-font": "~13.0.3", "expo-font": "~13.0.3",
"expo-haptics": "~14.0.1", "expo-haptics": "~14.0.1",
"expo-insights": "~0.8.2",
"expo-linking": "~7.0.5", "expo-linking": "~7.0.5",
"expo-router": "~4.0.17", "expo-router": "~4.0.17",
"expo-splash-screen": "~0.29.21", "expo-splash-screen": "~0.29.21",
"expo-status-bar": "~2.0.1", "expo-status-bar": "~2.0.1",
"expo-symbols": "~0.2.1", "expo-symbols": "~0.2.1",
"expo-system-ui": "~4.0.7", "expo-system-ui": "~4.0.7",
"expo-updates": "~0.26.13",
"expo-web-browser": "~14.0.2", "expo-web-browser": "~14.0.2",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
@ -39,10 +44,7 @@
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0", "react-native-screens": "~4.4.0",
"react-native-web": "~0.19.13", "react-native-web": "~0.19.13",
"react-native-webview": "13.12.5", "react-native-webview": "13.12.5"
"expo-dev-client": "~5.0.10",
"expo-insights": "~0.8.2",
"expo-updates": "~0.26.13"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@ -51,6 +53,7 @@
"@types/react-test-renderer": "^18.3.0", "@types/react-test-renderer": "^18.3.0",
"jest": "^29.2.1", "jest": "^29.2.1",
"jest-expo": "~52.0.3", "jest-expo": "~52.0.3",
"prettier": "^3.4.2",
"react-test-renderer": "18.3.1", "react-test-renderer": "18.3.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }

View File

@ -6,13 +6,13 @@
* You can remove the `reset-project` script from package.json and safely delete this file after running it. * You can remove the `reset-project` script from package.json and safely delete this file after running it.
*/ */
const fs = require("fs"); const fs = require('fs');
const path = require("path"); const path = require('path');
const root = process.cwd(); const root = process.cwd();
const oldDirs = ["app", "components", "hooks", "constants", "scripts"]; const oldDirs = ['app', 'components', 'hooks', 'constants', 'scripts'];
const newDir = "app-example"; const newDir = 'app-example';
const newAppDir = "app"; const newAppDir = 'app';
const newDirPath = path.join(root, newDir); const newDirPath = path.join(root, newDir);
const indexContent = `import { Text, View } from "react-native"; const indexContent = `import { Text, View } from "react-native";
@ -60,21 +60,21 @@ const moveDirectories = async () => {
// Create new /app directory // Create new /app directory
const newAppDirPath = path.join(root, newAppDir); const newAppDirPath = path.join(root, newAppDir);
await fs.promises.mkdir(newAppDirPath, { recursive: true }); await fs.promises.mkdir(newAppDirPath, { recursive: true });
console.log("\n📁 New /app directory created."); console.log('\n📁 New /app directory created.');
// Create index.tsx // Create index.tsx
const indexPath = path.join(newAppDirPath, "index.tsx"); const indexPath = path.join(newAppDirPath, 'index.tsx');
await fs.promises.writeFile(indexPath, indexContent); await fs.promises.writeFile(indexPath, indexContent);
console.log("📄 app/index.tsx created."); console.log('📄 app/index.tsx created.');
// Create _layout.tsx // Create _layout.tsx
const layoutPath = path.join(newAppDirPath, "_layout.tsx"); const layoutPath = path.join(newAppDirPath, '_layout.tsx');
await fs.promises.writeFile(layoutPath, layoutContent); await fs.promises.writeFile(layoutPath, layoutContent);
console.log("📄 app/_layout.tsx created."); console.log('📄 app/_layout.tsx created.');
console.log("\n✅ Project reset complete. Next steps:"); console.log('\n✅ Project reset complete. Next steps:');
console.log( console.log(
"1. Run `npx expo start` to start a development server.\n2. Edit app/index.tsx to edit the main screen.\n3. Delete the /app-example directory when you're done referencing it." "1. Run `npx expo start` to start a development server.\n2. Edit app/index.tsx to edit the main screen.\n3. Delete the /app-example directory when you're done referencing it.",
); );
} catch (error) { } catch (error) {
console.error(`Error during script execution: ${error}`); console.error(`Error during script execution: ${error}`);