create-better-t-stack 2.14.4 → 2.15.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 (37) hide show
  1. package/dist/index.js +18 -14
  2. package/package.json +1 -1
  3. package/templates/examples/ai/native/nativewind/app/(drawer)/ai.tsx.hbs +155 -0
  4. package/templates/examples/ai/native/nativewind/polyfills.js +25 -0
  5. package/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs +279 -0
  6. package/templates/examples/ai/native/unistyles/polyfills.js +25 -0
  7. package/templates/examples/todo/native/unistyles/app/(drawer)/todos.tsx.hbs +340 -0
  8. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/_layout.tsx +24 -7
  9. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx +15 -13
  10. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx +15 -13
  11. package/templates/frontend/native/nativewind/app/(drawer)/_layout.tsx.hbs +25 -9
  12. package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +43 -30
  13. package/templates/frontend/native/nativewind/app/+not-found.tsx +20 -9
  14. package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +3 -0
  15. package/templates/frontend/native/nativewind/app/modal.tsx +9 -7
  16. package/templates/frontend/native/nativewind/components/container.tsx +2 -3
  17. package/templates/frontend/native/nativewind/components/header-button.tsx +24 -29
  18. package/templates/frontend/native/nativewind/components/tabbar-icon.tsx +3 -10
  19. package/templates/frontend/native/nativewind/global.css +36 -11
  20. package/templates/frontend/native/nativewind/lib/constants.ts +8 -8
  21. package/templates/frontend/native/nativewind/{package.json → package.json.hbs} +4 -0
  22. package/templates/frontend/native/nativewind/tailwind.config.js +27 -0
  23. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx +9 -4
  24. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx +25 -17
  25. package/templates/frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx +26 -18
  26. package/templates/frontend/native/unistyles/app/(drawer)/{_layout.tsx → _layout.tsx.hbs} +35 -7
  27. package/templates/frontend/native/unistyles/app/(drawer)/index.tsx.hbs +121 -58
  28. package/templates/frontend/native/unistyles/app/+not-found.tsx +45 -14
  29. package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +9 -6
  30. package/templates/frontend/native/unistyles/app/modal.tsx +18 -14
  31. package/templates/frontend/native/unistyles/components/container.tsx +3 -8
  32. package/templates/frontend/native/unistyles/components/header-button.tsx +33 -28
  33. package/templates/frontend/native/unistyles/components/tabbar-icon.tsx +3 -10
  34. package/templates/frontend/native/unistyles/{package.json → package.json.hbs} +5 -1
  35. package/templates/frontend/native/unistyles/theme.ts +82 -19
  36. package/templates/frontend/native/unistyles/unistyles.ts +4 -4
  37. /package/templates/examples/todo/native/nativewind/app/{todo.tsx.hbs → (drawer)/todos.tsx.hbs} +0 -0
@@ -1,9 +1,8 @@
1
+ import React from "react";
1
2
  import { SafeAreaView } from "react-native";
2
3
 
3
4
  export const Container = ({ children }: { children: React.ReactNode }) => {
4
5
  return (
5
- <SafeAreaView className="flex flex-1 p-4 bg-background">
6
- {children}
7
- </SafeAreaView>
6
+ <SafeAreaView className="flex-1 bg-background">{children}</SafeAreaView>
8
7
  );
9
8
  };
@@ -1,31 +1,26 @@
1
- import FontAwesome from '@expo/vector-icons/FontAwesome';
2
- import { forwardRef } from 'react';
3
- import { Pressable, StyleSheet } from 'react-native';
1
+ import FontAwesome from "@expo/vector-icons/FontAwesome";
2
+ import { forwardRef } from "react";
3
+ import { Pressable } from "react-native";
4
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
- },
5
+ export const HeaderButton = forwardRef<
6
+ typeof Pressable,
7
+ { onPress?: () => void }
8
+ >(({ onPress }, ref) => {
9
+ return (
10
+ <Pressable
11
+ onPress={onPress}
12
+ className="p-2 mr-2 rounded-lg bg-secondary/50 active:bg-secondary"
13
+ >
14
+ {({ pressed }) => (
15
+ <FontAwesome
16
+ name="info-circle"
17
+ size={20}
18
+ className="text-secondary-foreground"
19
+ style={{
20
+ opacity: pressed ? 0.7 : 1,
21
+ }}
22
+ />
23
+ )}
24
+ </Pressable>
25
+ );
31
26
  });
