From 8019e7c4f020ba83bade58062e681b5306591f60 Mon Sep 17 00:00:00 2001 From: Marcusrehbock Date: Tue, 1 Sep 2026 22:57:13 +1000 Subject: [PATCH] refactor(ui): one cardEdges helper for the three list card stacks --- app/src/app/project/[id].tsx | 14 +++----------- app/src/app/today.tsx | 19 +++---------------- app/src/components/TaskListScreen.tsx | 17 ++--------------- app/src/components/ui.tsx | 17 +++++++++++++++++ 4 files changed, 25 insertions(+), 42 deletions(-) diff --git a/app/src/app/project/[id].tsx b/app/src/app/project/[id].tsx index 77effc7..8fb8377 100644 --- a/app/src/app/project/[id].tsx +++ b/app/src/app/project/[id].tsx @@ -2,10 +2,10 @@ import { Stack, useLocalSearchParams, useRouter } from "expo-router"; import { useState } from "react"; import { FlatList, Pressable, StyleSheet, Text, TextInput, View } from "react-native"; import Icon from "../../components/Icon"; -import { Button, Chips, Empty, Separator } from "../../components/ui"; +import { Button, cardEdges, Chips, Empty, Separator } from "../../components/ui"; import { haptic } from "../../lib/haptics"; import { createTask, dropProject, updateProject, updateTask } from "../../lib/store"; -import { C, radius, shadow, space, type } from "../../lib/theme"; +import { C, radius, space, type } from "../../lib/theme"; import { useStore } from "../../lib/useStore"; import type { ProjectStatus } from "../../lib/types"; @@ -60,8 +60,7 @@ export default function ProjectDetail() { [ s.row, - index === 0 && s.first, - index === tasks.length - 1 && s.last, + ...cardEdges(index, tasks.length), pressed && { backgroundColor: C.surface2 }, ]} onPress={() => router.push(`/task/${item.id}`)} @@ -122,13 +121,6 @@ const s = StyleSheet.create({ gap: space.md, paddingVertical: space.md + 2, paddingHorizontal: space.lg, - backgroundColor: C.surface, - }, - first: { borderTopLeftRadius: radius.lg, borderTopRightRadius: radius.lg }, - last: { - borderBottomLeftRadius: radius.lg, - borderBottomRightRadius: radius.lg, - ...shadow.card, }, checkbox: { width: 21, height: 21, borderRadius: 7, borderWidth: 1.5, borderColor: C.muted }, title: { ...type.row, color: C.text }, diff --git a/app/src/app/today.tsx b/app/src/app/today.tsx index 51d53e6..fec724c 100644 --- a/app/src/app/today.tsx +++ b/app/src/app/today.tsx @@ -1,8 +1,8 @@ import { SectionList, StyleSheet, View } from "react-native"; import TaskRow, { TaskSeparator } from "../components/TaskRow"; -import { Empty, SectionHeader } from "../components/ui"; +import { cardEdges, Empty, SectionHeader } from "../components/ui"; import { todayTasks } from "../lib/store"; -import { C, radius, shadow, space } from "../lib/theme"; +import { C, space } from "../lib/theme"; import { useStore } from "../lib/useStore"; export default function Today() { @@ -22,13 +22,7 @@ export default function Today() { // Each section is its own rounded card, so the first and last rows in a // section round their outer corners. renderItem={({ item, index, section }) => ( - + )} @@ -47,11 +41,4 @@ export default function Today() { const s = StyleSheet.create({ screen: { flex: 1, backgroundColor: C.bg }, content: { paddingHorizontal: space.lg, paddingBottom: 40 }, - row: { backgroundColor: C.surface }, - first: { borderTopLeftRadius: radius.lg, borderTopRightRadius: radius.lg }, - last: { - borderBottomLeftRadius: radius.lg, - borderBottomRightRadius: radius.lg, - ...shadow.card, - }, }); diff --git a/app/src/components/TaskListScreen.tsx b/app/src/components/TaskListScreen.tsx index f9ad91d..0ab2658 100644 --- a/app/src/components/TaskListScreen.tsx +++ b/app/src/components/TaskListScreen.tsx @@ -7,6 +7,7 @@ import { C, radius, shadow, space, type } from "../lib/theme"; import { useStore } from "../lib/useStore"; import type { TaskStatus } from "../lib/types"; import TaskRow, { TaskSeparator } from "./TaskRow"; +import { cardEdges } from "./ui"; // Deferred tasks are hidden from these lists until their date — you can't act // on them yet, so they shouldn't cost attention. A one-line footer keeps them @@ -57,14 +58,7 @@ export default function TaskListScreen({ const i = getIndex() ?? 0; return ( - + {children}; } +/** + * Row background plus rounded outer corners for the first and last row of a + * list, so a plain FlatList reads as one card without wrapping it in a `Card` + * (which would break drag-and-drop and section headers). + */ +export function cardEdges(index: number, count: number) { + return [u.cardRow, index === 0 && u.cardTop, index === count - 1 && u.cardBottom]; +} + /** Inset hairline for use between rows inside a `Card`. */ export function Separator({ inset = 0 }: { inset?: number }) { return ; @@ -165,6 +174,14 @@ export function Button({ const u = StyleSheet.create({ screen: { flex: 1, backgroundColor: C.bg }, + cardRow: { backgroundColor: C.surface }, + cardTop: { borderTopLeftRadius: radius.lg, borderTopRightRadius: radius.lg }, + cardBottom: { + borderBottomLeftRadius: radius.lg, + borderBottomRightRadius: radius.lg, + ...shadow.card, + }, + titleRow: { flexDirection: "row", alignItems: "center",