create-better-t-stack 3.2.22 → 3.2.23-canary.b8d62867

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 (86) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +1 -1
  3. package/dist/index.d.ts +4 -2
  4. package/dist/index.js +1 -1
  5. package/dist/{src-WIwtBCHf.js → src-VoUvj8ZF.js} +106 -66
  6. package/package.json +1 -1
  7. package/templates/addons/biome/biome.json.hbs +5 -0
  8. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +5 -5
  9. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
  10. package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
  11. package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
  12. package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +91 -0
  13. package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +102 -0
  14. package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
  15. package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
  16. package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
  17. package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +9 -1
  18. package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +5 -0
  19. package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +5 -0
  20. package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
  21. package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +90 -0
  22. package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +116 -0
  23. package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
  24. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +287 -0
  25. package/templates/examples/ai/native/{nativewind → bare}/polyfills.js +1 -0
  26. package/templates/examples/ai/native/{nativewind → uniwind}/app/(drawer)/ai.tsx.hbs +52 -51
  27. package/templates/examples/ai/native/uniwind/polyfills.js +26 -0
  28. package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +521 -0
  29. package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +295 -0
  30. package/templates/extras/bunfig.toml.hbs +3 -3
  31. package/templates/frontend/native/bare/_gitignore +18 -0
  32. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/(tabs)/_layout.tsx.hbs +7 -12
  33. package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
  34. package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
  35. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/_layout.tsx.hbs +24 -1
  36. package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
  37. package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
  38. package/templates/frontend/native/bare/app/_layout.tsx.hbs +163 -0
  39. package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
  40. package/templates/frontend/native/{nativewind → bare}/app.json.hbs +1 -0
  41. package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
  42. package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
  43. package/templates/frontend/native/{nativewind → bare}/components/tabbar-icon.tsx.hbs +1 -0
  44. package/templates/frontend/native/{nativewind → bare}/lib/android-navigation-bar.tsx.hbs +1 -0
  45. package/templates/frontend/native/{nativewind → bare}/lib/constants.ts.hbs +1 -0
  46. package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
  47. package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
  48. package/templates/frontend/native/{nativewind → bare}/package.json.hbs +1 -2
  49. package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
  50. package/templates/frontend/native/{nativewind → uniwind}/_gitignore +4 -8
  51. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
  52. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
  53. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
  54. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +83 -0
  55. package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +151 -0
  56. package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +32 -0
  57. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +131 -0
  58. package/templates/frontend/native/uniwind/app/modal.tsx.hbs +53 -0
  59. package/templates/frontend/native/uniwind/app.json.hbs +19 -0
  60. package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
  61. package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
  62. package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
  63. package/templates/frontend/native/uniwind/global.css +5 -0
  64. package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
  65. package/templates/frontend/native/uniwind/package.json.hbs +54 -0
  66. package/templates/frontend/native/{nativewind → uniwind}/tsconfig.json.hbs +4 -8
  67. package/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs +0 -86
  68. package/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs +0 -97
  69. package/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs +0 -95
  70. package/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs +0 -93
  71. package/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs +0 -104
  72. package/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs +0 -295
  73. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs +0 -19
  74. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs +0 -19
  75. package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +0 -178
  76. package/templates/frontend/native/nativewind/app/+not-found.tsx.hbs +0 -29
  77. package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -175
  78. package/templates/frontend/native/nativewind/app/modal.tsx.hbs +0 -14
  79. package/templates/frontend/native/nativewind/babel.config.js.hbs +0 -14
  80. package/templates/frontend/native/nativewind/components/container.tsx.hbs +0 -8
  81. package/templates/frontend/native/nativewind/components/header-button.tsx.hbs +0 -26
  82. package/templates/frontend/native/nativewind/global.css +0 -50
  83. package/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs +0 -12
  84. package/templates/frontend/native/nativewind/metro.config.js.hbs +0 -12
  85. package/templates/frontend/native/nativewind/tailwind.config.js.hbs +0 -59
  86. /package/templates/auth/clerk/convex/native/base/app/(auth)/{sign-out.tsx.hbs → sign-up.tsx.hbs} +0 -0