@@ -1,15 +1,8 @@
1
- import FontAwesome from '@expo/vector-icons/FontAwesome';
2
- import { StyleSheet } from 'react-native';
1
+ import FontAwesome from "@expo/vector-icons/FontAwesome";
3
2
 
4
3
  export const TabBarIcon = (props: {
5
- name: React.ComponentProps<typeof FontAwesome>['name'];
4
+ name: React.ComponentProps<typeof FontAwesome>["name"];
6
5
  color: string;
7
6
  }) => {
8
- return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
7
+ return <FontAwesome size={24} style={{ marginBottom: -3 }} {...props} />;
9
8
  };
10
-
11
- export const styles = StyleSheet.create({
12
- tabBarIcon: {
13
- marginBottom: -3,
14
- },
15
- });
@@ -5,21 +5,46 @@
5
5
  @layer base {
6
6
  :root {
7
7
  --background: 0 0% 100%;
8
- --foreground: 240 10% 3.9%;
9
- --primary: 240 5.9% 10%;
10
- --primary-foreground: 0 0% 98%;
11
- --secondary: 240 4.8% 95.9%;
12
- --secondary-foreground: 240 5.9% 10%;
8
+ --foreground: 222.2 84% 4.9%;
9
+ --card: 0 0% 100%;
10
+ --card-foreground: 222.2 84% 4.9%;
11
+ --popover: 0 0% 100%;
12
+ --popover-foreground: 222.2 84% 4.9%;
13
+ --primary: 221.2 83.2% 53.3%;
14
+ --primary-foreground: 210 40% 98%;
15
+ --secondary: 210 40% 96%;
16
+ --secondary-foreground: 222.2 84% 4.9%;
17
+ --muted: 210 40% 96%;
18
+ --muted-foreground: 215.4 16.3% 40%;
19
+ --accent: 210 40% 96%;
20
+ --accent-foreground: 222.2 84% 4.9%;
13
21
  --destructive: 0 84.2% 60.2%;
22
+ --destructive-foreground: 210 40% 98%;
23
+ --border: 214.3 31.8% 91.4%;
24
+ --input: 214.3 31.8% 91.4%;
25
+ --ring: 221.2 83.2% 53.3%;
26
+ --radius: 8px;
14
27
  }
15
28
 
16
29
  .dark:root {
17
- --background: 240 10% 3.9%;
18
- --foreground: 0 0% 98%;
19
- --primary: 0 0% 98%;
20
- --primary-foreground: 240 5.9% 10%;
21
- --secondary: 240 3.7% 15.9%;
22
- --secondary-foreground: 0 0% 98%;
30
+ --background: 222.2 84% 4.9%;
31
+ --foreground: 210 40% 98%;
32
+ --card: 222.2 84% 4.9%;
33
+ --card-foreground: 210 40% 98%;
34
+ --popover: 222.2 84% 4.9%;
35
+ --popover-foreground: 210 40% 98%;
36
+ --primary: 217.2 91.2% 59.8%;
37
+ --primary-foreground: 222.2 84% 4.9%;
38
+ --secondary: 217.2 32.6% 17.5%;
39
+ --secondary-foreground: 210 40% 98%;
40
+ --muted: 217.2 32.6% 17.5%;
41
+ --muted-foreground: 215 20.2% 70%;
42
+ --accent: 217.2 32.6% 17.5%;
43
+ --accent-foreground: 210 40% 98%;
23
44
  --destructive: 0 72% 51%;
45
+ --destructive-foreground: 210 40% 98%;
46
+ --border: 217.2 32.6% 17.5%;
47
+ --input: 217.2 32.6% 17.5%;
48
+ --ring: 224.3 76.3% 94.1%;
24
49
  }
25
50
  }
