@mr.dj2u/library-registry 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +42 -0
- package/THIRD_PARTY_NOTICES.md +90 -0
- package/assets/create-expo-app/sdk-56/assets/images/expo-badge-white.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/expo-badge.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/expo-logo.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/logo-glow.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/react-logo.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/react-logo@2x.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/react-logo@3x.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tabIcons/explore.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tabIcons/explore@2x.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tabIcons/explore@3x.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tabIcons/home.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tabIcons/home@2x.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tabIcons/home@3x.png +0 -0
- package/assets/create-expo-app/sdk-56/assets/images/tutorial-web.png +0 -0
- package/assets/create-expo-app/sdk-56/src/app/_layout.tsx +15 -0
- package/assets/create-expo-app/sdk-56/src/app/explore.tsx +180 -0
- package/assets/create-expo-app/sdk-56/src/app/index.tsx +98 -0
- package/assets/create-expo-app/sdk-56/src/components/animated-icon.module.css +6 -0
- package/assets/create-expo-app/sdk-56/src/components/animated-icon.tsx +132 -0
- package/assets/create-expo-app/sdk-56/src/components/animated-icon.web.tsx +108 -0
- package/assets/create-expo-app/sdk-56/src/components/app-tabs.tsx +32 -0
- package/assets/create-expo-app/sdk-56/src/components/app-tabs.web.tsx +115 -0
- package/assets/create-expo-app/sdk-56/src/components/external-link.tsx +25 -0
- package/assets/create-expo-app/sdk-56/src/components/hint-row.tsx +35 -0
- package/assets/create-expo-app/sdk-56/src/components/themed-text.tsx +73 -0
- package/assets/create-expo-app/sdk-56/src/components/themed-view.tsx +16 -0
- package/assets/create-expo-app/sdk-56/src/components/ui/collapsible.tsx +65 -0
- package/assets/create-expo-app/sdk-56/src/components/web-badge.tsx +43 -0
- package/assets/create-expo-app/sdk-56/src/constants/theme.ts +65 -0
- package/assets/create-expo-app/sdk-56/src/global.css +9 -0
- package/assets/create-expo-app/sdk-56/src/hooks/use-color-scheme.ts +1 -0
- package/assets/create-expo-app/sdk-56/src/hooks/use-color-scheme.web.ts +21 -0
- package/assets/create-expo-app/sdk-56/src/hooks/use-theme.ts +14 -0
- package/assets/create-expo-stack/2.21.3/base/components/BackButton.tsx +23 -0
- package/assets/create-expo-stack/2.21.3/base/components/Button.tsx +42 -0
- package/assets/create-expo-stack/2.21.3/base/components/Container.tsx +14 -0
- package/assets/create-expo-stack/2.21.3/base/components/EditScreenInfo.tsx +36 -0
- package/assets/create-expo-stack/2.21.3/base/components/HeaderButton.tsx +31 -0
- package/assets/create-expo-stack/2.21.3/base/components/ScreenContent.tsx +40 -0
- package/assets/create-expo-stack/2.21.3/base/components/TabBarIcon.tsx +15 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/ActivityIndicator.tsx +10 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Avatar.tsx +32 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Button.tsx +141 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/DatePicker/DatePicker.android.tsx +77 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/DatePicker/DatePicker.tsx +23 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/DatePicker/index.ts +1 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/Icon.ios.tsx +55 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/Icon.tsx +58 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/index.ts +16 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Icon/types.ts +19 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Picker.tsx +42 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/ProgressIndicator.tsx +68 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Slider.tsx +28 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Text.tsx +55 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/ThemeToggle.tsx +33 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/components/nativewindui/Toggle.tsx +20 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/lib/cn.ts +6 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/lib/useColorScheme.tsx +21 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/lib/useHeaderSearchBar.tsx +33 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/theme/colors.ts +123 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/theme/index.ts +32 -0
- package/assets/create-expo-stack/2.21.3-mrdj.2/src/theme/with-opacity.ts +155 -0
- package/assets/mds/routes/drawer-tabs/data.tsx +1 -0
- package/assets/mds/routes/drawer-tabs/index.tsx +1 -0
- package/assets/mds/routes/drawer-tabs/nativewindui.tsx +1 -0
- package/assets/mds/routes/drawer-tabs/sdk-56.tsx +1 -0
- package/assets/mds/routes/drawer-tabs/stylist.tsx +1 -0
- package/assets/mds/scripts/stylist-sync-android.mjs +39 -0
- package/assets/mds/src/app/exposition/data.tsx +1 -0
- package/assets/mds/src/app/exposition/index.tsx +1 -0
- package/assets/mds/src/app/exposition/nativewindui.tsx +1 -0
- package/assets/mds/src/app/exposition/sdk-56.tsx +1 -0
- package/assets/mds/src/app/exposition/stylist-sync+api.ts +241 -0
- package/assets/mds/src/app/exposition/stylist.tsx +1 -0
- package/assets/mds/src/app/onboarding/account-setup.tsx +1 -0
- package/assets/mds/src/app/onboarding/agreement.tsx +1 -0
- package/assets/mds/src/app/onboarding/terms.tsx +1 -0
- package/assets/mds/src/app/onboarding.tsx +1 -0
- package/assets/mds/src/app/settings.tsx +1 -0
- package/assets/mds/src/components/exposition/index.ts +8 -0
- package/assets/mds/src/components/exposition/notice.tsx +3 -0
- package/assets/mds/src/components/exposition/package-card.tsx +76 -0
- package/assets/mds/src/components/swmansion/animated-pressable.tsx +54 -0
- package/assets/mds/src/components/swmansion/gesture-card.tsx +54 -0
- package/assets/mds/src/components/swmansion/keyboard-form.tsx +73 -0
- package/assets/mds/src/components/swmansion/screens-card.tsx +40 -0
- package/assets/mds/src/components/swmansion/software-mansion-logo.tsx +15 -0
- package/assets/mds/src/components/swmansion/svg-mark.tsx +16 -0
- package/assets/mds/src/data/mock-app.ts +21 -0
- package/assets/mds/src/features/exposition/data-screen.tsx +152 -0
- package/assets/mds/src/features/exposition/embedded-fonts.ts +72 -0
- package/assets/mds/src/features/exposition/expo-sdk-56-screen.tsx +709 -0
- package/assets/mds/src/features/exposition/exposition-screen.tsx +191 -0
- package/assets/mds/src/features/exposition/nativewindui-screen.tsx +125 -0
- package/assets/mds/src/features/exposition/stylist-screen.tsx +3456 -0
- package/assets/mds/src/features/onboarding/account-setup-screen.tsx +54 -0
- package/assets/mds/src/features/onboarding/agreement-screen.tsx +6 -0
- package/assets/mds/src/features/onboarding/components/legal-document-view.tsx +103 -0
- package/assets/mds/src/features/onboarding/legal-documents.ts +80 -0
- package/assets/mds/src/features/onboarding/onboarding-screen.tsx +167 -0
- package/assets/mds/src/features/onboarding/terms-screen.tsx +6 -0
- package/assets/mds/src/features/settings/settings-screen.tsx +57 -0
- package/assets/mds/src/services/local-data.native.ts +103 -0
- package/assets/mds/src/services/local-data.ts +38 -0
- package/assets/mds/src/theme/font-assets.ts +3 -0
- package/assets/mds/src/theme/provider.tsx +59 -0
- package/assets/mds/src/theme/tokens.ts +180 -0
- package/dist/catalog.d.ts +3 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +1110 -0
- package/dist/catalog.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +7 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +479 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +169 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +6 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +209 -0
- package/dist/validation.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Image } from 'expo-image';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
import Animated, { Keyframe, Easing } from 'react-native-reanimated';
|
|
4
|
+
|
|
5
|
+
import classes from './animated-icon.module.css';
|
|
6
|
+
const DURATION = 300;
|
|
7
|
+
|
|
8
|
+
export function AnimatedSplashOverlay() {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const keyframe = new Keyframe({
|
|
13
|
+
0: {
|
|
14
|
+
transform: [{ scale: 0 }],
|
|
15
|
+
},
|
|
16
|
+
60: {
|
|
17
|
+
transform: [{ scale: 1.2 }],
|
|
18
|
+
easing: Easing.elastic(1.2),
|
|
19
|
+
},
|
|
20
|
+
100: {
|
|
21
|
+
transform: [{ scale: 1 }],
|
|
22
|
+
easing: Easing.elastic(1.2),
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const logoKeyframe = new Keyframe({
|
|
27
|
+
0: {
|
|
28
|
+
opacity: 0,
|
|
29
|
+
},
|
|
30
|
+
60: {
|
|
31
|
+
transform: [{ scale: 1.2 }],
|
|
32
|
+
opacity: 0,
|
|
33
|
+
easing: Easing.elastic(1.2),
|
|
34
|
+
},
|
|
35
|
+
100: {
|
|
36
|
+
transform: [{ scale: 1 }],
|
|
37
|
+
opacity: 1,
|
|
38
|
+
easing: Easing.elastic(1.2),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const glowKeyframe = new Keyframe({
|
|
43
|
+
0: {
|
|
44
|
+
transform: [{ rotateZ: '-180deg' }, { scale: 0.8 }],
|
|
45
|
+
opacity: 0,
|
|
46
|
+
},
|
|
47
|
+
[DURATION / 1000]: {
|
|
48
|
+
transform: [{ rotateZ: '0deg' }, { scale: 1 }],
|
|
49
|
+
opacity: 1,
|
|
50
|
+
easing: Easing.elastic(0.7),
|
|
51
|
+
},
|
|
52
|
+
100: {
|
|
53
|
+
transform: [{ rotateZ: '7200deg' }],
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export function AnimatedIcon() {
|
|
58
|
+
return (
|
|
59
|
+
<View style={styles.iconContainer}>
|
|
60
|
+
<Animated.View entering={glowKeyframe.duration(60 * 1000 * 4)} style={styles.glow}>
|
|
61
|
+
<Image style={styles.glow} source={require('@/assets/images/logo-glow.png')} />
|
|
62
|
+
</Animated.View>
|
|
63
|
+
|
|
64
|
+
<Animated.View style={styles.background} entering={keyframe.duration(DURATION)}>
|
|
65
|
+
<div className={classes.expoLogoBackground} />
|
|
66
|
+
</Animated.View>
|
|
67
|
+
|
|
68
|
+
<Animated.View style={styles.imageContainer} entering={logoKeyframe.duration(DURATION)}>
|
|
69
|
+
<Image style={styles.image} source={require('@/assets/images/expo-logo.png')} />
|
|
70
|
+
</Animated.View>
|
|
71
|
+
</View>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const styles = StyleSheet.create({
|
|
76
|
+
container: {
|
|
77
|
+
alignItems: 'center',
|
|
78
|
+
width: '100%',
|
|
79
|
+
zIndex: 1000,
|
|
80
|
+
position: 'absolute',
|
|
81
|
+
top: 128 / 2 + 138,
|
|
82
|
+
},
|
|
83
|
+
imageContainer: {
|
|
84
|
+
justifyContent: 'center',
|
|
85
|
+
alignItems: 'center',
|
|
86
|
+
},
|
|
87
|
+
glow: {
|
|
88
|
+
width: 201,
|
|
89
|
+
height: 201,
|
|
90
|
+
position: 'absolute',
|
|
91
|
+
},
|
|
92
|
+
iconContainer: {
|
|
93
|
+
justifyContent: 'center',
|
|
94
|
+
alignItems: 'center',
|
|
95
|
+
width: 128,
|
|
96
|
+
height: 128,
|
|
97
|
+
},
|
|
98
|
+
image: {
|
|
99
|
+
position: 'absolute',
|
|
100
|
+
width: 76,
|
|
101
|
+
height: 71,
|
|
102
|
+
},
|
|
103
|
+
background: {
|
|
104
|
+
width: 128,
|
|
105
|
+
height: 128,
|
|
106
|
+
position: 'absolute',
|
|
107
|
+
},
|
|
108
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { NativeTabs } from 'expo-router/unstable-native-tabs';
|
|
2
|
+
import { useColorScheme } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { Colors } from '@/constants/theme';
|
|
5
|
+
|
|
6
|
+
export default function AppTabs() {
|
|
7
|
+
const scheme = useColorScheme();
|
|
8
|
+
const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<NativeTabs
|
|
12
|
+
backgroundColor={colors.background}
|
|
13
|
+
indicatorColor={colors.backgroundElement}
|
|
14
|
+
labelStyle={{ selected: { color: colors.text } }}>
|
|
15
|
+
<NativeTabs.Trigger name="index">
|
|
16
|
+
<NativeTabs.Trigger.Label>Home</NativeTabs.Trigger.Label>
|
|
17
|
+
<NativeTabs.Trigger.Icon
|
|
18
|
+
src={require('@/assets/images/tabIcons/home.png')}
|
|
19
|
+
renderingMode="template"
|
|
20
|
+
/>
|
|
21
|
+
</NativeTabs.Trigger>
|
|
22
|
+
|
|
23
|
+
<NativeTabs.Trigger name="explore">
|
|
24
|
+
<NativeTabs.Trigger.Label>Explore</NativeTabs.Trigger.Label>
|
|
25
|
+
<NativeTabs.Trigger.Icon
|
|
26
|
+
src={require('@/assets/images/tabIcons/explore.png')}
|
|
27
|
+
renderingMode="template"
|
|
28
|
+
/>
|
|
29
|
+
</NativeTabs.Trigger>
|
|
30
|
+
</NativeTabs>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Tabs,
|
|
3
|
+
TabList,
|
|
4
|
+
TabTrigger,
|
|
5
|
+
TabSlot,
|
|
6
|
+
TabTriggerSlotProps,
|
|
7
|
+
TabListProps,
|
|
8
|
+
} from 'expo-router/ui';
|
|
9
|
+
import { SymbolView } from 'expo-symbols';
|
|
10
|
+
import { Pressable, useColorScheme, View, StyleSheet } from 'react-native';
|
|
11
|
+
|
|
12
|
+
import { ExternalLink } from './external-link';
|
|
13
|
+
import { ThemedText } from './themed-text';
|
|
14
|
+
import { ThemedView } from './themed-view';
|
|
15
|
+
|
|
16
|
+
import { Colors, MaxContentWidth, Spacing } from '@/constants/theme';
|
|
17
|
+
|
|
18
|
+
export default function AppTabs() {
|
|
19
|
+
return (
|
|
20
|
+
<Tabs>
|
|
21
|
+
<TabSlot style={{ height: '100%' }} />
|
|
22
|
+
<TabList asChild>
|
|
23
|
+
<CustomTabList>
|
|
24
|
+
<TabTrigger name="home" href="/" asChild>
|
|
25
|
+
<TabButton>Home</TabButton>
|
|
26
|
+
</TabTrigger>
|
|
27
|
+
<TabTrigger name="explore" href="/explore" asChild>
|
|
28
|
+
<TabButton>Explore</TabButton>
|
|
29
|
+
</TabTrigger>
|
|
30
|
+
</CustomTabList>
|
|
31
|
+
</TabList>
|
|
32
|
+
</Tabs>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function TabButton({ children, isFocused, ...props }: TabTriggerSlotProps) {
|
|
37
|
+
return (
|
|
38
|
+
<Pressable {...props} style={({ pressed }) => pressed && styles.pressed}>
|
|
39
|
+
<ThemedView
|
|
40
|
+
type={isFocused ? 'backgroundSelected' : 'backgroundElement'}
|
|
41
|
+
style={styles.tabButtonView}>
|
|
42
|
+
<ThemedText type="small" themeColor={isFocused ? 'text' : 'textSecondary'}>
|
|
43
|
+
{children}
|
|
44
|
+
</ThemedText>
|
|
45
|
+
</ThemedView>
|
|
46
|
+
</Pressable>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function CustomTabList(props: TabListProps) {
|
|
51
|
+
const scheme = useColorScheme();
|
|
52
|
+
const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<View {...props} style={styles.tabListContainer}>
|
|
56
|
+
<ThemedView type="backgroundElement" style={styles.innerContainer}>
|
|
57
|
+
<ThemedText type="smallBold" style={styles.brandText}>
|
|
58
|
+
Expo Starter
|
|
59
|
+
</ThemedText>
|
|
60
|
+
|
|
61
|
+
{props.children}
|
|
62
|
+
|
|
63
|
+
<ExternalLink href="https://docs.expo.dev" asChild>
|
|
64
|
+
<Pressable style={styles.externalPressable}>
|
|
65
|
+
<ThemedText type="link">Docs</ThemedText>
|
|
66
|
+
<SymbolView
|
|
67
|
+
tintColor={colors.text}
|
|
68
|
+
name={{ ios: 'arrow.up.right.square', web: 'link' }}
|
|
69
|
+
size={12}
|
|
70
|
+
/>
|
|
71
|
+
</Pressable>
|
|
72
|
+
</ExternalLink>
|
|
73
|
+
</ThemedView>
|
|
74
|
+
</View>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const styles = StyleSheet.create({
|
|
79
|
+
tabListContainer: {
|
|
80
|
+
position: 'absolute',
|
|
81
|
+
width: '100%',
|
|
82
|
+
padding: Spacing.three,
|
|
83
|
+
justifyContent: 'center',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
flexDirection: 'row',
|
|
86
|
+
},
|
|
87
|
+
innerContainer: {
|
|
88
|
+
paddingVertical: Spacing.two,
|
|
89
|
+
paddingHorizontal: Spacing.five,
|
|
90
|
+
borderRadius: Spacing.five,
|
|
91
|
+
flexDirection: 'row',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
flexGrow: 1,
|
|
94
|
+
gap: Spacing.two,
|
|
95
|
+
maxWidth: MaxContentWidth,
|
|
96
|
+
},
|
|
97
|
+
brandText: {
|
|
98
|
+
marginRight: 'auto',
|
|
99
|
+
},
|
|
100
|
+
pressed: {
|
|
101
|
+
opacity: 0.7,
|
|
102
|
+
},
|
|
103
|
+
tabButtonView: {
|
|
104
|
+
paddingVertical: Spacing.one,
|
|
105
|
+
paddingHorizontal: Spacing.three,
|
|
106
|
+
borderRadius: Spacing.three,
|
|
107
|
+
},
|
|
108
|
+
externalPressable: {
|
|
109
|
+
flexDirection: 'row',
|
|
110
|
+
justifyContent: 'center',
|
|
111
|
+
alignItems: 'center',
|
|
112
|
+
gap: Spacing.one,
|
|
113
|
+
marginLeft: Spacing.three,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Href, Link } from 'expo-router';
|
|
2
|
+
import { openBrowserAsync, WebBrowserPresentationStyle } from 'expo-web-browser';
|
|
3
|
+
import { type ComponentProps } from 'react';
|
|
4
|
+
|
|
5
|
+
type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: Href & string };
|
|
6
|
+
|
|
7
|
+
export function ExternalLink({ href, ...rest }: Props) {
|
|
8
|
+
return (
|
|
9
|
+
<Link
|
|
10
|
+
target="_blank"
|
|
11
|
+
{...rest}
|
|
12
|
+
href={href}
|
|
13
|
+
onPress={async (event) => {
|
|
14
|
+
if (process.env.EXPO_OS !== 'web') {
|
|
15
|
+
// Prevent the default behavior of linking to the default browser on native.
|
|
16
|
+
event.preventDefault();
|
|
17
|
+
// Open the link in an in-app browser.
|
|
18
|
+
await openBrowserAsync(href, {
|
|
19
|
+
presentationStyle: WebBrowserPresentationStyle.AUTOMATIC,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { ThemedText } from './themed-text';
|
|
5
|
+
import { ThemedView } from './themed-view';
|
|
6
|
+
|
|
7
|
+
import { Spacing } from '@/constants/theme';
|
|
8
|
+
|
|
9
|
+
type HintRowProps = {
|
|
10
|
+
title?: string;
|
|
11
|
+
hint?: ReactNode;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function HintRow({ title = 'Try editing', hint = 'app/index.tsx' }: HintRowProps) {
|
|
15
|
+
return (
|
|
16
|
+
<View style={styles.stepRow}>
|
|
17
|
+
<ThemedText type="small">{title}</ThemedText>
|
|
18
|
+
<ThemedView type="backgroundSelected" style={styles.codeSnippet}>
|
|
19
|
+
<ThemedText themeColor="textSecondary">{hint}</ThemedText>
|
|
20
|
+
</ThemedView>
|
|
21
|
+
</View>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const styles = StyleSheet.create({
|
|
26
|
+
stepRow: {
|
|
27
|
+
flexDirection: 'row',
|
|
28
|
+
justifyContent: 'space-between',
|
|
29
|
+
},
|
|
30
|
+
codeSnippet: {
|
|
31
|
+
borderRadius: Spacing.two,
|
|
32
|
+
paddingVertical: Spacing.half,
|
|
33
|
+
paddingHorizontal: Spacing.two,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Platform, StyleSheet, Text, type TextProps } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { Fonts, ThemeColor } from '@/constants/theme';
|
|
4
|
+
import { useTheme } from '@/hooks/use-theme';
|
|
5
|
+
|
|
6
|
+
export type ThemedTextProps = TextProps & {
|
|
7
|
+
type?: 'default' | 'title' | 'small' | 'smallBold' | 'subtitle' | 'link' | 'linkPrimary' | 'code';
|
|
8
|
+
themeColor?: ThemeColor;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function ThemedText({ style, type = 'default', themeColor, ...rest }: ThemedTextProps) {
|
|
12
|
+
const theme = useTheme();
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Text
|
|
16
|
+
style={[
|
|
17
|
+
{ color: theme[themeColor ?? 'text'] },
|
|
18
|
+
type === 'default' && styles.default,
|
|
19
|
+
type === 'title' && styles.title,
|
|
20
|
+
type === 'small' && styles.small,
|
|
21
|
+
type === 'smallBold' && styles.smallBold,
|
|
22
|
+
type === 'subtitle' && styles.subtitle,
|
|
23
|
+
type === 'link' && styles.link,
|
|
24
|
+
type === 'linkPrimary' && styles.linkPrimary,
|
|
25
|
+
type === 'code' && styles.code,
|
|
26
|
+
style,
|
|
27
|
+
]}
|
|
28
|
+
{...rest}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const styles = StyleSheet.create({
|
|
34
|
+
small: {
|
|
35
|
+
fontSize: 14,
|
|
36
|
+
lineHeight: 20,
|
|
37
|
+
fontWeight: 500,
|
|
38
|
+
},
|
|
39
|
+
smallBold: {
|
|
40
|
+
fontSize: 14,
|
|
41
|
+
lineHeight: 20,
|
|
42
|
+
fontWeight: 700,
|
|
43
|
+
},
|
|
44
|
+
default: {
|
|
45
|
+
fontSize: 16,
|
|
46
|
+
lineHeight: 24,
|
|
47
|
+
fontWeight: 500,
|
|
48
|
+
},
|
|
49
|
+
title: {
|
|
50
|
+
fontSize: 48,
|
|
51
|
+
fontWeight: 600,
|
|
52
|
+
lineHeight: 52,
|
|
53
|
+
},
|
|
54
|
+
subtitle: {
|
|
55
|
+
fontSize: 32,
|
|
56
|
+
lineHeight: 44,
|
|
57
|
+
fontWeight: 600,
|
|
58
|
+
},
|
|
59
|
+
link: {
|
|
60
|
+
lineHeight: 30,
|
|
61
|
+
fontSize: 14,
|
|
62
|
+
},
|
|
63
|
+
linkPrimary: {
|
|
64
|
+
lineHeight: 30,
|
|
65
|
+
fontSize: 14,
|
|
66
|
+
color: '#3c87f7',
|
|
67
|
+
},
|
|
68
|
+
code: {
|
|
69
|
+
fontFamily: Fonts.mono,
|
|
70
|
+
fontWeight: Platform.select({ android: 700 }) ?? 500,
|
|
71
|
+
fontSize: 12,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { View, type ViewProps } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { ThemeColor } from '@/constants/theme';
|
|
4
|
+
import { useTheme } from '@/hooks/use-theme';
|
|
5
|
+
|
|
6
|
+
export type ThemedViewProps = ViewProps & {
|
|
7
|
+
lightColor?: string;
|
|
8
|
+
darkColor?: string;
|
|
9
|
+
type?: ThemeColor;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function ThemedView({ style, lightColor, darkColor, type, ...otherProps }: ThemedViewProps) {
|
|
13
|
+
const theme = useTheme();
|
|
14
|
+
|
|
15
|
+
return <View style={[{ backgroundColor: theme[type ?? 'background'] }, style]} {...otherProps} />;
|
|
16
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { SymbolView } from 'expo-symbols';
|
|
2
|
+
import { PropsWithChildren, useState } from 'react';
|
|
3
|
+
import { Pressable, StyleSheet } from 'react-native';
|
|
4
|
+
import Animated, { FadeIn } from 'react-native-reanimated';
|
|
5
|
+
|
|
6
|
+
import { ThemedText } from '@/components/themed-text';
|
|
7
|
+
import { ThemedView } from '@/components/themed-view';
|
|
8
|
+
import { Spacing } from '@/constants/theme';
|
|
9
|
+
import { useTheme } from '@/hooks/use-theme';
|
|
10
|
+
|
|
11
|
+
export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
|
|
12
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
13
|
+
const theme = useTheme();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<ThemedView>
|
|
17
|
+
<Pressable
|
|
18
|
+
style={({ pressed }) => [styles.heading, pressed && styles.pressedHeading]}
|
|
19
|
+
onPress={() => setIsOpen((value) => !value)}>
|
|
20
|
+
<ThemedView type="backgroundElement" style={styles.button}>
|
|
21
|
+
<SymbolView
|
|
22
|
+
name={{ ios: 'chevron.right', android: 'chevron_right', web: 'chevron_right' }}
|
|
23
|
+
size={14}
|
|
24
|
+
weight="bold"
|
|
25
|
+
tintColor={theme.text}
|
|
26
|
+
style={{ transform: [{ rotate: isOpen ? '-90deg' : '90deg' }] }}
|
|
27
|
+
/>
|
|
28
|
+
</ThemedView>
|
|
29
|
+
|
|
30
|
+
<ThemedText type="small">{title}</ThemedText>
|
|
31
|
+
</Pressable>
|
|
32
|
+
{isOpen && (
|
|
33
|
+
<Animated.View entering={FadeIn.duration(200)}>
|
|
34
|
+
<ThemedView type="backgroundElement" style={styles.content}>
|
|
35
|
+
{children}
|
|
36
|
+
</ThemedView>
|
|
37
|
+
</Animated.View>
|
|
38
|
+
)}
|
|
39
|
+
</ThemedView>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const styles = StyleSheet.create({
|
|
44
|
+
heading: {
|
|
45
|
+
flexDirection: 'row',
|
|
46
|
+
alignItems: 'center',
|
|
47
|
+
gap: Spacing.two,
|
|
48
|
+
},
|
|
49
|
+
pressedHeading: {
|
|
50
|
+
opacity: 0.7,
|
|
51
|
+
},
|
|
52
|
+
button: {
|
|
53
|
+
width: Spacing.four,
|
|
54
|
+
height: Spacing.four,
|
|
55
|
+
borderRadius: 12,
|
|
56
|
+
justifyContent: 'center',
|
|
57
|
+
alignItems: 'center',
|
|
58
|
+
},
|
|
59
|
+
content: {
|
|
60
|
+
marginTop: Spacing.three,
|
|
61
|
+
borderRadius: Spacing.three,
|
|
62
|
+
marginLeft: Spacing.four,
|
|
63
|
+
padding: Spacing.four,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { version } from 'expo/package.json';
|
|
2
|
+
import { Image } from 'expo-image';
|
|
3
|
+
import { useColorScheme, StyleSheet } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { ThemedText } from './themed-text';
|
|
6
|
+
import { ThemedView } from './themed-view';
|
|
7
|
+
|
|
8
|
+
import { Spacing } from '@/constants/theme';
|
|
9
|
+
|
|
10
|
+
export function WebBadge() {
|
|
11
|
+
const scheme = useColorScheme();
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<ThemedView style={styles.container}>
|
|
15
|
+
<ThemedText type="code" themeColor="textSecondary" style={styles.versionText}>
|
|
16
|
+
v{version}
|
|
17
|
+
</ThemedText>
|
|
18
|
+
<Image
|
|
19
|
+
source={
|
|
20
|
+
scheme === 'dark'
|
|
21
|
+
? require('@/assets/images/expo-badge-white.png')
|
|
22
|
+
: require('@/assets/images/expo-badge.png')
|
|
23
|
+
}
|
|
24
|
+
style={styles.badgeImage}
|
|
25
|
+
/>
|
|
26
|
+
</ThemedView>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const styles = StyleSheet.create({
|
|
31
|
+
container: {
|
|
32
|
+
padding: Spacing.five,
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
gap: Spacing.two,
|
|
35
|
+
},
|
|
36
|
+
versionText: {
|
|
37
|
+
textAlign: 'center',
|
|
38
|
+
},
|
|
39
|
+
badgeImage: {
|
|
40
|
+
width: 123,
|
|
41
|
+
aspectRatio: 123 / 24,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Below are the colors that are used in the app. The colors are defined in the light and dark mode.
|
|
3
|
+
* There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import '@/global.css';
|
|
7
|
+
|
|
8
|
+
import { Platform } from 'react-native';
|
|
9
|
+
|
|
10
|
+
export const Colors = {
|
|
11
|
+
light: {
|
|
12
|
+
text: '#000000',
|
|
13
|
+
background: '#ffffff',
|
|
14
|
+
backgroundElement: '#F0F0F3',
|
|
15
|
+
backgroundSelected: '#E0E1E6',
|
|
16
|
+
textSecondary: '#60646C',
|
|
17
|
+
},
|
|
18
|
+
dark: {
|
|
19
|
+
text: '#ffffff',
|
|
20
|
+
background: '#000000',
|
|
21
|
+
backgroundElement: '#212225',
|
|
22
|
+
backgroundSelected: '#2E3135',
|
|
23
|
+
textSecondary: '#B0B4BA',
|
|
24
|
+
},
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
27
|
+
export type ThemeColor = keyof typeof Colors.light & keyof typeof Colors.dark;
|
|
28
|
+
|
|
29
|
+
export const Fonts = Platform.select({
|
|
30
|
+
ios: {
|
|
31
|
+
/** iOS `UIFontDescriptorSystemDesignDefault` */
|
|
32
|
+
sans: 'system-ui',
|
|
33
|
+
/** iOS `UIFontDescriptorSystemDesignSerif` */
|
|
34
|
+
serif: 'ui-serif',
|
|
35
|
+
/** iOS `UIFontDescriptorSystemDesignRounded` */
|
|
36
|
+
rounded: 'ui-rounded',
|
|
37
|
+
/** iOS `UIFontDescriptorSystemDesignMonospaced` */
|
|
38
|
+
mono: 'ui-monospace',
|
|
39
|
+
},
|
|
40
|
+
default: {
|
|
41
|
+
sans: 'normal',
|
|
42
|
+
serif: 'serif',
|
|
43
|
+
rounded: 'normal',
|
|
44
|
+
mono: 'monospace',
|
|
45
|
+
},
|
|
46
|
+
web: {
|
|
47
|
+
sans: 'var(--font-display)',
|
|
48
|
+
serif: 'var(--font-serif)',
|
|
49
|
+
rounded: 'var(--font-rounded)',
|
|
50
|
+
mono: 'var(--font-mono)',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const Spacing = {
|
|
55
|
+
half: 2,
|
|
56
|
+
one: 4,
|
|
57
|
+
two: 8,
|
|
58
|
+
three: 16,
|
|
59
|
+
four: 24,
|
|
60
|
+
five: 32,
|
|
61
|
+
six: 64,
|
|
62
|
+
} as const;
|
|
63
|
+
|
|
64
|
+
export const BottomTabInset = Platform.select({ ios: 50, android: 80 }) ?? 0;
|
|
65
|
+
export const MaxContentWidth = 800;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--font-display:
|
|
3
|
+
Spline Sans, Inter, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji,
|
|
4
|
+
Segoe UI Symbol, Noto Color Emoji;
|
|
5
|
+
--font-mono:
|
|
6
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
|
|
7
|
+
--font-rounded: 'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif;
|
|
8
|
+
--font-serif: Georgia, 'Times New Roman', serif;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useColorScheme } from 'react-native';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useColorScheme as useRNColorScheme } from 'react-native';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* To support static rendering, this value needs to be re-calculated on the client side for web
|
|
6
|
+
*/
|
|
7
|
+
export function useColorScheme() {
|
|
8
|
+
const [hasHydrated, setHasHydrated] = useState(false);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
setHasHydrated(true);
|
|
12
|
+
}, []);
|
|
13
|
+
|
|
14
|
+
const colorScheme = useRNColorScheme();
|
|
15
|
+
|
|
16
|
+
if (hasHydrated) {
|
|
17
|
+
return colorScheme;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return 'light';
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learn more about light and dark modes:
|
|
3
|
+
* https://docs.expo.dev/guides/color-schemes/
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Colors } from '@/constants/theme';
|
|
7
|
+
import { useColorScheme } from '@/hooks/use-color-scheme';
|
|
8
|
+
|
|
9
|
+
export function useTheme() {
|
|
10
|
+
const scheme = useColorScheme();
|
|
11
|
+
const theme = scheme === 'unspecified' ? 'light' : scheme;
|
|
12
|
+
|
|
13
|
+
return Colors[theme];
|
|
14
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Feather } from '@expo/vector-icons';
|
|
2
|
+
import { Text, View, StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export const BackButton = ({ onPress }: { onPress: () => void }) => {
|
|
5
|
+
return (
|
|
6
|
+
<View style={styles.backButton}>
|
|
7
|
+
<Feather name="chevron-left" size={16} color="#007AFF" />
|
|
8
|
+
<Text style={styles.backButtonText} onPress={onPress}>
|
|
9
|
+
Back
|
|
10
|
+
</Text>
|
|
11
|
+
</View>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
const styles = StyleSheet.create({
|
|
15
|
+
backButton: {
|
|
16
|
+
flexDirection: 'row',
|
|
17
|
+
paddingLeft: 20,
|
|
18
|
+
},
|
|
19
|
+
backButtonText: {
|
|
20
|
+
color: '#007AFF',
|
|
21
|
+
marginLeft: 4,
|
|
22
|
+
},
|
|
23
|
+
});
|