79 lines
2.4 KiB
Swift
79 lines
2.4 KiB
Swift
import SwiftUI
|
|
|
|
/// Shared geometry for the window shell and data pages. Colors and controls
|
|
/// follow the system appearance, including accessibility contrast settings.
|
|
enum PuterLayout {
|
|
static let pageInset: CGFloat = 20
|
|
static let sectionSpacing: CGFloat = 16
|
|
static let controlSpacing: CGFloat = 8
|
|
static let compactSidebarWidth: CGFloat = 84
|
|
static let expandedSidebarWidth: CGFloat = 210
|
|
static let sidebarRowHeight: CGFloat = 28
|
|
static let toolbarControlHeight: CGFloat = 36
|
|
}
|
|
|
|
enum PuterAppearance: String, CaseIterable, Identifiable {
|
|
case system = "System"
|
|
case light = "Light"
|
|
case dark = "Dark"
|
|
|
|
var id: String { rawValue }
|
|
|
|
var colorScheme: ColorScheme? {
|
|
switch self {
|
|
case .system: nil
|
|
case .light: .light
|
|
case .dark: .dark
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A single navigation surface; data views deliberately do not use glass.
|
|
struct NavigationGlass: ViewModifier {
|
|
@Environment(\.accessibilityReduceTransparency) private var reduceTransparency
|
|
|
|
@ViewBuilder func body(content: Content) -> some View {
|
|
if reduceTransparency {
|
|
content.background(.background, in: .rect(cornerRadius: 16))
|
|
} else if #available(macOS 26, *) {
|
|
content.glassEffect(.regular, in: .rect(cornerRadius: 16))
|
|
} else {
|
|
content.background(.regularMaterial, in: .rect(cornerRadius: 16))
|
|
}
|
|
}
|
|
}
|
|
|
|
struct GlassActions<Content: View>: View {
|
|
@ViewBuilder var content: () -> Content
|
|
|
|
var body: some View {
|
|
if #available(macOS 26, *) {
|
|
GlassEffectContainer(spacing: 8) {
|
|
content()
|
|
.buttonStyle(.glass)
|
|
.buttonBorderShape(.capsule)
|
|
.controlSize(.large)
|
|
.menuStyle(.button)
|
|
}
|
|
} else {
|
|
content().buttonStyle(.bordered)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Preserve native menu semantics without the legacy pop-up button bezel.
|
|
struct GlassMenuSurface: ViewModifier {
|
|
@ViewBuilder func body(content: Content) -> some View {
|
|
if #available(macOS 26, *) {
|
|
content
|
|
.menuStyle(.borderlessButton)
|
|
.fixedSize()
|
|
.padding(.horizontal, 12)
|
|
.frame(minHeight: 32)
|
|
.glassEffect(.regular.interactive(), in: .capsule)
|
|
} else {
|
|
content.menuStyle(.button)
|
|
}
|
|
}
|
|
}
|