ui: make Featured Trips carousel scroll edge-to-edge
Use contentMargins on horizontal ScrollView so cards start inset but scroll to screen edges. Pad headers and error states individually. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -189,6 +189,7 @@ struct HomeView: View {
|
|||||||
.foregroundStyle(Theme.warmOrange)
|
.foregroundStyle(Theme.warmOrange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
|
|
||||||
// Horizontal carousel grouped by region
|
// Horizontal carousel grouped by region
|
||||||
ScrollView(.horizontal, showsIndicators: false) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
@@ -218,8 +219,8 @@ struct HomeView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 1) // Prevent clipping
|
|
||||||
}
|
}
|
||||||
|
.contentMargins(.horizontal, Theme.Spacing.md, for: .scrollContent)
|
||||||
}
|
}
|
||||||
} else if let error = suggestedTripsGenerator.error {
|
} else if let error = suggestedTripsGenerator.error {
|
||||||
// Error state
|
// Error state
|
||||||
@@ -249,6 +250,7 @@ struct HomeView: View {
|
|||||||
.background(Theme.cardBackground(colorScheme))
|
.background(Theme.cardBackground(colorScheme))
|
||||||
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ struct LoadingTripsView: View {
|
|||||||
.foregroundStyle(Theme.textPrimary(colorScheme))
|
.foregroundStyle(Theme.textPrimary(colorScheme))
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
|
|
||||||
// Loading indicator with message
|
// Loading indicator with message
|
||||||
LoadingSpinner(size: .small, label: message)
|
LoadingSpinner(size: .small, label: message)
|
||||||
.padding(.vertical, Theme.Spacing.xs)
|
.padding(.vertical, Theme.Spacing.xs)
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
|
|
||||||
// Placeholder cards
|
// Placeholder cards
|
||||||
ScrollView(.horizontal, showsIndicators: false) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
@@ -33,6 +35,7 @@ struct LoadingTripsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.contentMargins(.horizontal, Theme.Spacing.md, for: .scrollContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ struct HomeContent_Classic: View {
|
|||||||
|
|
||||||
// Suggested Trips
|
// Suggested Trips
|
||||||
suggestedTripsSection
|
suggestedTripsSection
|
||||||
.padding(.horizontal, Theme.Spacing.md)
|
|
||||||
|
|
||||||
// Saved Trips
|
// Saved Trips
|
||||||
if !savedTrips.isEmpty {
|
if !savedTrips.isEmpty {
|
||||||
@@ -120,6 +119,7 @@ struct HomeContent_Classic: View {
|
|||||||
.foregroundStyle(Theme.warmOrange)
|
.foregroundStyle(Theme.warmOrange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
|
|
||||||
// Horizontal carousel grouped by region
|
// Horizontal carousel grouped by region
|
||||||
ScrollView(.horizontal, showsIndicators: false) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
@@ -149,8 +149,8 @@ struct HomeContent_Classic: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 1)
|
|
||||||
}
|
}
|
||||||
|
.contentMargins(.horizontal, Theme.Spacing.md, for: .scrollContent)
|
||||||
}
|
}
|
||||||
} else if let error = suggestedTripsGenerator.error {
|
} else if let error = suggestedTripsGenerator.error {
|
||||||
// Error state
|
// Error state
|
||||||
@@ -180,6 +180,7 @@ struct HomeContent_Classic: View {
|
|||||||
.background(Theme.cardBackground(colorScheme))
|
.background(Theme.cardBackground(colorScheme))
|
||||||
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ struct HomeContent_ClassicAnimated: View {
|
|||||||
|
|
||||||
// Suggested Trips
|
// Suggested Trips
|
||||||
suggestedTripsSection
|
suggestedTripsSection
|
||||||
.padding(.horizontal, Theme.Spacing.md)
|
|
||||||
|
|
||||||
// Saved Trips
|
// Saved Trips
|
||||||
if !savedTrips.isEmpty {
|
if !savedTrips.isEmpty {
|
||||||
@@ -119,6 +118,7 @@ struct HomeContent_ClassicAnimated: View {
|
|||||||
.foregroundStyle(Theme.warmOrange)
|
.foregroundStyle(Theme.warmOrange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
|
|
||||||
// Horizontal carousel grouped by region
|
// Horizontal carousel grouped by region
|
||||||
ScrollView(.horizontal, showsIndicators: false) {
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
@@ -148,8 +148,8 @@ struct HomeContent_ClassicAnimated: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 1)
|
|
||||||
}
|
}
|
||||||
|
.contentMargins(.horizontal, Theme.Spacing.md, for: .scrollContent)
|
||||||
}
|
}
|
||||||
} else if let error = suggestedTripsGenerator.error {
|
} else if let error = suggestedTripsGenerator.error {
|
||||||
// Error state
|
// Error state
|
||||||
@@ -179,6 +179,7 @@ struct HomeContent_ClassicAnimated: View {
|
|||||||
.background(Theme.cardBackground(colorScheme))
|
.background(Theme.cardBackground(colorScheme))
|
||||||
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
.clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal, Theme.Spacing.md)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user