@@ -1,18 +1,18 @@
1
1
  export const NAV_THEME = {
2
2
  light: {
3
3
  background: "hsl(0 0% 100%)",
4
- border: "hsl(240 5.9% 90%)",
4
+ border: "hsl(220 13% 91%)",
5
5
  card: "hsl(0 0% 100%)",
6
6
  notification: "hsl(0 84.2% 60.2%)",
7
- primary: "hsl(240 5.9% 10%)",
8
- text: "hsl(240 10% 3.9%)",
7
+ primary: "hsl(221.2 83.2% 53.3%)",
8
+ text: "hsl(222.2 84% 4.9%)",
9
9
  },
10
10
  dark: {
11
- background: "hsl(240 10% 3.9%)",
12
- border: "hsl(240 3.7% 15.9%)",
13
- card: "hsl(240 10% 3.9%)",
11
+ background: "hsl(222.2 84% 4.9%)",
12
+ border: "hsl(217.2 32.6% 17.5%)",
13
+ card: "hsl(222.2 84% 4.9%)",
14
14
  notification: "hsl(0 72% 51%)",
15
- primary: "hsl(0 0% 98%)",
16
- text: "hsl(0 0% 98%)",
15
+ primary: "hsl(217.2 91.2% 59.8%)",
16
+ text: "hsl(210 40% 98%)",
17
17
  },
18
18
  };
@@ -16,6 +16,10 @@
16
16
  "@react-navigation/native": "^7.0.14",
17
17
  "@tanstack/react-form": "^1.0.5",
18
18
  "@tanstack/react-query": "^5.69.2",
