lovdacn 0.0.1 → 0.0.3

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.
Files changed (156) hide show
  1. package/README.md +72 -106
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +224 -0
  4. package/package.json +41 -63
  5. package/templates/nativewind/.vscode/extensions.json +1 -0
  6. package/templates/nativewind/.vscode/settings.json +7 -0
  7. package/templates/nativewind/AGENTS.md +3 -0
  8. package/templates/nativewind/CLAUDE.md +1 -0
  9. package/{LICENSE → templates/nativewind/LICENSE} +21 -21
  10. package/templates/nativewind/README.md +56 -0
  11. package/templates/nativewind/app.json +43 -0
  12. package/templates/nativewind/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
  13. package/templates/nativewind/assets/expo.icon/Assets/grid.png +0 -0
  14. package/templates/nativewind/assets/expo.icon/icon.json +40 -0
  15. package/templates/nativewind/assets/images/android-icon-background.png +0 -0
  16. package/templates/nativewind/assets/images/android-icon-foreground.png +0 -0
  17. package/templates/nativewind/assets/images/android-icon-monochrome.png +0 -0
  18. package/templates/nativewind/assets/images/expo-badge-white.png +0 -0
  19. package/templates/nativewind/assets/images/expo-badge.png +0 -0
  20. package/templates/nativewind/assets/images/expo-logo.png +0 -0
  21. package/templates/nativewind/assets/images/favicon.png +0 -0
  22. package/templates/nativewind/assets/images/icon.png +0 -0
  23. package/templates/nativewind/assets/images/logo-glow.png +0 -0
  24. package/templates/nativewind/assets/images/react-logo.png +0 -0
  25. package/templates/nativewind/assets/images/react-logo@2x.png +0 -0
  26. package/templates/nativewind/assets/images/react-logo@3x.png +0 -0
  27. package/templates/nativewind/assets/images/splash-icon.png +0 -0
  28. package/templates/nativewind/assets/images/tabIcons/explore.png +0 -0
  29. package/templates/nativewind/assets/images/tabIcons/explore@2x.png +0 -0
  30. package/templates/nativewind/assets/images/tabIcons/explore@3x.png +0 -0
  31. package/templates/nativewind/assets/images/tabIcons/home.png +0 -0
  32. package/templates/nativewind/assets/images/tabIcons/home@2x.png +0 -0
  33. package/templates/nativewind/assets/images/tabIcons/home@3x.png +0 -0
  34. package/templates/nativewind/assets/images/tutorial-web.png +0 -0
  35. package/templates/nativewind/babel.config.js +9 -0
  36. package/templates/nativewind/expo-env.d.ts +3 -0
  37. package/templates/nativewind/lvcn.json +16 -0
  38. package/templates/nativewind/metro.config.js +6 -0
  39. package/templates/nativewind/nativewind-env.d.ts +3 -0
  40. package/templates/nativewind/package.json +55 -0
  41. package/templates/nativewind/postcss.config.js +6 -0
  42. package/templates/nativewind/scripts/reset-project.js +114 -0
  43. package/templates/nativewind/src/app/_layout.tsx +25 -0
  44. package/templates/nativewind/src/app/explore.tsx +180 -0
  45. package/templates/nativewind/src/app/index.tsx +12 -0
  46. package/templates/nativewind/src/components/animated-icon.module.css +6 -0
  47. package/templates/nativewind/src/components/animated-icon.tsx +148 -0
  48. package/templates/nativewind/src/components/animated-icon.web.tsx +108 -0
  49. package/templates/nativewind/src/components/app-tabs.tsx +32 -0
  50. package/templates/nativewind/src/components/app-tabs.web.tsx +115 -0
  51. package/templates/nativewind/src/components/external-link.tsx +25 -0
  52. package/templates/nativewind/src/components/hint-row.tsx +35 -0
  53. package/templates/nativewind/src/components/themed-text.tsx +73 -0
  54. package/templates/nativewind/src/components/themed-view.tsx +16 -0
  55. package/templates/nativewind/src/components/ui/button.tsx +106 -0
  56. package/templates/nativewind/src/components/ui/collapsible.tsx +65 -0
  57. package/templates/nativewind/src/components/ui/text.tsx +89 -0
  58. package/templates/nativewind/src/components/web-badge.tsx +43 -0
  59. package/templates/nativewind/src/constants/theme.ts +65 -0
  60. package/templates/nativewind/src/global.css +13 -0
  61. package/templates/nativewind/src/hooks/use-color-scheme.ts +1 -0
  62. package/templates/nativewind/src/hooks/use-color-scheme.web.ts +21 -0
  63. package/templates/nativewind/src/hooks/use-theme.ts +14 -0
  64. package/templates/nativewind/tailwind.config.js +86 -0
  65. package/templates/nativewind/tsconfig.json +21 -0
  66. package/templates/uniwind/.claude/settings.json +5 -0
  67. package/templates/uniwind/.vscode/extensions.json +1 -0
  68. package/templates/uniwind/.vscode/settings.json +7 -0
  69. package/templates/uniwind/AGENTS.md +3 -0
  70. package/templates/uniwind/CLAUDE.md +1 -0
  71. package/templates/uniwind/LICENSE +21 -0
  72. package/templates/uniwind/README.md +56 -0
  73. package/templates/uniwind/app.json +42 -0
  74. package/templates/uniwind/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
  75. package/templates/uniwind/assets/expo.icon/Assets/grid.png +0 -0
  76. package/templates/uniwind/assets/expo.icon/icon.json +40 -0
  77. package/templates/uniwind/assets/images/android-icon-background.png +0 -0
  78. package/templates/uniwind/assets/images/android-icon-foreground.png +0 -0
  79. package/templates/uniwind/assets/images/android-icon-monochrome.png +0 -0
  80. package/templates/uniwind/assets/images/expo-badge-white.png +0 -0
  81. package/templates/uniwind/assets/images/expo-badge.png +0 -0
  82. package/templates/uniwind/assets/images/expo-logo.png +0 -0
  83. package/templates/uniwind/assets/images/favicon.png +0 -0
  84. package/templates/uniwind/assets/images/icon.png +0 -0
  85. package/templates/uniwind/assets/images/logo-glow.png +0 -0
  86. package/templates/uniwind/assets/images/react-logo.png +0 -0
  87. package/templates/uniwind/assets/images/react-logo@2x.png +0 -0
  88. package/templates/uniwind/assets/images/react-logo@3x.png +0 -0
  89. package/templates/uniwind/assets/images/splash-icon.png +0 -0
  90. package/templates/uniwind/assets/images/tabIcons/explore.png +0 -0
  91. package/templates/uniwind/assets/images/tabIcons/explore@2x.png +0 -0
  92. package/templates/uniwind/assets/images/tabIcons/explore@3x.png +0 -0
  93. package/templates/uniwind/assets/images/tabIcons/home.png +0 -0
  94. package/templates/uniwind/assets/images/tabIcons/home@2x.png +0 -0
  95. package/templates/uniwind/assets/images/tabIcons/home@3x.png +0 -0
  96. package/templates/uniwind/assets/images/tutorial-web.png +0 -0
  97. package/templates/uniwind/expo-env.d.ts +3 -0
  98. package/templates/uniwind/lvcn.json +16 -0
  99. package/templates/uniwind/metro.config.js +14 -0
  100. package/templates/uniwind/package.json +46 -0
  101. package/templates/uniwind/scripts/reset-project.js +114 -0
  102. package/templates/uniwind/src/app/_layout.tsx +23 -0
  103. package/templates/uniwind/src/app/explore.tsx +180 -0
  104. package/templates/uniwind/src/app/index.tsx +98 -0
  105. package/templates/uniwind/src/components/animated-icon.module.css +6 -0
  106. package/templates/uniwind/src/components/animated-icon.tsx +148 -0
  107. package/templates/uniwind/src/components/animated-icon.web.tsx +108 -0
  108. package/templates/uniwind/src/components/app-tabs.tsx +32 -0
  109. package/templates/uniwind/src/components/app-tabs.web.tsx +115 -0
  110. package/templates/uniwind/src/components/external-link.tsx +25 -0
  111. package/templates/uniwind/src/components/hint-row.tsx +35 -0
  112. package/templates/uniwind/src/components/themed-text.tsx +73 -0
  113. package/templates/uniwind/src/components/themed-view.tsx +16 -0
  114. package/templates/uniwind/src/components/ui/collapsible.tsx +65 -0
  115. package/templates/uniwind/src/components/web-badge.tsx +43 -0
  116. package/templates/uniwind/src/constants/theme.ts +65 -0
  117. package/templates/uniwind/src/global.css +12 -0
  118. package/templates/uniwind/src/hooks/use-color-scheme.ts +1 -0
  119. package/templates/uniwind/src/hooks/use-color-scheme.web.ts +21 -0
  120. package/templates/uniwind/src/hooks/use-theme.ts +14 -0
  121. package/templates/uniwind/src/uniwind-types.d.ts +10 -0
  122. package/templates/uniwind/tsconfig.json +20 -0
  123. package/.changeset/config.json +0 -17
  124. package/.github/actions/setup/action.yml +0 -21
  125. package/.github/workflows/check.yml +0 -54
  126. package/.github/workflows/release.yml +0 -0
  127. package/.github/workflows/snapshot.yml +0 -24
  128. package/.prettierrc +0 -8
  129. package/.vscode/extensions.json +0 -6
  130. package/.vscode/settings.json +0 -46
  131. package/eslint.config.mjs +0 -118
  132. package/patches/@changesets__get-github-info@0.6.0.patch +0 -48
  133. package/scripts/copy-package-json.ts +0 -35
  134. package/src/bin.ts +0 -18
  135. package/src/cli.ts +0 -66
  136. package/src/contexts/cli-options.ts +0 -29
  137. package/src/project-manifest.ts +0 -370
  138. package/src/services/commands/add.ts +0 -128
  139. package/src/services/commands/doctor.ts +0 -287
  140. package/src/services/commands/init.ts +0 -94
  141. package/src/services/git.ts +0 -39
  142. package/src/services/package-manager.ts +0 -48
  143. package/src/services/project-config.ts +0 -295
  144. package/src/services/required-files-checker.ts +0 -375
  145. package/src/services/spinner.ts +0 -15
  146. package/src/services/template.ts +0 -223
  147. package/src/utils/retry-with.ts +0 -9
  148. package/src/utils/run-command.ts +0 -10
  149. package/test/Dummy.test.ts +0 -7
  150. package/tsconfig.base.json +0 -53
  151. package/tsconfig.json +0 -14
  152. package/tsconfig.scripts.json +0 -17
  153. package/tsconfig.src.json +0 -10
  154. package/tsconfig.test.json +0 -10
  155. package/tsup.config.ts +0 -9
  156. package/vitest.config.ts +0 -12
