create-100x-mobile 0.3.2 → 0.4.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.
@@ -93,7 +93,7 @@ async function cmdNew(args) {
93
93
  // We'll calculate totalSteps after Clerk prompts, but we create the
94
94
  // counter now. We'll adjust totalSteps after Clerk prompts.
95
95
  let currentStep = 0;
96
- let totalSteps = 5; // base: structure, deps, convex, git, health check
96
+ let totalSteps = 6; // base: structure, deps, expo deps, convex, git, health check
97
97
  // totalSteps += 1 if clerkDomain (convex env step) — adjusted after Clerk prompts
98
98
  const stepLabel = () => `(${currentStep}/${totalSteps})`;
99
99
  // ── Step: Create directories ─────────────────────────
@@ -168,6 +168,40 @@ async function cmdNew(args) {
168
168
  }
169
169
  }
170
170
  prompts_1.log.success("Dependencies installed.");
171
+ // ── Step: Resolve Expo dependencies ────────────────────
172
+ currentStep++;
173
+ prompts_1.log.step(`Installing Expo dependencies ${stepLabel()}`);
174
+ const expoPackages = [
175
+ "expo-router",
176
+ "@expo/vector-icons",
177
+ "expo-auth-session",
178
+ "expo-blur",
179
+ "expo-constants",
180
+ "expo-font",
181
+ "expo-haptics",
182
+ "expo-linking",
183
+ "expo-secure-store",
184
+ "expo-splash-screen",
185
+ "expo-status-bar",
186
+ "expo-system-ui",
187
+ "expo-web-browser",
188
+ "react-native-gesture-handler",
189
+ "react-native-reanimated",
190
+ "react-native-safe-area-context",
191
+ "react-native-screens",
192
+ "react-native-svg",
193
+ "react-native-web",
194
+ ];
195
+ try {
196
+ await (0, run_1.run)("npx", ["expo", "install", ...expoPackages], {
197
+ cwd: projectDir,
198
+ });
199
+ prompts_1.log.success("Expo dependencies resolved.");
200
+ }
201
+ catch {
202
+ prompts_1.log.warn("Could not resolve Expo deps automatically.");
203
+ prompts_1.log.info(picocolors_1.default.dim(" Run manually: npx expo install --fix"));
204
+ }
171
205
  // ── Step 5: Prompt for Clerk keys ──────────────────────
172
206
  // Moved BEFORE Convex init so we only need a single `convex dev --once` run.
173
207
  prompts_1.log.info("");
@@ -225,7 +259,7 @@ async function cmdNew(args) {
225
259
  }
226
260
  // Adjust total steps if Clerk domain is configured
227
261
  if (clerkDomain) {
228
- totalSteps = 6; // adds convex env step
262
+ totalSteps = 7; // adds convex env step
229
263
  }
230
264
  // ── Write Clerk env vars to .env.local ─────────
231
265
  const envLocalPath = (0, node_path_1.join)(projectDir, ".env.local");
