create-better-t-stack 2.8.4 → 2.9.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.
Files changed (62) hide show
  1. package/README.md +17 -16
  2. package/dist/index.js +5 -5
  3. package/package.json +1 -1
  4. package/templates/auth/native/unistyles/app/(drawer)/index.tsx.hbs +179 -0
  5. package/templates/auth/native/unistyles/components/sign-in.tsx.hbs +134 -0
  6. package/templates/auth/native/unistyles/components/sign-up.tsx.hbs +152 -0
  7. package/templates/frontend/native/unistyles/_gitignore +24 -0
  8. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx +34 -0
  9. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx +29 -0
  10. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx +29 -0
  11. package/templates/frontend/native/unistyles/app/(drawer)/_layout.tsx +59 -0
  12. package/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs +115 -0
  13. package/templates/frontend/native/unistyles/app/+html.tsx +48 -0
  14. package/templates/frontend/native/unistyles/app/+not-found.tsx +34 -0
  15. package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +77 -0
  16. package/templates/frontend/native/unistyles/app/modal.tsx +29 -0
  17. package/templates/frontend/native/unistyles/app.json +44 -0
  18. package/templates/frontend/native/unistyles/babel.config.js +20 -0
  19. package/templates/frontend/native/unistyles/breakpoints.ts +9 -0
  20. package/templates/frontend/native/unistyles/components/container.tsx +20 -0
  21. package/templates/frontend/native/unistyles/components/header-button.tsx +31 -0
  22. package/templates/frontend/native/unistyles/components/tabbar-icon.tsx +15 -0
  23. package/templates/frontend/native/unistyles/expo-env.d.ts +3 -0
  24. package/templates/frontend/native/unistyles/index.js +2 -0
  25. package/templates/frontend/native/unistyles/metro.config.js +20 -0
  26. package/templates/frontend/native/unistyles/package.json +47 -0
  27. package/templates/frontend/native/unistyles/theme.ts +35 -0
  28. package/templates/frontend/native/unistyles/tsconfig.json +12 -0
  29. package/templates/frontend/native/unistyles/unistyles.ts +27 -0
  30. package/templates/frontend/react/web-base/src/components/header.tsx.hbs +5 -6
  31. /package/templates/auth/native/{lib/auth-client.ts → native-base/lib/auth-client.ts.hbs} +0 -0
  32. /package/templates/auth/native/{app → nativewind/app}/(drawer)/index.tsx.hbs +0 -0
  33. /package/templates/auth/native/{components → nativewind/components}/sign-in.tsx.hbs +0 -0
  34. /package/templates/auth/native/{components → nativewind/components}/sign-up.tsx.hbs +0 -0
  35. /package/templates/frontend/native/{assets → native-base/assets}/adaptive-icon.png +0 -0
  36. /package/templates/frontend/native/{assets → native-base/assets}/favicon.png +0 -0
  37. /package/templates/frontend/native/{assets → native-base/assets}/icon.png +0 -0
  38. /package/templates/frontend/native/{assets → native-base/assets}/splash.png +0 -0
  39. /package/templates/frontend/native/{_gitignore → nativewind/_gitignore} +0 -0
  40. /package/templates/frontend/native/{app → nativewind/app}/(drawer)/(tabs)/_layout.tsx +0 -0
  41. /package/templates/frontend/native/{app → nativewind/app}/(drawer)/(tabs)/index.tsx +0 -0
  42. /package/templates/frontend/native/{app → nativewind/app}/(drawer)/(tabs)/two.tsx +0 -0
  43. /package/templates/frontend/native/{app → nativewind/app}/(drawer)/_layout.tsx +0 -0
  44. /package/templates/frontend/native/{app → nativewind/app}/(drawer)/index.tsx.hbs +0 -0
  45. /package/templates/frontend/native/{app → nativewind/app}/+html.tsx +0 -0
  46. /package/templates/frontend/native/{app → nativewind/app}/+not-found.tsx +0 -0
  47. /package/templates/frontend/native/{app → nativewind/app}/_layout.tsx.hbs +0 -0
  48. /package/templates/frontend/native/{app → nativewind/app}/modal.tsx +0 -0
  49. /package/templates/frontend/native/{app-env.d.ts → nativewind/app-env.d.ts} +0 -0
  50. /package/templates/frontend/native/{app.json → nativewind/app.json} +0 -0
  51. /package/templates/frontend/native/{babel.config.js → nativewind/babel.config.js} +0 -0
  52. /package/templates/frontend/native/{components → nativewind/components}/container.tsx +0 -0
  53. /package/templates/frontend/native/{components → nativewind/components}/header-button.tsx +0 -0
  54. /package/templates/frontend/native/{components → nativewind/components}/tabbar-icon.tsx +0 -0
  55. /package/templates/frontend/native/{global.css → nativewind/global.css} +0 -0
  56. /package/templates/frontend/native/{lib → nativewind/lib}/android-navigation-bar.tsx +0 -0
  57. /package/templates/frontend/native/{lib → nativewind/lib}/constants.ts +0 -0
  58. /package/templates/frontend/native/{lib → nativewind/lib}/use-color-scheme.ts +0 -0
  59. /package/templates/frontend/native/{metro.config.js → nativewind/metro.config.js} +0 -0
  60. /package/templates/frontend/native/{package.json → nativewind/package.json} +0 -0
  61. /package/templates/frontend/native/{tailwind.config.js → nativewind/tailwind.config.js} +0 -0
  62. /package/templates/frontend/native/{tsconfig.json → nativewind/tsconfig.json} +0 -0
