← All repositories

listless

A simple list app for Apple platforms

git clone https://code.inqk.net/listless.git


commit edcc9fdb76d8a4b9dd19c97286a98953c16de071
parent cc89aadad02adbe78696fedc38362c7c21b1f1ce
Author: Michael Camilleri <[email protected]>
Date:   Tue,  3 Mar 2026 08:30:27 +0900

Use shadow/glow for selection state on iOS

Previous to this commit, selection state was indicated by a stroke
around the outside of the active task (there was no way to indicate
selection state for a completed task). This commit uses shadows (in
light mode) and glows (in dark mode) instead. It uses a different
background for completed tasks.

Co-Authored-By: Claude 4.6 Opus <[email protected]>

Diffstat

MListlessiOS/Helpers/AppColors.swift | 21+++++++++++++++++++++
MListlessiOS/Views/TaskRowView.swift | 28+++++++++++++---------------

2 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/ListlessiOS/Helpers/AppColors.swift b/ListlessiOS/Helpers/AppColors.swift

@@ -13,4 +13,25 @@ extension Color {
     static let taskCard = Color(uiColor: UIColor { traits in
         traits.userInterfaceStyle == .dark ? UIColor.secondarySystemBackground : .white
     })
+
+    /// Selected background for completed rows.
+    static let completedSelected = Color(uiColor: UIColor { traits in
+        traits.userInterfaceStyle == .dark
+            ? UIColor(white: 0.12, alpha: 1)
+            : UIColor(red: 0.88, green: 0.86, blue: 0.83, alpha: 1)
+    })
+
+    /// Drop shadow for selected active cards in light mode.
+    static let selectionShadowLight = Color(uiColor: UIColor { traits in
+        traits.userInterfaceStyle == .dark
+            ? .clear
+            : UIColor(white: 0.0, alpha: 0.15)
+    })
+
+    /// Glow for selected active cards in dark mode.
+    static let selectionShadowDark = Color(uiColor: UIColor { traits in
+        traits.userInterfaceStyle == .dark
+            ? UIColor(red: 1.0, green: 0.95, blue: 0.5, alpha: 0.2)
+            : .clear
+    })
 }

diff --git a/ListlessiOS/Views/TaskRowView.swift b/ListlessiOS/Views/TaskRowView.swift

@@ -122,20 +122,10 @@ struct TaskRowView: View {
         .clipShape(
             UnevenRoundedRectangle(
                 topLeadingRadius: 0, bottomLeadingRadius: 0,
-                bottomTrailingRadius: task.isCompleted ? 0 : TaskRowMetrics.trailingCornerRadius,
-                topTrailingRadius: task.isCompleted ? 0 : TaskRowMetrics.trailingCornerRadius
+                bottomTrailingRadius: TaskRowMetrics.trailingCornerRadius,
+                topTrailingRadius: TaskRowMetrics.trailingCornerRadius
             )
         )
-        .overlay {
-            if isSelected && !task.isCompleted {
-                UnevenRoundedRectangle(
-                    topLeadingRadius: 0, bottomLeadingRadius: 0,
-                    bottomTrailingRadius: TaskRowMetrics.trailingCornerRadius,
-                    topTrailingRadius: TaskRowMetrics.trailingCornerRadius
-                )
-                .strokeBorder(Color.accentColor, lineWidth: 2)
-            }
-        }
         .overlay(alignment: .leading) {
             if !task.isCompleted {
                 Rectangle()
@@ -177,10 +167,18 @@ struct TaskRowView: View {
         .clipShape(
             UnevenRoundedRectangle(
                 topLeadingRadius: 0, bottomLeadingRadius: 0,
-                bottomTrailingRadius: task.isCompleted ? 0 : TaskRowMetrics.trailingCornerRadius,
-                topTrailingRadius: task.isCompleted ? 0 : TaskRowMetrics.trailingCornerRadius
+                bottomTrailingRadius: TaskRowMetrics.trailingCornerRadius,
+                topTrailingRadius: TaskRowMetrics.trailingCornerRadius
             )
         )
+        .shadow(
+            color: isSelected && !task.isCompleted ? .selectionShadowLight : .clear,
+            radius: 4, x: 0, y: 2
+        )
+        .shadow(
+            color: isSelected && !task.isCompleted ? .selectionShadowDark : .clear,
+            radius: 10, x: 0, y: 0
+        )
     }
 
     @MainActor
@@ -192,7 +190,7 @@ struct TaskRowView: View {
     @ViewBuilder
     private var cardBackground: some View {
         if task.isCompleted {
-            Color.clear
+            isSelected ? Color.completedSelected : Color.clear
         } else {
             Color.taskCard
         }