@@ -0,0 +1,521 @@
1
+ import { useState } from "react";
2
+ import {
3
+ View,
4
+ Text,
5
+ TextInput,
6
+ ScrollView,
7
+ ActivityIndicator,
8
+ Alert,
9
+ TouchableOpacity,
10
+ StyleSheet,
11
+ } from "react-native";
12
+ import { Ionicons } from "@expo/vector-icons";
13
+ {{#if (eq backend "convex")}}
14
+ import { useMutation, useQuery } from "convex/react";
15
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
16
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
17
+ {{else}}
18
+ import { useMutation, useQuery } from "@tanstack/react-query";
19
+ {{/if}}
20
+ import { Container } from "@/components/container";
21
+ import { useColorScheme } from "@/lib/use-color-scheme";
22
+ import { NAV_THEME } from "@/lib/constants";
23
+ {{#unless (eq backend "convex")}}
24
+ {{#if (eq api "orpc")}}
25
+ import { orpc } from "@/utils/orpc";
26
+ {{/if}}
27
+ {{#if (eq api "trpc")}}
28
+ import { trpc } from "@/utils/trpc";
29
+ {{/if}}
30
+ {{/unless}}
31
+
32
+ export default function TodosScreen() {
33
+ const { colorScheme } = useColorScheme();
34
+ const theme = colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light;
35
+ const [newTodoText, setNewTodoText] = useState("");
36
+
37
+ {{#if (eq backend "convex")}}
38
+ const todos = useQuery(api.todos.getAll);
39
+ const createTodoMutation = useMutation(api.todos.create);
40
+ const toggleTodoMutation = useMutation(api.todos.toggle);
41
+ const deleteTodoMutation = useMutation(api.todos.deleteTodo);
42
+
43
+ async function handleAddTodo() {
44
+ const text = newTodoText.trim();
45
+ if (!text) return;
46
+ await createTodoMutation({ text });
47
+ setNewTodoText("");
48
+ }
49
+
50
+ function handleToggleTodo(id: Id<"todos">, currentCompleted: boolean) {
51
+ toggleTodoMutation({ id, completed: !currentCompleted });
52
+ }
53
+
54
+ function handleDeleteTodo(id: Id<"todos">) {
55
+ Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
56
+ { text: "Cancel", style: "cancel" },
57
+ {
58
+ text: "Delete",
59
+ style: "destructive",
60
+ onPress: () => deleteTodoMutation({ id }),
61
+ },
62
+ ]);
63
+ }
64
+
65
+ const isLoading = !todos;
66
+ const completedCount = todos?.filter((t) => t.completed).length || 0;
67
+ const totalCount = todos?.length || 0;
68
+ {{else}}
69
+ {{#if (eq api "orpc")}}
70
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
71
+ const createMutation = useMutation(
72
+ orpc.todo.create.mutationOptions({
73
+ onSuccess: () => {
74
+ todos.refetch();
75
+ setNewTodoText("");
76
+ },
77
+ })
78
+ );
79
+ const toggleMutation = useMutation(
80
+ orpc.todo.toggle.mutationOptions({
81
+ onSuccess: () => {
82
+ todos.refetch();
83
+ },
84
+ })
85
+ );
86
+ const deleteMutation = useMutation(
87
+ orpc.todo.delete.mutationOptions({
88
+ onSuccess: () => {
89
+ todos.refetch();
90
+ },
91
+ })
92
+ );
93
+ {{/if}}
94
+ {{#if (eq api "trpc")}}
95
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
96
+ const createMutation = useMutation(
97
+ trpc.todo.create.mutationOptions({
98
+ onSuccess: () => {
99
+ todos.refetch();
100
+ setNewTodoText("");
101
+ },
102
+ })
103
+ );
104
+ const toggleMutation = useMutation(
105
+ trpc.todo.toggle.mutationOptions({
106
+ onSuccess: () => {
107
+ todos.refetch();
108
+ },
109
+ })
110
+ );
111
+ const deleteMutation = useMutation(
112
+ trpc.todo.delete.mutationOptions({
113
+ onSuccess: () => {
114
+ todos.refetch();
115
+ },
116
+ })
117
+ );
118
+ {{/if}}
119
+
120
+ function handleAddTodo() {
121
+ if (newTodoText.trim()) {
122
+ createMutation.mutate({ text: newTodoText });
123
+ }
124
+ }
125
+
126
+ function handleToggleTodo(id: number, completed: boolean) {
127
+ toggleMutation.mutate({ id, completed: !completed });
128
+ }
129
+
130
+ function handleDeleteTodo(id: number) {
131
+ Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
132
+ { text: "Cancel", style: "cancel" },
133
+ {
134
+ text: "Delete",
135
+ style: "destructive",
136
+ onPress: () => deleteMutation.mutate({ id }),
137
+ },
138
+ ]);
139
+ }
140
+
141
+ const isLoading = todos?.isLoading;
142
+ const completedCount = todos?.data?.filter((t) => t.completed).length || 0;
143
+ const totalCount = todos?.data?.length || 0;
144
+ {{/if}}
145
+
146
+ return (
147
+ <Container>
148
+ <ScrollView
149
+ style={styles.scrollView}
150
+ contentContainerStyle={styles.contentContainer}
151
+ >
152
+ <View style={styles.header}>
153
+ <View style={styles.headerRow}>
154
+ <Text style={[styles.title, { color: theme.text }]}>
155
+ Todo List
156
+ </Text>
157
+ {totalCount > 0 && (
158
+ <View style={[styles.badge, { backgroundColor: theme.primary }]}>
159
+ <Text style={styles.badgeText}>
160
+ {completedCount}/{totalCount}
161
+ </Text>
162
+ </View>
163
+ )}
164
+ </View>
165
+ </View>
166
+ <View
167
+ style={[
168
+ styles.inputCard,
169
+ { backgroundColor: theme.card, borderColor: theme.border },
170
+ ]}
171
+ >
172
+ <View style={styles.inputRow}>
173
+ <View style={styles.inputContainer}>
174
+ <TextInput
175
+ value={newTodoText}
176
+ onChangeText={setNewTodoText}
177
+ placeholder="Add a new task..."
178
+ placeholderTextColor={theme.text}
179
+ {{#unless (eq backend "convex")}}
180
+ editable={!createMutation.isPending}
181
+ {{/unless}}
182
+ onSubmitEditing={handleAddTodo}
183
+ returnKeyType="done"
184
+ style={[
185
+ styles.input,
186
+ {
187
+ color: theme.text,
188
+ borderColor: theme.border,
189
+ backgroundColor: theme.background,
190
+ },
191
+ ]}
192
+ />
193
+ </View>
194
+ <TouchableOpacity
195
+ onPress={handleAddTodo}
196
+ {{#if (eq backend "convex")}}
197
+ disabled={!newTodoText.trim()}
198
+ style={[
199
+ styles.addButton,
200
+ {
201
+ backgroundColor: !newTodoText.trim()
202
+ ? theme.border
203
+ : theme.primary,
204
+ opacity: !newTodoText.trim() ? 0.5 : 1,
205
+ },
206
+ ]}
207
+ >
208
+ <Ionicons
209
+ name="add"
210
+ size={24}
211
+ color={newTodoText.trim() ? "#ffffff" : theme.text}
212
+ />
213
+ {{else}}
214
+ disabled={createMutation.isPending || !newTodoText.trim()}
215
+ style={[
216
+ styles.addButton,
217
+ {
218
+ backgroundColor:
219
+ createMutation.isPending || !newTodoText.trim()
220
+ ? theme.border
221
+ : theme.primary,
222
+ opacity:
223
+ createMutation.isPending || !newTodoText.trim() ? 0.5 : 1,
224
+ },
225
+ ]}
226
+ >
227
+ {createMutation.isPending ? (
228
+ <ActivityIndicator size="small" color="#ffffff" />
229
+ ) : (
230
+ <Ionicons name="add" size={24} color="#ffffff" />
231
+ )}
232
+ {{/if}}
233
+ </TouchableOpacity>
234
+ </View>
235
+ </View>
236
+
237
+ {{#if (eq backend "convex")}}
238
+ {isLoading && (
239
+ <View style={styles.centerContainer}>
240
+ <ActivityIndicator size="large" color={theme.primary} />
241
+ <Text
242
+ style={[styles.loadingText, { color: theme.text, opacity: 0.7 }]}
243
+ >
244
+ Loading todos...
245
+ </Text>
246
+ </View>
247
+ )}
248
+
249
+ {todos && todos.length === 0 && !isLoading && (
250
+ <View
251
+ style={[
252
+ styles.emptyCard,
253
+ { backgroundColor: theme.card, borderColor: theme.border },
254
+ ]}
255
+ >
256
+ <Ionicons
257
+ name="checkbox-outline"
258
+ size={64}
259
+ color={theme.text}
260
+ style=\{{ opacity: 0.5, marginBottom: 16 }}
261
+ />
262
+ <Text style={[styles.emptyTitle, { color: theme.text }]}>
263
+ No todos yet
264
+ </Text>
265
+ <Text
266
+ style={[styles.emptyText, { color: theme.text, opacity: 0.7 }]}
267
+ >
268
+ Add your first task to get started!
269
+ </Text>
270
+ </View>
271
+ )}
272
+
273
+ {todos && todos.length > 0 && (
274
+ <View style={styles.todosList}>
275
+ {todos.map((todo) => (
276
+ <View
277
+ key={todo._id}
278
+ style={[
279
+ styles.todoCard,
280
+ { backgroundColor: theme.card, borderColor: theme.border },
281
+ ]}
282
+ >
283
+ <View style={styles.todoRow}>
284
+ <TouchableOpacity
285
+ onPress={() => handleToggleTodo(todo._id, todo.completed)}
286
+ style={[styles.checkbox, { borderColor: theme.border }]}
287
+ >
288
+ {todo.completed && (
289
+ <Ionicons
290
+ name="checkmark"
291
+ size={16}
292
+ color={theme.primary}
293
+ />
294
+ )}
295
+ </TouchableOpacity>
296
+ <View style={styles.todoTextContainer}>
297
+ <Text
298
+ style={[
299
+ styles.todoText,
300
+ { color: theme.text },
301
+ todo.completed && {
302
+ textDecorationLine: "line-through",
303
+ opacity: 0.5,
304
+ },
305
+ ]}
306
+ >
307
+ {todo.text}
308
+ </Text>
309
+ </View>
310
+ <TouchableOpacity
311
+ onPress={() => handleDeleteTodo(todo._id)}
312
+ style={styles.deleteButton}
313
+ >
314
+ <Ionicons
315
+ name="trash-outline"
316
+ size={24}
317
+ color={theme.notification}
318
+ />
319
+ </TouchableOpacity>
320
+ </View>
321
+ </View>
322
+ ))}
323
+ </View>
324
+ )}
325
+ {{else}}
326
+ {isLoading && (
327
+ <View style={styles.centerContainer}>
328
+ <ActivityIndicator size="large" color={theme.primary} />
329
+ <Text
330
+ style={[styles.loadingText, { color: theme.text, opacity: 0.7 }]}
331
+ >
332
+ Loading todos...
333
+ </Text>
334
+ </View>
335
+ )}
336
+
337
+ {todos?.data && todos.data.length === 0 && !isLoading && (
338
+ <View
339
+ style={[
340
+ styles.emptyCard,
341
+ { backgroundColor: theme.card, borderColor: theme.border },
342
+ ]}
343
+ >
344
+ <Ionicons
345
+ name="checkbox-outline"
346
+ size={64}
347
+ color={theme.text}
348
+ style=\{{ opacity: 0.5, marginBottom: 16 }}
349
+ />
350
+ <Text style={[styles.emptyTitle, { color: theme.text }]}>
351
+ No todos yet
352
+ </Text>
353
+ <Text
354
+ style={[styles.emptyText, { color: theme.text, opacity: 0.7 }]}
355
+ >
356
+ Add your first task to get started!
357
+ </Text>
358
+ </View>
359
+ )}
360
+
361
+ {todos?.data && todos.data.length > 0 && (
362
+ <View style={styles.todosList}>
363
+ {todos.data.map((todo) => (
364
+ <View
365
+ key={todo.id}
366
+ style={[
367
+ styles.todoCard,
368
+ { backgroundColor: theme.card, borderColor: theme.border },
369
+ ]}
370
+ >
371
+ <View style={styles.todoRow}>
372
+ <TouchableOpacity
373
+ onPress={() => handleToggleTodo(todo.id, todo.completed)}
374
+ style={[styles.checkbox, { borderColor: theme.border }]}
375
+ >
376
+ {todo.completed && (
377
+ <Ionicons
378
+ name="checkmark"
379
+ size={16}
380
+ color={theme.primary}
381
+ />
382
+ )}
383
+ </TouchableOpacity>
384
+ <View style={styles.todoTextContainer}>
385
+ <Text
386
+ style={[
387
+ styles.todoText,
388
+ { color: theme.text },
389
+ todo.completed && {
390
+ textDecorationLine: "line-through",
391
+ opacity: 0.5,
392
+ },
393
+ ]}
394
+ >
395
+ {todo.text}
396
+ </Text>
397
+ </View>
398
+ <TouchableOpacity
399
+ onPress={() => handleDeleteTodo(todo.id)}
400
+ style={styles.deleteButton}
401
+ >
402
+ <Ionicons
403
+ name="trash-outline"
404
+ size={24}
405
+ color={theme.notification}
406
+ />
407
+ </TouchableOpacity>
408
+ </View>
409
+ </View>
410
+ ))}
411
+ </View>
412
+ )}
413
+ {{/if}}
414
+ </ScrollView>
415
+ </Container>
416
+ );
417
+ }
418
+
419
+ const styles = StyleSheet.create({
420
+ scrollView: {
421
+ flex: 1,
422
+ },
423
+ contentContainer: {
424
+ padding: 16,
425
+ },
426
+ header: {
427
+ marginBottom: 16,
428
+ },
429
+ headerRow: {
430
+ flexDirection: "row",
431
+ alignItems: "center",
432
+ justifyContent: "space-between",
433
+ },
434
+ title: {
435
+ fontSize: 24,
436
+ fontWeight: "bold",
437
+ },
438
+ badge: {
439
+ paddingHorizontal: 8,
440
+ paddingVertical: 4,
441
+ },
442
+ badgeText: {
443
+ color: "#ffffff",
444
+ fontSize: 12,
445
+ },
446
+ inputCard: {
447
+ borderWidth: 1,
448
+ padding: 12,
449
+ marginBottom: 16,
450
+ },
451
+ inputRow: {
452
+ flexDirection: "row",
453
+ alignItems: "center",
454
+ gap: 8,
455
+ },
456
+ inputContainer: {
457
+ flex: 1,
458
+ },
459
+ input: {
460
+ borderWidth: 1,
461
+ padding: 12,
462
+ fontSize: 16,
463
+ },
464
+ addButton: {
465
+ padding: 12,
466
+ justifyContent: "center",
467
+ alignItems: "center",
468
+ },
469
+ centerContainer: {
470
+ alignItems: "center",
471
+ justifyContent: "center",
472
+ paddingVertical: 32,
473
+ },
474
+ loadingText: {
475
+ marginTop: 16,
476
+ fontSize: 14,
477
+ },
478
+ emptyCard: {
479
+ borderWidth: 1,
480
+ padding: 32,
481
+ alignItems: "center",
482
+ justifyContent: "center",
483
+ },
484
+ emptyTitle: {
485
+ fontSize: 16,
486
+ fontWeight: "bold",
487
+ marginBottom: 8,
488
+ },
489
+ emptyText: {
490
+ fontSize: 14,
491
+ textAlign: "center",
492
+ },
493
+ todosList: {
494
+ gap: 8,
495
+ },
496
+ todoCard: {
497
+ borderWidth: 1,
498
+ padding: 12,
499
+ },
500
+ todoRow: {
501
+ flexDirection: "row",
502
+ alignItems: "center",
503
+ gap: 12,
504
+ },
505
+ checkbox: {
506
+ width: 20,
507
+ height: 20,
508
+ borderWidth: 2,
509
+ justifyContent: "center",
510
+ alignItems: "center",
511
+ },
512
+ todoTextContainer: {
513
+ flex: 1,
514
+ },
515
+ todoText: {
516
+ fontSize: 16,
517
+ },
518
+ deleteButton: {
519
+ padding: 8,
520
+ },
521
+ });