19
+ {{#if (includes examples "ai")}}
20
+ "@stardazed/streams-text-encoding": "^1.0.2",
21
+ "@ungap/structured-clone": "^1.3.0",
22
+ {{/if}}
19
23
  "expo": "^53.0.4",
20
24
  "expo-constants": "~17.1.4",
21
25
  "expo-linking": "~7.1.4",
@@ -11,6 +11,14 @@ module.exports = {
11
11
  colors: {
12
12
  background: "hsl(var(--background))",
13
13
  foreground: "hsl(var(--foreground))",
14
+ card: {
15
+ DEFAULT: "hsl(var(--card))",
16
+ foreground: "hsl(var(--card-foreground))",
17
+ },
18
+ popover: {
19
+ DEFAULT: "hsl(var(--popover))",
20
+ foreground: "hsl(var(--popover-foreground))",
21
+ },
14
22
  primary: {
15
23
  DEFAULT: "hsl(var(--primary))",
16
24
  foreground: "hsl(var(--primary-foreground))",
@@ -19,9 +27,28 @@ module.exports = {
19
27
  DEFAULT: "hsl(var(--secondary))",
20
28
  foreground: "hsl(var(--secondary-foreground))",
21
29
  },
30
+ muted: {
31
+ DEFAULT: "hsl(var(--muted))",
32
+ foreground: "hsl(var(--muted-foreground))",
33
+ },
34
+ accent: {
35
+ DEFAULT: "hsl(var(--accent))",
36
+ foreground: "hsl(var(--accent-foreground))",
37
+ },
22
38
  destructive: {
23
39
  DEFAULT: "hsl(var(--destructive))",
40
+ foreground: "hsl(var(--destructive-foreground))",
24
41
  },
42
+ border: "hsl(var(--border))",
43
+ input: "hsl(var(--input))",
44
+ ring: "hsl(var(--ring))",
45
+ radius: "var(--radius)",
46
+ },
47
+ borderRadius: {
48
+ xl: "calc(var(--radius) + 4px)",
49
+ lg: "var(--radius)",
50
+ md: "calc(var(--radius) - 2px)",
51
+ sm: "calc(var(--radius) - 4px)",
25
52
  },
26
53
  borderWidth: {
27
54
  hairline: hairlineWidth(),
@@ -10,23 +10,28 @@ export default function TabLayout() {
10
10
  <Tabs
11
11
  screenOptions={{
12
12
  headerShown: false,
13
+ tabBarActiveTintColor: theme.colors.primary,
14
+ tabBarInactiveTintColor: theme.colors.mutedForeground,
13
15
  tabBarStyle: {
14
16
  backgroundColor: theme.colors.background,
17
+ borderTopColor: theme.colors.border,
15
18
  },
16
19
  }}
17
20
  >
18
21
  <Tabs.Screen
19
22
  name="index"
20
23
  options={{
21
- title: "Tab One",
22
- tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
24
+ title: "Home",
25
+ tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
23
26
  }}
24
27
  />
25
28
  <Tabs.Screen
26
29
  name="two"
27
30
  options={{
28
- title: "Tab Two",
29
- tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
31
+ title: "Explore",
32
+ tabBarIcon: ({ color }) => (
33
+ <TabBarIcon name="compass" color={color} />
34
+ ),
30
35
  }}
31
36
  />
32
37
  </Tabs>
@@ -1,29 +1,37 @@
1
- import { Stack } from "expo-router";
2
- import { StyleSheet } from "react-native-unistyles";
3
1
  import { Container } from "@/components/container";
4
- import { Text, View } from "react-native";
2
+ import { ScrollView, Text, View } from "react-native";
3
+ import { StyleSheet } from "react-native-unistyles";
5
4
 
6
5
  export default function Home() {
7
6
  return (
8
- <>
9
- <Stack.Screen options={{ title: "Tab One" }} />
10
- <Container>
11
- <View style={styles.container}>
12
- <Text style={styles.text}>Tab One</Text>
7
+ <Container>
8
+ <ScrollView contentContainerStyle={styles.container}>
9
+ <View style={styles.headerSection}>
10
+ <Text style={styles.title}>Tab One</Text>
11
+ <Text style={styles.subtitle}>
12
+ Explore the first section of your app
13
+ </Text>
13
14
  </View>
14
- </Container>
15
- </>
15
+ </ScrollView>
16
+ </Container>
16
17
  );
17
18
  }
18
19
 
19
20
  const styles = StyleSheet.create((theme) => ({
20
- text: {
21
- color: theme.colors.typography,
22
- },
23
21
  container: {
24
- flex: 1,
25
- paddingBottom: 100,
26
- justifyContent: "center",
27
- alignItems: "center",
22
+ padding: theme.spacing.lg,
23
+ },
24
+ headerSection: {
25
+ paddingVertical: theme.spacing.xl,
26
+ },
27
+ title: {
28
+ fontSize: theme.fontSize["3xl"],
29
+ fontWeight: "bold",
30
+ color: theme.colors.foreground,
31
+ marginBottom: theme.spacing.sm,
32
+ },
33
+ subtitle: {
34
+ fontSize: theme.fontSize.lg,
35
+ color: theme.colors.mutedForeground,
28
36
  },
29
37
  }));
@@ -1,29 +1,37 @@
1
- import { Stack } from "expo-router";
2
- import { StyleSheet } from "react-native-unistyles";
3
1
  import { Container } from "@/components/container";
4
- import { Text, View } from "react-native";
2
+ import { ScrollView, Text, View } from "react-native";
3
+ import { StyleSheet } from "react-native-unistyles";
5
4
 
6
- export default function Home() {
5
+ export default function TabTwo() {
7
6
  return (
8
- <>
9
- <Stack.Screen options={{ title: "Tab Two" }} />
10
- <Container>
11
- <View style={styles.container}>
12
- <Text style={styles.text}>Tab Two</Text>
7
+ <Container>
8
+ <ScrollView contentContainerStyle={styles.container}>
9
+ <View style={styles.headerSection}>
10
+ <Text style={styles.title}>Tab Two</Text>
11
+ <Text style={styles.subtitle}>
12
+ Discover more features and content
13
+ </Text>
13
14
  </View>
14
- </Container>
15
- </>
15
+ </ScrollView>
16
+ </Container>
16
17
  );
17
18
  }
18
19
 
19
20
  const styles = StyleSheet.create((theme) => ({
20
- text: {
21
- color: theme.colors.typography,
22
- },
23
21
  container: {
24
- flex: 1,
25
- paddingBottom: 100,
26
- justifyContent: "center",
27
- alignItems: "center",
22
+ padding: theme.spacing.lg,
23
+ },
24
+ headerSection: {
25
+ paddingVertical: theme.spacing.xl,
26
+ },
27
+ title: {
28
+ fontSize: theme.fontSize["3xl"],
29
+ fontWeight: "bold",
30
+ color: theme.colors.foreground,
31
+ marginBottom: theme.spacing.sm,
32
+ },
33
+ subtitle: {
34
+ fontSize: theme.fontSize.lg,
35
+ color: theme.colors.mutedForeground,
28
36
  },
29
37
  }));
@@ -10,26 +10,26 @@ const DrawerLayout = () => {
10
10
 
11
11
  return (
12
12
  <Drawer
13
- screenOptions={{
13
+ screenOptions=\{{
14
14
  headerStyle: {
15
15
  backgroundColor: theme.colors.background,
16
16
  },
17
17
  headerTitleStyle: {
18
- color: theme.colors.typography,
18
+ color: theme.colors.foreground,
19
19
  },
20
- headerTintColor: theme.colors.typography,
20
+ headerTintColor: theme.colors.foreground,
21
21
  drawerStyle: {
22
22
  backgroundColor: theme.colors.background,
23
23
  },
24
24
  drawerLabelStyle: {
25
- color: theme.colors.typography,
25
+ color: theme.colors.foreground,
26
26
  },
27
- drawerInactiveTintColor: theme.colors.typography,
27
+ drawerInactiveTintColor: theme.colors.mutedForeground,
28
28
  }}
29
29
  >
30
30
  <Drawer.Screen
31
31
  name="index"
32
- options={{
32
+ options=\{{
33
33
  headerTitle: "Home",
34
34
  drawerLabel: "Home",
35
35
  drawerIcon: ({ size, color }) => (
@@ -39,7 +39,7 @@ const DrawerLayout = () => {
39
39
  />
40
40
  <Drawer.Screen
41
41
  name="(tabs)"
42
- options={{
42
+ options=\{{
43
43
  headerTitle: "Tabs",
44
44
  drawerLabel: "Tabs",
45
45
  drawerIcon: ({ size, color }) => (
@@ -52,6 +52,34 @@ const DrawerLayout = () => {
52
52
  ),
53
53
  }}
54
54
  />
55
+ {{#if (includes examples "todo")}}
56
+ <Drawer.Screen
57
+ name="todos"
58
+ options=\{{
59
+ headerTitle: "Todos",
60
+ drawerLabel: "Todos",
61
+ drawerIcon: ({ size, color }) => (
62
+ <Ionicons name="checkbox-outline" size={size} color={color} />
63
+ ),
64
+ }}
65
+ />
66
+ {{/if}}
67
+ {{#if (includes examples "ai")}}
68
+ <Drawer.Screen
69
+ name="ai"
70
+ options=\{{
71
+ headerTitle: "AI",
72
+ drawerLabel: "AI",
73
+ drawerIcon: ({ size, color }) => (
74
+ <Ionicons
75
+ name="chatbubble-ellipses-outline"
76
+ size={size}
77
+ color={color}
78
+ />
79
+ ),
80
+ }}
81
+ />
82
+ {{/if}}
55
83
  </Drawer>
56
84
  );
57
85
  };