mirror of
https://github.com/yattee/yattee.git
synced 2026-10-25 06:02:57 +00:00
The corner layout side column puts a 12pt resize grabber strip before the panel, and every page then added the standard 16pt horizontal padding, so content sat ~28pt from the left edge but 16pt from the right. Add a PanelHorizontalInsets environment value with a panelHorizontalPadding() modifier that the info, comments, related and chapters pages use instead of .padding(.horizontal). The side column trims the leading inset by the grabber width so content is 16pt from the column's outer edge on both sides; other hosts keep the defaults. Queue and tracks are List-backed and get the same leading delta as a scroll content margin. The page bar follows the same insets so the first pill lines up with the content.
81 lines
2.5 KiB
Swift
81 lines
2.5 KiB
Swift
//
|
|
// PanelPageBar.swift
|
|
// Yattee
|
|
//
|
|
// Scrolling pill row for switching details panel pages.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
#if os(iOS) || os(macOS)
|
|
|
|
struct PanelPageBar: View {
|
|
let pages: [PanelPageConfiguration]
|
|
@Binding var selectedPage: PanelPageType
|
|
let accentColor: Color
|
|
var showLabels: Bool = true
|
|
|
|
@Environment(\.panelHorizontalInsets) private var insets
|
|
|
|
/// Pills sit 4pt closer to the edge than page content (12 vs 16 with the
|
|
/// standard inset); a host that trims the content inset (corner side
|
|
/// column) trims the bar the same way so the first pill lines up.
|
|
private static let pillEdgeOffset: CGFloat = 4
|
|
|
|
var body: some View {
|
|
ScrollViewReader { proxy in
|
|
ScrollView(.horizontal, showsIndicators: false) {
|
|
HStack(spacing: 8) {
|
|
ForEach(pages) { page in
|
|
pageButton(page.pageType)
|
|
.id(page.pageType)
|
|
}
|
|
}
|
|
.padding(.leading, max(0, insets.leading - Self.pillEdgeOffset))
|
|
.padding(.trailing, max(0, insets.trailing - Self.pillEdgeOffset))
|
|
.padding(.vertical, 6)
|
|
}
|
|
.onChange(of: selectedPage) { _, newValue in
|
|
withAnimation(.easeInOut(duration: 0.2)) {
|
|
proxy.scrollTo(newValue, anchor: .center)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func pageButton(_ pageType: PanelPageType) -> some View {
|
|
let isSelected = pageType == selectedPage
|
|
|
|
Button {
|
|
withAnimation(.easeInOut(duration: 0.2)) {
|
|
selectedPage = pageType
|
|
}
|
|
} label: {
|
|
HStack(spacing: 5) {
|
|
Image(systemName: pageType.systemImage)
|
|
.font(.system(size: 13, weight: .medium))
|
|
|
|
if showLabels || isSelected {
|
|
Text(pageType.displayName)
|
|
.font(.subheadline)
|
|
.fontWeight(.medium)
|
|
.lineLimit(1)
|
|
.fixedSize()
|
|
}
|
|
}
|
|
.foregroundStyle(isSelected ? Color.white : Color.primary)
|
|
.padding(.horizontal, 12)
|
|
.padding(.vertical, 7)
|
|
.background {
|
|
Capsule()
|
|
.fill(isSelected ? AnyShapeStyle(accentColor) : AnyShapeStyle(.quaternary.opacity(0.6)))
|
|
}
|
|
.contentShape(Capsule())
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
|
|
#endif
|