Update packages. Format code with prettier
This commit is contained in:
@@ -15,19 +15,24 @@ export default function TabLayout() {
|
||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
||||
headerShown: false,
|
||||
tabBarButton: HapticTab,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
name='index'
|
||||
options={{
|
||||
title: 'Home',
|
||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name='house.fill' color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="explore"
|
||||
name='explore'
|
||||
options={{
|
||||
title: 'Explore',
|
||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name='paperplane.fill' color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
|
@@ -15,71 +15,82 @@ export default function TabTwoScreen() {
|
||||
headerImage={
|
||||
<IconSymbol
|
||||
size={310}
|
||||
color="#808080"
|
||||
name="chevron.left.forwardslash.chevron.right"
|
||||
color='#808080'
|
||||
name='chevron.left.forwardslash.chevron.right'
|
||||
style={styles.headerImage}
|
||||
/>
|
||||
}>
|
||||
}
|
||||
>
|
||||
<ThemedView style={styles.titleContainer}>
|
||||
<ThemedText
|
||||
type="title"
|
||||
type='title'
|
||||
style={{
|
||||
fontFamily: Fonts.rounded,
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Explore
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
<ThemedText>This app includes example code to help you get started.</ThemedText>
|
||||
<Collapsible title="File-based routing">
|
||||
<ThemedText>
|
||||
This app includes example code to help you get started.
|
||||
</ThemedText>
|
||||
<Collapsible title='File-based routing'>
|
||||
<ThemedText>
|
||||
This app has two screens:{' '}
|
||||
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
|
||||
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
|
||||
<ThemedText type='defaultSemiBold'>app/(tabs)/index.tsx</ThemedText>{' '}
|
||||
and{' '}
|
||||
<ThemedText type='defaultSemiBold'>app/(tabs)/explore.tsx</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.
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/router/introduction">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
<ExternalLink href='https://docs.expo.dev/router/introduction'>
|
||||
<ThemedText type='link'>Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Android, iOS, and web support">
|
||||
<Collapsible title='Android, iOS, and web support'>
|
||||
<ThemedText>
|
||||
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.
|
||||
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>
|
||||
</Collapsible>
|
||||
<Collapsible title="Images">
|
||||
<Collapsible title='Images'>
|
||||
<ThemedText>
|
||||
For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
|
||||
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
|
||||
different screen densities
|
||||
For static images, you can use the{' '}
|
||||
<ThemedText type='defaultSemiBold'>@2x</ThemedText> and{' '}
|
||||
<ThemedText type='defaultSemiBold'>@3x</ThemedText> suffixes to
|
||||
provide files for different screen densities
|
||||
</ThemedText>
|
||||
<Image
|
||||
source={require('assets/images/react-logo.png')}
|
||||
style={{ width: 100, height: 100, alignSelf: 'center' }}
|
||||
/>
|
||||
<ExternalLink href="https://reactnative.dev/docs/images">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
<ExternalLink href='https://reactnative.dev/docs/images'>
|
||||
<ThemedText type='link'>Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Light and dark mode components">
|
||||
<Collapsible title='Light and dark mode components'>
|
||||
<ThemedText>
|
||||
This template has light and dark mode support. The{' '}
|
||||
<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.
|
||||
<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.
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
<ExternalLink href='https://docs.expo.dev/develop/user-interface/color-themes/'>
|
||||
<ThemedText type='link'>Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Animations">
|
||||
<Collapsible title='Animations'>
|
||||
<ThemedText>
|
||||
This template includes an example of an animated component. The{' '}
|
||||
<ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
|
||||
the powerful{' '}
|
||||
<ThemedText type="defaultSemiBold" style={{ fontFamily: Fonts.mono }}>
|
||||
<ThemedText type='defaultSemiBold'>
|
||||
components/HelloWave.tsx
|
||||
</ThemedText>{' '}
|
||||
component uses the powerful{' '}
|
||||
<ThemedText type='defaultSemiBold' style={{ fontFamily: Fonts.mono }}>
|
||||
react-native-reanimated
|
||||
</ThemedText>{' '}
|
||||
library to create a waving hand animation.
|
||||
@@ -87,7 +98,10 @@ export default function TabTwoScreen() {
|
||||
{Platform.select({
|
||||
ios: (
|
||||
<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.
|
||||
</ThemedText>
|
||||
),
|
||||
|
@@ -15,17 +15,19 @@ export default function HomeScreen() {
|
||||
source={require('assets/images/partial-react-logo.png')}
|
||||
style={styles.reactLogo}
|
||||
/>
|
||||
}>
|
||||
}
|
||||
>
|
||||
<ThemedView style={styles.titleContainer}>
|
||||
<ThemedText type="title">Welcome!</ThemedText>
|
||||
<ThemedText type='title'>Welcome!</ThemedText>
|
||||
<HelloWave />
|
||||
</ThemedView>
|
||||
<ThemedView style={styles.stepContainer}>
|
||||
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
|
||||
<ThemedText type='subtitle'>Step 1: Try it</ThemedText>
|
||||
<ThemedText>
|
||||
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
|
||||
Press{' '}
|
||||
<ThemedText type="defaultSemiBold">
|
||||
Edit{' '}
|
||||
<ThemedText type='defaultSemiBold'>app/(tabs)/index.tsx</ThemedText>{' '}
|
||||
to see changes. Press{' '}
|
||||
<ThemedText type='defaultSemiBold'>
|
||||
{Platform.select({
|
||||
ios: 'cmd + d',
|
||||
android: 'cmd + m',
|
||||
@@ -36,22 +38,26 @@ export default function HomeScreen() {
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
<ThemedView style={styles.stepContainer}>
|
||||
<Link href="/modal">
|
||||
<Link href='/modal'>
|
||||
<Link.Trigger>
|
||||
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
|
||||
<ThemedText type='subtitle'>Step 2: Explore</ThemedText>
|
||||
</Link.Trigger>
|
||||
<Link.Preview />
|
||||
<Link.Menu>
|
||||
<Link.MenuAction title="Action" icon="cube" onPress={() => alert('Action pressed')} />
|
||||
<Link.MenuAction
|
||||
title="Share"
|
||||
icon="square.and.arrow.up"
|
||||
title='Action'
|
||||
icon='cube'
|
||||
onPress={() => alert('Action pressed')}
|
||||
/>
|
||||
<Link.MenuAction
|
||||
title='Share'
|
||||
icon='square.and.arrow.up'
|
||||
onPress={() => alert('Share pressed')}
|
||||
/>
|
||||
<Link.Menu title="More" icon="ellipsis">
|
||||
<Link.Menu title='More' icon='ellipsis'>
|
||||
<Link.MenuAction
|
||||
title="Delete"
|
||||
icon="trash"
|
||||
title='Delete'
|
||||
icon='trash'
|
||||
destructive
|
||||
onPress={() => alert('Delete pressed')}
|
||||
/>
|
||||
@@ -64,13 +70,16 @@ export default function HomeScreen() {
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
<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>
|
||||
{`When you're ready, run `}
|
||||
<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> to{' '}
|
||||
<ThemedText type="defaultSemiBold">app-example</ThemedText>.
|
||||
<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> to{' '}
|
||||
<ThemedText type='defaultSemiBold'>app-example</ThemedText>.
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
</ParallaxScrollView>
|
||||
|
@@ -1,4 +1,8 @@
|
||||
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
||||
import {
|
||||
DarkTheme,
|
||||
DefaultTheme,
|
||||
ThemeProvider,
|
||||
} from '@react-navigation/native';
|
||||
import { Stack } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import 'react-native-reanimated';
|
||||
@@ -6,14 +10,14 @@ import { useColorScheme } from '@/hooks/use-color-scheme';
|
||||
import * as Sentry from '@sentry/react-native';
|
||||
import { ConvexProvider, ConvexReactClient } from 'convex/react';
|
||||
|
||||
Sentry.init({
|
||||
Sentry.init({
|
||||
dsn: 'https://ff2e19b7c72ee50463c6c66b5bef7ce0@sentry.gbrown.org/8',
|
||||
sendDefaultPii: true,
|
||||
tracesSampleRate: 1.0,
|
||||
profilesSampleRate: 1.0,
|
||||
});
|
||||
|
||||
const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL)
|
||||
const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL);
|
||||
|
||||
export const unstable_settings = {
|
||||
anchor: '(tabs)',
|
||||
@@ -25,11 +29,14 @@ const RootLayout = () => {
|
||||
return (
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="modal" options={{ presentation: 'modal', title: 'Modal' }} />
|
||||
<Stack.Screen name='(tabs)' options={{ headerShown: false }} />
|
||||
<Stack.Screen
|
||||
name='modal'
|
||||
options={{ presentation: 'modal', title: 'Modal' }}
|
||||
/>
|
||||
</Stack>
|
||||
<StatusBar style="auto" />
|
||||
<StatusBar style='auto' />
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
};
|
||||
export default Sentry.wrap(RootLayout);
|
||||
|
@@ -7,9 +7,9 @@ import { ThemedView } from '@/components/themed-view';
|
||||
export default function ModalScreen() {
|
||||
return (
|
||||
<ThemedView style={styles.container}>
|
||||
<ThemedText type="title">This is a modal</ThemedText>
|
||||
<Link href="/" dismissTo style={styles.link}>
|
||||
<ThemedText type="link">Go to home screen</ThemedText>
|
||||
<ThemedText type='title'>This is a modal</ThemedText>
|
||||
<Link href='/' dismissTo style={styles.link}>
|
||||
<ThemedText type='link'>Go to home screen</ThemedText>
|
||||
</Link>
|
||||
</ThemedView>
|
||||
);
|
||||
|
@@ -1,13 +1,18 @@
|
||||
import { Href, Link } from 'expo-router';
|
||||
import { openBrowserAsync, WebBrowserPresentationStyle } from 'expo-web-browser';
|
||||
import {
|
||||
openBrowserAsync,
|
||||
WebBrowserPresentationStyle,
|
||||
} from 'expo-web-browser';
|
||||
import { type ComponentProps } from 'react';
|
||||
|
||||
type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: Href & string };
|
||||
type Props = Omit<ComponentProps<typeof Link>, 'href'> & {
|
||||
href: Href & string;
|
||||
};
|
||||
|
||||
export function ExternalLink({ href, ...rest }: Props) {
|
||||
return (
|
||||
<Link
|
||||
target="_blank"
|
||||
target='_blank'
|
||||
{...rest}
|
||||
href={href}
|
||||
onPress={async (event) => {
|
||||
|
@@ -12,7 +12,8 @@ export function HelloWave() {
|
||||
},
|
||||
animationIterationCount: 4,
|
||||
animationDuration: '300ms',
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
👋
|
||||
</Animated.Text>
|
||||
);
|
||||
|
@@ -34,11 +34,15 @@ export default function ParallaxScrollView({
|
||||
translateY: interpolate(
|
||||
scrollOffset.value,
|
||||
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
|
||||
[-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
|
||||
[-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75],
|
||||
),
|
||||
},
|
||||
{
|
||||
scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]),
|
||||
scale: interpolate(
|
||||
scrollOffset.value,
|
||||
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
|
||||
[2, 1, 1],
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -48,13 +52,15 @@ export default function ParallaxScrollView({
|
||||
<Animated.ScrollView
|
||||
ref={scrollRef}
|
||||
style={{ backgroundColor, flex: 1 }}
|
||||
scrollEventThrottle={16}>
|
||||
scrollEventThrottle={16}
|
||||
>
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.header,
|
||||
{ backgroundColor: headerBackgroundColor[colorScheme] },
|
||||
headerAnimatedStyle,
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
{headerImage}
|
||||
</Animated.View>
|
||||
<ThemedView style={styles.content}>{children}</ThemedView>
|
||||
|
@@ -7,8 +7,16 @@ export type ThemedViewProps = ViewProps & {
|
||||
darkColor?: string;
|
||||
};
|
||||
|
||||
export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
|
||||
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
||||
export function ThemedView({
|
||||
style,
|
||||
lightColor,
|
||||
darkColor,
|
||||
...otherProps
|
||||
}: ThemedViewProps) {
|
||||
const backgroundColor = useThemeColor(
|
||||
{ light: lightColor, dark: darkColor },
|
||||
'background',
|
||||
);
|
||||
|
||||
return <View style={[{ backgroundColor }, style]} {...otherProps} />;
|
||||
}
|
||||
|
@@ -7,7 +7,10 @@ import { IconSymbol } from '@/components/ui/icon-symbol';
|
||||
import { Colors } from '@/constants/theme';
|
||||
import { useColorScheme } from '@/hooks/use-color-scheme';
|
||||
|
||||
export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
|
||||
export function Collapsible({
|
||||
children,
|
||||
title,
|
||||
}: PropsWithChildren & { title: string }) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const theme = useColorScheme() ?? 'light';
|
||||
|
||||
@@ -16,16 +19,17 @@ export function Collapsible({ children, title }: PropsWithChildren & { title: st
|
||||
<TouchableOpacity
|
||||
style={styles.heading}
|
||||
onPress={() => setIsOpen((value) => !value)}
|
||||
activeOpacity={0.8}>
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<IconSymbol
|
||||
name="chevron.right"
|
||||
name='chevron.right'
|
||||
size={18}
|
||||
weight="medium"
|
||||
weight='medium'
|
||||
color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
|
||||
style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
|
||||
/>
|
||||
|
||||
<ThemedText type="defaultSemiBold">{title}</ThemedText>
|
||||
<ThemedText type='defaultSemiBold'>{title}</ThemedText>
|
||||
</TouchableOpacity>
|
||||
{isOpen && <ThemedView style={styles.content}>{children}</ThemedView>}
|
||||
</ThemedView>
|
||||
|
@@ -18,7 +18,7 @@ export function IconSymbol({
|
||||
<SymbolView
|
||||
weight={weight}
|
||||
tintColor={color}
|
||||
resizeMode="scaleAspectFit"
|
||||
resizeMode='scaleAspectFit'
|
||||
name={name}
|
||||
style={[
|
||||
{
|
||||
|
@@ -5,7 +5,10 @@ import { SymbolWeight, SymbolViewProps } from 'expo-symbols';
|
||||
import { ComponentProps } from 'react';
|
||||
import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native';
|
||||
|
||||
type IconMapping = Record<SymbolViewProps['name'], ComponentProps<typeof MaterialIcons>['name']>;
|
||||
type IconMapping = Record<
|
||||
SymbolViewProps['name'],
|
||||
ComponentProps<typeof MaterialIcons>['name']
|
||||
>;
|
||||
type IconSymbolName = keyof typeof MAPPING;
|
||||
|
||||
/**
|
||||
@@ -37,5 +40,12 @@ export function IconSymbol({
|
||||
style?: StyleProp<TextStyle>;
|
||||
weight?: SymbolWeight;
|
||||
}) {
|
||||
return <MaterialIcons color={color} size={size} name={MAPPING[name]} style={style} />;
|
||||
return (
|
||||
<MaterialIcons
|
||||
color={color}
|
||||
size={size}
|
||||
name={MAPPING[name]}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@@ -47,7 +47,8 @@ export const Fonts = Platform.select({
|
||||
web: {
|
||||
sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
|
||||
serif: "Georgia, 'Times New Roman', serif",
|
||||
rounded: "'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif",
|
||||
rounded:
|
||||
"'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif",
|
||||
mono: "SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
|
||||
},
|
||||
});
|
||||
|
@@ -8,7 +8,7 @@ import { useColorScheme } from '@/hooks/use-color-scheme';
|
||||
|
||||
export function useThemeColor(
|
||||
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 colorFromProps = props[theme];
|
||||
|
Reference in New Issue
Block a user