@@ -2,13 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.addTodoFormTemplate = addTodoFormTemplate;
4
4
  function addTodoFormTemplate() {
5
- return `import React, { useState } from "react";
6
- import { View, TextInput, TouchableOpacity, StyleSheet } from "react-native";
7
- import Animated, {
8
- useSharedValue,
9
- useAnimatedStyle,
10
- withSpring,
11
- } from "react-native-reanimated";
5
+ return `import React, { useState, useRef } from "react";
6
+ import { View, TextInput, TouchableOpacity, StyleSheet, Animated } from "react-native";
12
7
  import * as Haptics from "expo-haptics";
13
8
  import { Plus } from "lucide-react-native";
14
9
 
@@ -18,17 +13,20 @@ interface AddTodoFormProps {
18
13
 
19
14
  export function AddTodoForm({ onAddTodo }: AddTodoFormProps) {
20
15
  const [text, setText] = useState("");
21
- const buttonScale = useSharedValue(1);
22
-
23
- const buttonAnimatedStyle = useAnimatedStyle(() => ({
24
- transform: [{ scale: buttonScale.value }],
25
- }));
16
+ const buttonScale = useRef(new Animated.Value(1)).current;
26
17
 
27
18
  const handleSubmit = () => {
28
19
  if (text.trim()) {
29
- buttonScale.value = withSpring(0.9, { damping: 15 }, () => {
30
- buttonScale.value = withSpring(1, { damping: 15 });
31
- });
20
+ Animated.sequence([
21
+ Animated.spring(buttonScale, {
22
+ toValue: 0.9,
23
+ useNativeDriver: true,
24
+ }),
25
+ Animated.spring(buttonScale, {
26
+ toValue: 1,
27
+ useNativeDriver: true,
28
+ }),
29
+ ]).start();
32
30
  Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
33
31
  onAddTodo(text);
34
32
  setText("");
@@ -48,7 +46,7 @@ export function AddTodoForm({ onAddTodo }: AddTodoFormProps) {
48
46
  returnKeyType="done"
49
47
  multiline={false}
50
48
  />
51
- <Animated.View style={buttonAnimatedStyle}>
49
+ <Animated.View style={{ transform: [{ scale: buttonScale }] }}>
52
50
  <TouchableOpacity
53
51
  style={[styles.addButton, !text.trim() && styles.addButtonDisabled]}
54
52
  onPress={handleSubmit}
@@ -2,14 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.todoItemTemplate = todoItemTemplate;
4
4
  function todoItemTemplate() {
5
- return `import React from "react";
6
- import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
7
- import Animated, {
8
- FadeInDown,
9
- useSharedValue,
10
- useAnimatedStyle,
11
- withSpring,
12
- } from "react-native-reanimated";
5
+ return `import React, { useRef } from "react";
6
+ import { View, Text, TouchableOpacity, StyleSheet, Animated } from "react-native";
13
7
  import * as Haptics from "expo-haptics";
14
8
  import { Check, X } from "lucide-react-native";
15
9
  import type { Todo } from "@/app/(tabs)/index";
@@ -22,16 +16,28 @@ interface TodoItemProps {
22
16
  }
23
17
 
24
18
  export function TodoItem({ todo, onToggle, onDelete }: TodoItemProps) {
25
- const checkboxScale = useSharedValue(1);
19
+ const checkboxScale = useRef(new Animated.Value(1)).current;
20
+ const fadeAnim = useRef(new Animated.Value(0)).current;
26
21
 
27
- const checkboxAnimatedStyle = useAnimatedStyle(() => ({
28
- transform: [{ scale: checkboxScale.value }],
29
- }));
22
+ React.useEffect(() => {
23
+ Animated.timing(fadeAnim, {
24
+ toValue: 1,
25
+ duration: 300,
26
+ useNativeDriver: true,
27
+ }).start();
28
+ }, []);
30
29
 
31
30
  const handleToggle = () => {
32
- checkboxScale.value = withSpring(0.85, { damping: 15 }, () => {
33
- checkboxScale.value = withSpring(1, { damping: 15 });
34
- });
31
+ Animated.sequence([
32
+ Animated.spring(checkboxScale, {
33
+ toValue: 0.85,
34
+ useNativeDriver: true,
35
+ }),
36
+ Animated.spring(checkboxScale, {
37
+ toValue: 1,
38
+ useNativeDriver: true,
39
+ }),
40
+ ]).start();
35
41
  Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
36
42
  onToggle(todo._id);
37
43
  };
@@ -42,7 +48,7 @@ export function TodoItem({ todo, onToggle, onDelete }: TodoItemProps) {
42
48
  };
43
49
 
44
50
  return (
45
- <Animated.View entering={FadeInDown.duration(300).springify()}>
51
+ <Animated.View style={{ opacity: fadeAnim }}>
46
52
  <View style={styles.container}>
47
53
  <TouchableOpacity
48
54
  style={styles.checkboxHitArea}
@@ -53,7 +59,7 @@ export function TodoItem({ todo, onToggle, onDelete }: TodoItemProps) {
53
59
  style={[
54
60
  styles.checkbox,
55
61
  todo.completed && styles.checkboxCompleted,
56
- checkboxAnimatedStyle,
62
+ { transform: [{ scale: checkboxScale }] },
57
63
  ]}
58
64
  >
59
65
  {todo.completed && (
@@ -15,33 +15,11 @@ function packageJsonTemplate(appName) {
15
15
  },
16
16
  dependencies: {
17
17
  "@clerk/clerk-expo": "^2.14.24",
18
- "@expo/vector-icons": "^15.0.3",
19
18
  "@react-navigation/bottom-tabs": "^7.3.10",
20
19
  "@react-navigation/native": "^7.1.6",
21
20
  convex: "^1.26.1",
22
- expo: "~54.0.31",
23
- "expo-auth-session": "~7.0.10",
24
- "expo-blur": "~15.0.8",
25
- "expo-constants": "~18.0.13",
26
- "expo-font": "~14.0.10",
27
- "expo-haptics": "~15.0.8",
28
- "expo-linking": "~8.0.11",
29
- "expo-router": "~6.0.21",
30
- "expo-secure-store": "~15.0.8",
31
- "expo-splash-screen": "~31.0.13",
32
- "expo-status-bar": "~3.0.9",
33
- "expo-system-ui": "~6.0.9",
34
- "expo-web-browser": "~15.0.10",
21
+ expo: "latest",
35
22
  "lucide-react-native": "^0.542.0",
36
- react: "19.1.0",
37
- "react-dom": "19.1.0",
38
- "react-native": "0.81.5",
39
- "react-native-gesture-handler": "~2.28.0",
40
- "react-native-reanimated": "~3.16.1",
41
- "react-native-safe-area-context": "~5.6.0",
42
- "react-native-screens": "~4.16.0",
43
- "react-native-svg": "15.12.1",
44
- "react-native-web": "^0.21.0",
45
23
  },
46
24
  devDependencies: {
47
25
  "@babel/core": "^7.25.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-100x-mobile",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Scaffold a full-stack mobile app with Expo + Convex + Clerk in seconds",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {