Files
puter/Sources/puter/PuterStyle.swift
T
soconnor 4bfa239aa0
Build and test / macos (push) Waiting to run
Signed release / release (push) Waiting to run
Refresh puter UI, power telemetry and demand-aware monitoring
2026-09-22 20:03:16 -04:00

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)
}
}
}