~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain-ios

1 collaborator
0
1
main
58 lines · 2.2 KB Raw History
import SwiftUI

/// Visual treatment for a selectable thumbnail in a reorderable collection.
/// Only covers the rounded corner clip + selection ring; the pickup animation
/// (scale, opacity, shadow) lives at PhotoThumbnailCell's outer body so the X
/// button scales together with the photo.
struct ReorderableThumbnail: ViewModifier {
    let isSelected: Bool
    let cornerRadius: CGFloat

    func body(content: Content) -> some View {
        content
            .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
            .overlay(
                RoundedRectangle(cornerRadius: cornerRadius)
                    .stroke(Color.accentColor, lineWidth: 2.5)
                    .opacity(isSelected ? 1 : 0)
            )
    }
}

extension View {
    func reorderableThumbnail(isSelected: Bool, cornerRadius: CGFloat = 8) -> some View {
        modifier(ReorderableThumbnail(isSelected: isSelected, cornerRadius: cornerRadius))
    }
}

#Preview {
    // Show a row of thumbnails with varied colors simulating real photos,
    // plus a larger card size, to exercise both the unselected and selected
    // ring states at a glance.
    let thumbnailColors: [Color] = [.indigo, .teal, .orange, .pink]
    VStack(spacing: 20) {
        // Standard 72pt strip (unselected, selected, unselected, unselected)
        HStack(spacing: 8) {
            ForEach(Array(thumbnailColors.enumerated()), id: \.offset) { idx, color in
                RoundedRectangle(cornerRadius: 8)
                    .fill(color.opacity(0.55))
                    .frame(width: 72, height: 72)
                    .reorderableThumbnail(isSelected: idx == 1)
            }
        }

        // Larger card size — exercises the cornerRadius parameter
        HStack(spacing: 12) {
            ForEach(Array(thumbnailColors.prefix(3).enumerated()), id: \.offset) { idx, color in
                RoundedRectangle(cornerRadius: 12)
                    .fill(color.opacity(0.55))
                    .frame(width: 100, height: 100)
                    .reorderableThumbnail(isSelected: idx == 0, cornerRadius: 12)
            }
        }
    }
    .padding()
    .background(Color(.systemBackground))
    .preferredColorScheme(.dark)
    .tint(Color.accentColor)
}