@@ -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,106 @@
1
+ import { TextClassContext } from '@/components/ui/text';
2
+ import { cn } from '@/lib/utils';
3
+ import { cva, type VariantProps } from 'class-variance-authority';
4
+ import { Platform, Pressable } from 'react-native';
5
+
6
+ const buttonVariants = cva(
7
+ cn(
8
+ 'group shrink-0 flex-row items-center justify-center gap-2 rounded-md shadow-none',
9
+ Platform.select({
10
+ web: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
11
+ })
12
+ ),
13
+ {
14
+ variants: {
15
+ variant: {
16
+ default: cn(
17
+ 'bg-primary active:bg-primary/90 shadow-sm shadow-black/5',
18
+ Platform.select({ web: 'hover:bg-primary/90' })
19
+ ),
20
+ destructive: cn(
21
+ 'bg-destructive active:bg-destructive/90 dark:bg-destructive/60 shadow-sm shadow-black/5',
22
+ Platform.select({
23
+ web: 'hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',
24
+ })
25
+ ),
26
+ outline: cn(
27
+ 'border-border bg-background active:bg-accent dark:bg-input/30 dark:border-input dark:active:bg-input/50 border shadow-sm shadow-black/5',
28
+ Platform.select({
29
+ web: 'hover:bg-accent dark:hover:bg-input/50',
30
+ })
31
+ ),
32
+ secondary: cn(
33
+ 'bg-secondary active:bg-secondary/80 shadow-sm shadow-black/5',
34
+ Platform.select({ web: 'hover:bg-secondary/80' })
35
+ ),
36
+ ghost: cn(
37
+ 'active:bg-accent dark:active:bg-accent/50',
38
+ Platform.select({ web: 'hover:bg-accent dark:hover:bg-accent/50' })
39
+ ),
40
+ link: '',
41
+ },
42
+ size: {
43
+ default: cn('h-10 px-4 py-2 sm:h-9', Platform.select({ web: 'has-[>svg]:px-3' })),
44
+ sm: cn('h-9 gap-1.5 rounded-md px-3 sm:h-8', Platform.select({ web: 'has-[>svg]:px-2.5' })),
45
+ lg: cn('h-11 rounded-md px-6 sm:h-10', Platform.select({ web: 'has-[>svg]:px-4' })),
46
+ icon: 'h-10 w-10 sm:h-9 sm:w-9',
47
+ },
48
+ },
49
+ defaultVariants: {
50
+ variant: 'default',
51
+ size: 'default',
52
+ },
53
+ }
54
+ );
55
+
56
+ const buttonTextVariants = cva(
57
+ cn(
58
+ 'text-foreground text-sm font-medium',
59
+ Platform.select({ web: 'pointer-events-none transition-colors' })
60
+ ),
61
+ {
62
+ variants: {
63
+ variant: {
64
+ default: 'text-primary-foreground',
65
+ destructive: 'text-white',
66
+ outline: cn(
67
+ 'group-active:text-accent-foreground',
68
+ Platform.select({ web: 'group-hover:text-accent-foreground' })
69
+ ),
70
+ secondary: 'text-secondary-foreground',
71
+ ghost: 'group-active:text-accent-foreground',
72
+ link: cn(
73
+ 'text-primary group-active:underline',
74
+ Platform.select({ web: 'underline-offset-4 hover:underline group-hover:underline' })
75
+ ),
76
+ },
77
+ size: {
78
+ default: '',
79
+ sm: '',
80
+ lg: '',
81
+ icon: '',
82
+ },
83
+ },
84
+ defaultVariants: {
85
+ variant: 'default',
86
+ size: 'default',
87
+ },
88
+ }
89
+ );
90
+
91
+ type ButtonProps = React.ComponentProps<typeof Pressable> & React.RefAttributes<typeof Pressable> & VariantProps<typeof buttonVariants>;
92
+
93
+ function Button({ className, variant, size, ...props }: ButtonProps) {
94
+ return (
95
+ <TextClassContext.Provider value={buttonTextVariants({ variant, size })}>
96
+ <Pressable
97
+ className={cn(props.disabled && 'opacity-50', buttonVariants({ variant, size }), className)}
98
+ role="button"
99
+ {...props}
100
+ />
101
+ </TextClassContext.Provider>
102
+ );
103
+ }
104
+
105
+ export { Button, buttonTextVariants, buttonVariants };
106
+ export type { ButtonProps };
@@ -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,89 @@
1
+ import { cn } from '@/lib/utils';
2
+ import { Slot } from '@rn-primitives/slot';
3
+ import { cva, type VariantProps } from 'class-variance-authority';
4
+ import * as React from 'react';
5
+ import { Platform, Text as RNText, type Role } from 'react-native';
6
+
7
+ const textVariants = cva(
8
+ cn(
9
+ 'text-foreground text-base',
10
+ Platform.select({
11
+ web: 'select-text',
12
+ })
13
+ ),
14
+ {
15
+ variants: {
16
+ variant: {
17
+ default: '',
18
+ h1: cn(
19
+ 'text-center text-4xl font-extrabold tracking-tight',
20
+ Platform.select({ web: 'scroll-m-20 text-balance' })
21
+ ),
22
+ h2: cn(
23
+ 'border-border border-b pb-2 text-3xl font-semibold tracking-tight',
24
+ Platform.select({ web: 'scroll-m-20 first:mt-0' })
25
+ ),
26
+ h3: cn('text-2xl font-semibold tracking-tight', Platform.select({ web: 'scroll-m-20' })),
27
+ h4: cn('text-xl font-semibold tracking-tight', Platform.select({ web: 'scroll-m-20' })),
28
+ p: 'mt-3 leading-7 sm:mt-6',
29
+ blockquote: 'mt-4 border-l-2 pl-3 italic sm:mt-6 sm:pl-6',
30
+ code: cn(
31
+ 'bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold'
32
+ ),
33
+ lead: 'text-muted-foreground text-xl',
34
+ large: 'text-lg font-semibold',
35
+ small: 'text-sm font-medium leading-none',
36
+ muted: 'text-muted-foreground text-sm',
37
+ },
38
+ },
39
+ defaultVariants: {
40
+ variant: 'default',
41
+ },
42
+ }
43
+ );
44
+
45
+ type TextVariantProps = VariantProps<typeof textVariants>;
46
+
47
+ type TextVariant = NonNullable<TextVariantProps['variant']>;
48
+
49
+ const ROLE: Partial<Record<TextVariant, Role>> = {
50
+ h1: 'heading',
51
+ h2: 'heading',
52
+ h3: 'heading',
53
+ h4: 'heading',
54
+ blockquote: Platform.select({ web: 'blockquote' as Role }),
55
+ code: Platform.select({ web: 'code' as Role }),
56
+ };
57
+
58
+ const ARIA_LEVEL: Partial<Record<TextVariant, string>> = {
59
+ h1: '1',
60
+ h2: '2',
61
+ h3: '3',
62
+ h4: '4',
63
+ };
64
+
65
+ const TextClassContext = React.createContext<string | undefined>(undefined);
66
+
67
+ function Text({
68
+ className,
69
+ asChild = false,
70
+ variant = 'default',
71
+ ...props
72
+ }: React.ComponentProps<typeof RNText> &
73
+ React.RefAttributes<typeof RNText> &
74
+ TextVariantProps & {
75
+ asChild?: boolean;
76
+ }) {
77
+ const textClass = React.useContext(TextClassContext);
78
+ const Component = asChild ? Slot : RNText;
79
+ return (
80
+ <Component
81
+ className={cn(textVariants({ variant }), textClass, className)}
82
+ role={variant ? ROLE[variant] : undefined}
83
+ aria-level={variant ? ARIA_LEVEL[variant] : undefined}
84
+ {...props}
85
+ />
86
+ );
87
+ }
88
+
89
+ export { Text, TextClassContext };
@@ -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,13 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --font-display:
7
+ Spline Sans, Inter, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji,
8
+ Segoe UI Symbol, Noto Color Emoji;
9
+ --font-mono:
10
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
11
+ --font-rounded: 'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif;
12
+ --font-serif: Georgia, 'Times New Roman', serif;
13
+ }
@@ -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,86 @@
1
+ const { hairlineWidth } = require("nativewind/theme");
2
+
3
+ /** @type {import('tailwindcss').Config} */
4
+ module.exports = {
5
+ darkMode: "class",
6
+ content: [
7
+ "./src/**/*.{js,jsx,ts,tsx}",
8
+ "./app/**/*.{js,jsx,ts,tsx}",
9
+ "./components/**/*.{js,jsx,ts,tsx}",
10
+ ],
11
+ presets: [require("nativewind/preset")],
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ border: "hsl(var(--border))",
16
+ input: "hsl(var(--input))",
17
+ ring: "hsl(var(--ring))",
18
+ background: "hsl(var(--background))",
19
+ foreground: "hsl(var(--foreground))",
20
+ primary: {
21
+ DEFAULT: "hsl(var(--primary))",
22
+ foreground: "hsl(var(--primary-foreground))",
23
+ },
24
+ secondary: {
25
+ DEFAULT: "hsl(var(--secondary))",
26
+ foreground: "hsl(var(--secondary-foreground))",
27
+ },
28
+ destructive: {
29
+ DEFAULT: "hsl(var(--destructive))",
30
+ foreground: "hsl(var(--destructive-foreground))",
31
+ },
32
+ muted: {
33
+ DEFAULT: "hsl(var(--muted))",
34
+ foreground: "hsl(var(--muted-foreground))",
35
+ },
36
+ accent: {
37
+ DEFAULT: "hsl(var(--accent))",
38
+ foreground: "hsl(var(--accent-foreground))",
39
+ },
40
+ popover: {
41
+ DEFAULT: "hsl(var(--popover))",
42
+ foreground: "hsl(var(--popover-foreground))",
43
+ },
44
+ card: {
45
+ DEFAULT: "hsl(var(--card))",
46
+ foreground: "hsl(var(--card-foreground))",
47
+ },
48
+ "chart-1": "hsl(var(--chart-1))",
49
+ "chart-2": "hsl(var(--chart-2))",
50
+ "chart-3": "hsl(var(--chart-3))",
51
+ "chart-4": "hsl(var(--chart-4))",
52
+ "chart-5": "hsl(var(--chart-5))",
53
+ },
54
+ borderRadius: {
55
+ "4xl": "min(calc(var(--radius) * 2.6), 32px)",
56
+ "3xl": "min(calc(var(--radius) * 2.2), 32px)",
57
+ "2xl": "min(calc(var(--radius) * 1.8), 28px)",
58
+ xl: "min(calc(var(--radius) * 1.4), 24px)",
59
+ lg: "min(var(--radius), 20px)",
60
+ md: "calc(var(--radius) * 0.8)",
61
+ sm: "calc(var(--radius) * 0.6)",
62
+ },
63
+ borderWidth: {
64
+ hairline: hairlineWidth(),
65
+ },
66
+ keyframes: {
67
+ "accordion-down": {
68
+ from: { height: "0" },
69
+ to: { height: "var(--radix-accordion-content-height)" },
70
+ },
71
+ "accordion-up": {
72
+ from: { height: "var(--radix-accordion-content-height)" },
73
+ to: { height: "0" },
74
+ },
75
+ },
76
+ animation: {
77
+ "accordion-down": "accordion-down 0.2s ease-out",
78
+ "accordion-up": "accordion-up 0.2s ease-out",
79
+ },
80
+ },
81
+ },
82
+ future: {
83
+ hoverOnlyWhenSupported: true,
84
+ },
85
+ plugins: [require("tailwindcss-animate")],
86
+ };
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "expo/tsconfig.base",
3
+ "compilerOptions": {
4
+ "strict": true,
5
+ "paths": {
6
+ "@/*": [
7
+ "./src/*"
8
+ ],
9
+ "@/assets/*": [
10
+ "./assets/*"
11
+ ]
12
+ }
13
+ },
14
+ "include": [
15
+ "**/*.ts",
16
+ "**/*.tsx",
17
+ ".expo/types/**/*.ts",
18
+ "expo-env.d.ts",
19
+ "nativewind-env.d.ts"
20
+ ]
21
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "enabledPlugins": {
3
+ "expo@claude-plugins-official": true
4
+ }
5
+ }
@@ -0,0 +1 @@
1
+ { "recommendations": ["expo.vscode-expo-tools"] }
@@ -0,0 +1,7 @@
1
+ {
2
+ "editor.codeActionsOnSave": {
3
+ "source.fixAll": "explicit",
4
+ "source.organizeImports": "explicit",
5
+ "source.sortMembers": "explicit"
6
+ }
7
+ }
@@ -0,0 +1,3 @@
1
+ # Expo HAS CHANGED
2
+
3
+ Read the exact versioned docs at https://docs.expo.dev/versions/v57.0.0/ before writing any code.
@@ -0,0 +1 @@
1
+ @AGENTS.md
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.