mirror of
https://github.com/yattee/yattee.git
synced 2026-04-10 17:46:58 +00:00
Yattee v2 rewrite
This commit is contained in:
127
Yattee/Views/Components/VideoListContent.swift
Normal file
127
Yattee/Views/Components/VideoListContent.swift
Normal file
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// VideoListContent.swift
|
||||
// Yattee
|
||||
//
|
||||
// Handles inset/plain list styling without ScrollView wrapper.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// A container that applies inset card or plain styling to list content.
|
||||
///
|
||||
/// Unlike `VideoListContainer`, this component does NOT wrap content in a ScrollView.
|
||||
/// Use this when the parent view already has its own ScrollView with additional content
|
||||
/// (tabs, headers, etc.).
|
||||
///
|
||||
/// Usage:
|
||||
/// ```swift
|
||||
/// ScrollView {
|
||||
/// VStack(spacing: 0) {
|
||||
/// tabPicker
|
||||
///
|
||||
/// VideoListContent(listStyle: listStyle) {
|
||||
/// ForEach(Array(videos.enumerated()), id: \.element.id) { index, video in
|
||||
/// VideoListRow(
|
||||
/// isLast: index == videos.count - 1,
|
||||
/// rowStyle: rowStyle,
|
||||
/// listStyle: listStyle
|
||||
/// ) {
|
||||
/// VideoRowView(video: video, style: rowStyle)
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
struct VideoListContent<Content: View>: View {
|
||||
let listStyle: VideoListStyle
|
||||
|
||||
@ViewBuilder let content: () -> Content
|
||||
|
||||
/// Corner radius for card container in inset style.
|
||||
private let cardCornerRadius: CGFloat = 10
|
||||
|
||||
/// Horizontal padding for card container.
|
||||
private let cardHorizontalPadding: CGFloat = 16
|
||||
|
||||
/// Bottom padding for content.
|
||||
private let bottomPadding: CGFloat = 16
|
||||
|
||||
var body: some View {
|
||||
let list = LazyVStack(spacing: 0) {
|
||||
content()
|
||||
}
|
||||
|
||||
if listStyle == .inset {
|
||||
list
|
||||
.background(ListBackgroundStyle.card.color)
|
||||
.clipShape(RoundedRectangle(cornerRadius: cardCornerRadius))
|
||||
.padding(.horizontal, cardHorizontalPadding)
|
||||
.padding(.bottom, bottomPadding)
|
||||
} else {
|
||||
list
|
||||
.padding(.bottom, bottomPadding)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Preview
|
||||
|
||||
#Preview("Inset Style") {
|
||||
ScrollView {
|
||||
VideoListContent(listStyle: .inset) {
|
||||
ForEach(0..<5) { index in
|
||||
VideoListRow(
|
||||
isLast: index == 4,
|
||||
rowStyle: .regular,
|
||||
listStyle: .inset
|
||||
) {
|
||||
HStack(spacing: 12) {
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 120, height: 68)
|
||||
VStack(alignment: .leading) {
|
||||
Text("Video Title \(index + 1)")
|
||||
.font(.subheadline)
|
||||
Text("Channel Name")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if os(iOS)
|
||||
.background(Color(uiColor: .systemGroupedBackground))
|
||||
#endif
|
||||
}
|
||||
|
||||
#Preview("Plain Style") {
|
||||
ScrollView {
|
||||
VideoListContent(listStyle: .plain) {
|
||||
ForEach(0..<5) { index in
|
||||
VideoListRow(
|
||||
isLast: index == 4,
|
||||
rowStyle: .regular,
|
||||
listStyle: .plain
|
||||
) {
|
||||
HStack(spacing: 12) {
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(width: 120, height: 68)
|
||||
VStack(alignment: .leading) {
|
||||
Text("Video Title \(index + 1)")
|
||||
.font(.subheadline)
|
||||
Text("Channel Name")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user