@@ -0,0 +1,77 @@
1
+ {{#if (eq api "trpc")}}
2
+ import { queryClient } from "@/utils/trpc";
3
+ {{/if}}
4
+ {{#if (eq api "orpc")}}
5
+ import { queryClient } from "@/utils/orpc";
6
+ {{/if}}
7
+ {{#if (eq backend "convex")}}
8
+ import { ConvexProvider, ConvexReactClient } from "convex/react";
9
+ {{else}}
10
+ import { QueryClientProvider } from "@tanstack/react-query";
11
+ {{/if}}
12
+ import { Stack } from "expo-router";
13
+ import { GestureHandlerRootView } from "react-native-gesture-handler";
14
+ import { useUnistyles } from "react-native-unistyles";
15
+
16
+ export const unstable_settings = {
17
+ // Ensure that reloading on `/modal` keeps a back button present.
18
+ initialRouteName: "(drawer)",
19
+ };
20
+
21
+ {{#if (eq backend "convex")}}
22
+ const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!, {
23
+ unsavedChangesWarning: false,
24
+ });
25
+ {{/if}}
26
+
27
+ export default function RootLayout() {
28
+ const { theme } = useUnistyles();
29
+
30
+ return (
31
+ {{#if (eq backend "convex")}}
32
+ <ConvexProvider client={convex}>
33
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
34
+ <Stack
35
+ screenOptions=\{{
36
+ headerStyle: {
37
+ backgroundColor: theme.colors.background,
38
+ },
39
+ headerTitleStyle: {
40
+ color: theme.colors.typography,
41
+ },
42
+ headerTintColor: theme.colors.typography,
43
+ }}
44
+ >
45
+ <Stack.Screen name="(drawer)" options=\{{ headerShown: false }} />
46
+ <Stack.Screen
47
+ name="modal"
48
+ options=\{{ title: "Modal", presentation: "modal" }}
49
+ />
50
+ </Stack>
51
+ </GestureHandlerRootView>
52
+ </ConvexProvider>
53
+ {{else}}
54
+ <QueryClientProvider client={queryClient}>
55
+ <GestureHandlerRootView style=\{{ flex: 1 }}>
56
+ <Stack
57
+ screenOptions=\{{
58
+ headerStyle: {
59
+ backgroundColor: theme.colors.background,
60
+ },
61
+ headerTitleStyle: {
62
+ color: theme.colors.typography,
63
+ },
64
+ headerTintColor: theme.colors.typography,
65
+ }}
66
+ >
67
+ <Stack.Screen name="(drawer)" options=\{{ headerShown: false }} />
68
+ <Stack.Screen
69
+ name="modal"
70
+ options=\{{ title: "Modal", presentation: "modal" }}
71
+ />
72
+ </Stack>
73
+ </GestureHandlerRootView>
74
+ </QueryClientProvider>
75
+ {{/if}}
76
+ );
77
+ }
@@ -0,0 +1,29 @@
1
+ import { Container } from "@/components/container";
2
+ import { StatusBar } from "expo-status-bar";
3
+ import { Platform, Text, View } from "react-native";
4
+ import { StyleSheet } from "react-native-unistyles";
5
+
6
+ export default function Modal() {
7
+ return (
8
+ <>
9
+ <StatusBar style={Platform.OS === "ios" ? "light" : "auto"} />
10
+ <Container>
11
+ <View style={styles.container}>
12
+ <Text style={styles.text}>Model</Text>
13
+ </View>
14
+ </Container>
15
+ </>
16
+ );
17
+ }
18
+
19
+ const styles = StyleSheet.create((theme) => ({
20
+ text: {
21
+ color: theme.colors.typography,
22
+ },
23
+ container: {
24
+ flex: 1,
25
+ paddingBottom: 100,
26
+ justifyContent: "center",
27
+ alignItems: "center",
28
+ },
29
+ }));
@@ -0,0 +1,44 @@
1
+ {
2
+ "expo": {
3
+ "name": "my-better-t-app",
4
+ "slug": "my-better-t-app",
5
+ "version": "1.0.0",
6
+ "newArchEnabled": true,
7
+ "scheme": "my-better-t-app",
8
+ "web": {
9
+ "bundler": "metro",
10
+ "output": "static",
11
+ "favicon": "./assets/favicon.png"
12
+ },
13
+ "plugins": [
14
+ "expo-router",
15
+ "react-native-edge-to-edge",
16
+ "expo-secure-store"
17
+ ],
18
+ "experiments": {
19
+ "typedRoutes": true,
20
+ "tsconfigPaths": true,
21
+ "reactCompiler": true
22
+ },
23
+ "orientation": "portrait",
24
+ "icon": "./assets/icon.png",
25
+ "userInterfaceStyle": "automatic",
26
+ "splash": {
27
+ "image": "./assets/splash.png",
28
+ "resizeMode": "contain",
29
+ "backgroundColor": "#ffffff"
30
+ },
31
+ "assetBundlePatterns": ["**/*"],
32
+ "ios": {
33
+ "supportsTablet": true,
34
+ "bundleIdentifier": "com.amanvarshney01.mybettertapp"
35
+ },
36
+ "android": {
37
+ "adaptiveIcon": {
38
+ "foregroundImage": "./assets/adaptive-icon.png",
39
+ "backgroundColor": "#ffffff"
40
+ },
41
+ "package": "com.amanvarshney01.mybettertapp"
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,20 @@
1
+ module.exports = function (api) {
2
+ api.cache(true);
3
+ const plugins = [];
4
+
5
+ plugins.push([
6
+ 'react-native-unistyles/plugin',
7
+ {
8
+ autoProcessRoot: 'app',
9
+ autoProcessImports: ['@/components'],
10
+ },
11
+ ]);
12
+
13
+ plugins.push('react-native-reanimated/plugin');
14
+
15
+ return {
16
+ presets: ['babel-preset-expo'],
17
+
18
+ plugins,
19
+ };
20
+ };
@@ -0,0 +1,9 @@
1
+ export const breakpoints = {
2
+ xs: 0,
3
+ sm: 576,
4
+ md: 768,
5
+ lg: 992,
6
+ xl: 1200,
7
+ superLarge: 2000,
8
+ tvLike: 4000,
9
+ } as const;
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { View } from "react-native";
3
+ import { StyleSheet } from "react-native-unistyles";
4
+
5
+ export const Container = ({ children }: { children: React.ReactNode }) => {
6
+ return <View style={styles.container}>{children}</View>;
7
+ };
8
+
9
+ const styles = StyleSheet.create((theme, rt) => ({
10
+ container: {
11
+ flex: 1,
12
+ paddingBottom: rt.insets.bottom,
13
+ backgroundColor: theme.colors.background,
14
+ transform: [
15
+ {
16
+ translateY: rt.insets.ime * -1,
17
+ },
18
+ ],
19
+ },
20
+ }));
@@ -0,0 +1,31 @@
1
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
2
+ import { forwardRef } from 'react';
3
+ import { Pressable, StyleSheet } from 'react-native';
4
+
5
+ export const HeaderButton = forwardRef<typeof Pressable, { onPress?: () => void }>(
6
+ ({ onPress }, ref) => {
7
+ return (
8
+ <Pressable onPress={onPress}>
9
+ {({ pressed }) => (
10
+ <FontAwesome
11
+ name="info-circle"
12
+ size={25}
13
+ color="gray"
14
+ style={[
15
+ styles.headerRight,
16
+ {
17
+ opacity: pressed ? 0.5 : 1,
18
+ },
19
+ ]}
20
+ />
21
+ )}
22
+ </Pressable>
23
+ );
24
+ }
25
+ );
26
+
27
+ export const styles = StyleSheet.create({
28
+ headerRight: {
29
+ marginRight: 15,
30
+ },
31
+ });
@@ -0,0 +1,15 @@
1
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
2
+ import { StyleSheet } from 'react-native';
3
+
4
+ export const TabBarIcon = (props: {
5
+ name: React.ComponentProps<typeof FontAwesome>['name'];
6
+ color: string;
7
+ }) => {
8
+ return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
9
+ };
10
+
11
+ export const styles = StyleSheet.create({
12
+ tabBarIcon: {
13
+ marginBottom: -3,
14
+ },
15
+ });
@@ -0,0 +1,3 @@
1
+ /// <reference types="expo/types" />
2
+
3
+ // NOTE: This file should not be edited and should be in your git ignore
@@ -0,0 +1,2 @@
1
+ import 'expo-router/entry';
2
+ import './unistyles';
@@ -0,0 +1,20 @@
1
+ // Learn more https://docs.expo.io/guides/customizing-metro
2
+ const { getDefaultConfig } = require("expo/metro-config");
3
+ const path = require("path");
4
+
5
+ const workspaceRoot = path.resolve(__dirname, "../..");
6
+ const projectRoot = __dirname;
7
+
8
+ const config = getDefaultConfig(projectRoot);
9
+
10
+ // 1. Watch all files within the monorepo
11
+ config.watchFolders = [workspaceRoot];
12
+ // 2. Let Metro know where to resolve packages, and in what order
13
+ config.resolver.nodeModulesPaths = [
14
+ path.resolve(projectRoot, "node_modules"),
15
+ path.resolve(workspaceRoot, "node_modules"),
16
+ ];
17
+ // 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
18
+ config.resolver.disableHierarchicalLookup = true;
19
+
20
+ module.exports = config;
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "native",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "dev": "expo start --clear",
7
+ "android": "expo run:android",
8
+ "ios": "expo run:ios",
9
+ "web": "expo start --web"
10
+ },
11
+ "dependencies": {
12
+ "@better-auth/expo": "^1.2.7",
13
+ "@expo/vector-icons": "^14.0.0",
14
+ "@react-navigation/bottom-tabs": "^7.0.5",
15
+ "@react-navigation/drawer": "^7.0.0",
16
+ "@react-navigation/native": "^7.0.3",
17
+ "@tanstack/react-form": "^1.0.5",
18
+ "babel-plugin-react-compiler": "^19.0.0-beta-af1b7da-20250417",
19
+ "expo": "^53.0.8",
20
+ "expo-constants": "~17.1.4",
21
+ "expo-linking": "~7.1.4",
22
+ "expo-router": "~5.0.3",
23
+ "expo-secure-store": "~14.2.3",
24
+ "expo-status-bar": "~2.2.3",
25
+ "expo-system-ui": "~5.0.6",
26
+ "expo-dev-client": "~5.1.8",
27
+ "expo-web-browser": "~14.1.6",
28
+ "react": "19.0.0",
29
+ "react-dom": "19.0.0",
30
+ "react-native": "0.79.2",
31
+ "react-native-edge-to-edge": "1.6.0",
32
+ "react-native-gesture-handler": "~2.24.0",
33
+ "react-native-nitro-modules": "0.25.2",
34
+ "react-native-reanimated": "~3.17.4",
35
+ "react-native-safe-area-context": "5.4.0",
36
+ "react-native-screens": "~4.10.0",
37
+ "react-native-unistyles": "3.0.0-rc.3",
38
+ "react-native-web": "^0.20.0"
39
+ },
40
+ "devDependencies": {
41
+ "ajv": "^8.12.0",
42
+ "@babel/core": "^7.20.0",
43
+ "@types/react": "~19.0.10",
44
+ "typescript": "~5.8.3"
45
+ },
46
+ "private": true
47
+ }
@@ -0,0 +1,35 @@
1
+ const sharedColors = {
2
+ success: "#22C55E",
3
+ destructive: "#DC2626",
4
+ border: "#D1D5DB",
5
+ } as const;
6
+
7
+ export const lightTheme = {
8
+ colors: {
9
+ ...sharedColors,
10
+ typography: "#000000",
11
+ background: "#ffffff",
12
+ primary: "#3B82F6",
13
+ },
14
+ margins: {
15
+ sm: 2,
16
+ md: 4,
17
+ lg: 8,
18
+ xl: 12,
19
+ },
20
+ } as const;
21
+
22
+ export const darkTheme = {
23
+ colors: {
24
+ ...sharedColors,
25
+ typography: "#ffffff",
26
+ background: "#000000",
27
+ primary: "#60A5FA",
28
+ },
29
+ margins: {
30
+ sm: 2,
31
+ md: 4,
32
+ lg: 8,
33
+ xl: 12,
34
+ },
35
+ } as const;
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "expo/tsconfig.base",
3
+ "compilerOptions": {
4
+ "strict": true,
5
+ "jsx": "react-jsx",
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ "@/*": ["*"]
9
+ }
10
+ },
11
+ "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
12
+ }
@@ -0,0 +1,27 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+
3
+ import { breakpoints } from './breakpoints';
4
+ import { lightTheme, darkTheme } from './theme';
5
+
6
+ type AppBreakpoints = typeof breakpoints;
7
+
8
+ type AppThemes = {
9
+ light: typeof lightTheme;
10
+ dark: typeof darkTheme;
11
+ };
12
+
13
+ declare module 'react-native-unistyles' {
14
+ export interface UnistylesBreakpoints extends AppBreakpoints {}
15
+ export interface UnistylesThemes extends AppThemes {}
16
+ }
17
+
18
+ StyleSheet.configure({
19
+ breakpoints,
20
+ themes: {
21
+ light: lightTheme,
22
+ dark: darkTheme,
23
+ },
24
+ settings: {
25
+ adaptiveThemes: true,
26
+ },
27
+ });
@@ -41,10 +41,10 @@ export default function Header() {
41
41
  );
42
42
  {{else if (includes frontend "react-router")}}
43
43
  return (
44
- <NavLink
45
- key={to}
46
- to={to}
47
- className={({ isActive }) => isActive ? "font-bold" : ""}
44
+ <NavLink
45
+ key={to}
46
+ to={to}
47
+ className={({ isActive }) => isActive ? "font-bold" : ""}
48
48
  end
49
49
  >
50
50
  {label}
@@ -60,7 +60,6 @@ export default function Header() {
60
60
  </Link>
61
61
  );
62
62
  {{else}}
63
- // Fallback case (shouldn't happen with valid frontend selection)
64
63
  return null;
65
64
  {{/if}}
66
65
  })}
@@ -77,4 +76,4 @@ export default function Header() {
77
76
  <hr />
78
77
  </div>
79
78
  );
80
- }
79
+ }