fix: keep pill selector + swipeable pages (Quick Add first)
Pill tabs (Quick Add / AI Chat) stay visible and tappable. Pages are also swipeable. Pills sync with swipe position. Quick Add shown first, swipe left for AI Chat. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -180,13 +180,12 @@ struct MainTabView: View {
|
|||||||
// MARK: - Assistant Sheet
|
// MARK: - Assistant Sheet
|
||||||
|
|
||||||
struct AssistantSheetView: View {
|
struct AssistantSheetView: View {
|
||||||
@State private var selectedPage = 0
|
@State private var selectedMode = 0
|
||||||
var onFoodAdded: () -> Void = {}
|
var onFoodAdded: () -> Void = {}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
// Drag handle + title
|
VStack(spacing: 12) {
|
||||||
VStack(spacing: 8) {
|
|
||||||
Capsule()
|
Capsule()
|
||||||
.fill(Color.textTertiary.opacity(0.3))
|
.fill(Color.textTertiary.opacity(0.3))
|
||||||
.frame(width: 36, height: 5)
|
.frame(width: 36, height: 5)
|
||||||
@@ -196,21 +195,21 @@ struct AssistantSheetView: View {
|
|||||||
.font(.headline)
|
.font(.headline)
|
||||||
.foregroundStyle(Color.textPrimary)
|
.foregroundStyle(Color.textPrimary)
|
||||||
|
|
||||||
// Page indicator dots
|
// Pill selector — tappable, syncs with swipe
|
||||||
HStack(spacing: 6) {
|
HStack(spacing: 4) {
|
||||||
Circle()
|
tabPill("Quick Add", icon: "magnifyingglass", index: 0)
|
||||||
.fill(selectedPage == 0 ? Color.accentWarm : Color.textTertiary.opacity(0.3))
|
tabPill("AI Chat", icon: "sparkles", index: 1)
|
||||||
.frame(width: 7, height: 7)
|
|
||||||
Circle()
|
|
||||||
.fill(selectedPage == 1 ? Color.accentWarm : Color.textTertiary.opacity(0.3))
|
|
||||||
.frame(width: 7, height: 7)
|
|
||||||
}
|
}
|
||||||
.padding(.bottom, 4)
|
.padding(4)
|
||||||
|
.background(Color.textTertiary.opacity(0.08))
|
||||||
|
.clipShape(Capsule())
|
||||||
|
.padding(.horizontal, 40)
|
||||||
}
|
}
|
||||||
|
.padding(.bottom, 12)
|
||||||
.background(Color.canvas)
|
.background(Color.canvas)
|
||||||
|
|
||||||
// Swipeable pages: Quick Add first, AI Chat second
|
// Swipeable pages — Quick Add first
|
||||||
TabView(selection: $selectedPage) {
|
TabView(selection: $selectedMode) {
|
||||||
FoodSearchView(isSheet: true, onFoodAdded: onFoodAdded)
|
FoodSearchView(isSheet: true, onFoodAdded: onFoodAdded)
|
||||||
.tag(0)
|
.tag(0)
|
||||||
|
|
||||||
@@ -218,8 +217,25 @@ struct AssistantSheetView: View {
|
|||||||
.tag(1)
|
.tag(1)
|
||||||
}
|
}
|
||||||
.tabViewStyle(.page(indexDisplayMode: .never))
|
.tabViewStyle(.page(indexDisplayMode: .never))
|
||||||
|
.animation(.easeInOut(duration: 0.2), value: selectedMode)
|
||||||
}
|
}
|
||||||
.background(Color.canvas)
|
.background(Color.canvas)
|
||||||
.presentationDetents([.large])
|
.presentationDetents([.large])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func tabPill(_ title: String, icon: String, index: Int) -> some View {
|
||||||
|
Button {
|
||||||
|
withAnimation(.easeInOut(duration: 0.2)) { selectedMode = index }
|
||||||
|
} label: {
|
||||||
|
HStack(spacing: 5) {
|
||||||
|
Image(systemName: icon).font(.caption2)
|
||||||
|
Text(title).font(.subheadline.weight(selectedMode == index ? .semibold : .regular))
|
||||||
|
}
|
||||||
|
.foregroundStyle(selectedMode == index ? Color.textPrimary : Color.textTertiary)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
.background(selectedMode == index ? Color.surfaceCard : Color.clear)
|
||||||
|
.clipShape(Capsule())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user