From c7659ccda30ded82e9afe3d5bc623d34a62abd63 Mon Sep 17 00:00:00 2001 From: John Burwell Date: Thu, 28 May 2026 20:49:23 -0500 Subject: [PATCH] Centralize shared card surface styling --- .../ContentUIShared.swift | 59 +++++++++++++++++++ .../ItemDetailColumnViews.swift | 6 +- .../SidebarColumnViews.swift | 11 +--- .../ConnectedDeviceSourcePickerView.swift | 4 +- 4 files changed, 65 insertions(+), 15 deletions(-) diff --git a/World Manager for Minecraft/ContentUIShared.swift b/World Manager for Minecraft/ContentUIShared.swift index 3480086..25c9f12 100644 --- a/World Manager for Minecraft/ContentUIShared.swift +++ b/World Manager for Minecraft/ContentUIShared.swift @@ -1,6 +1,65 @@ import AppKit import SwiftUI +enum AppChrome { + static let sidebarRowCornerRadius: CGFloat = 10 + static let placeholderCardCornerRadius: CGFloat = 16 + static let panelCardCornerRadius: CGFloat = 18 +} + +enum AppCardStyle { + case primaryPanel + case secondaryPanel + case placeholder + + fileprivate var cornerRadius: CGFloat { + switch self { + case .primaryPanel, .secondaryPanel: + return AppChrome.panelCardCornerRadius + case .placeholder: + return AppChrome.placeholderCardCornerRadius + } + } + + fileprivate var fillStyle: AnyShapeStyle { + switch self { + case .primaryPanel: + return AnyShapeStyle(.regularMaterial) + case .secondaryPanel: + return AnyShapeStyle(.quaternary.opacity(0.32)) + case .placeholder: + return AnyShapeStyle(.thinMaterial) + } + } +} + +private struct AppCardSurfaceModifier: ViewModifier { + let style: AppCardStyle + + func body(content: Content) -> some View { + content.background( + style.fillStyle, + in: RoundedRectangle(cornerRadius: style.cornerRadius, style: .continuous) + ) + } +} + +extension View { + func appCardSurface(_ style: AppCardStyle) -> some View { + modifier(AppCardSurfaceModifier(style: style)) + } + + func appSidebarRowSurface(isHighlighted: Bool) -> some View { + let fillStyle = isHighlighted + ? AnyShapeStyle(.secondary.opacity(0.08)) + : AnyShapeStyle(Color.clear) + return background( + fillStyle, + in: RoundedRectangle(cornerRadius: AppChrome.sidebarRowCornerRadius, style: .continuous) + ) + } +} + struct ToolbarShareButton: View { let systemImage: String let isEnabled: Bool diff --git a/World Manager for Minecraft/ItemDetailColumnViews.swift b/World Manager for Minecraft/ItemDetailColumnViews.swift index 1e2e72d..526f2c5 100644 --- a/World Manager for Minecraft/ItemDetailColumnViews.swift +++ b/World Manager for Minecraft/ItemDetailColumnViews.swift @@ -253,7 +253,7 @@ private struct SourceDetailView: View { } } .padding(18) - .background(.regularMaterial, in: RoundedRectangle(cornerRadius: 18, style: .continuous)) + .appCardSurface(.primaryPanel) } } @@ -609,7 +609,7 @@ private struct SourceDetailView: View { } } .padding(18) - .background(.regularMaterial, in: RoundedRectangle(cornerRadius: 18, style: .continuous)) + .appCardSurface(.primaryPanel) } } } @@ -1083,7 +1083,7 @@ struct ItemDetailView: View { } .frame(maxWidth: .infinity, alignment: .leading) .padding(18) - .background(.quaternary.opacity(0.32), in: RoundedRectangle(cornerRadius: 18, style: .continuous)) + .appCardSurface(.secondaryPanel) } } diff --git a/World Manager for Minecraft/SidebarColumnViews.swift b/World Manager for Minecraft/SidebarColumnViews.swift index 963f470..245b16e 100644 --- a/World Manager for Minecraft/SidebarColumnViews.swift +++ b/World Manager for Minecraft/SidebarColumnViews.swift @@ -180,7 +180,7 @@ private struct SourceHeaderRow: View { } .padding(.horizontal, 10) .padding(.vertical, 8) - .background(backgroundStyle, in: RoundedRectangle(cornerRadius: 10, style: .continuous)) + .appSidebarRowSurface(isHighlighted: isHovering && !isSelected) .contentShape(Rectangle()) .onTapGesture(perform: onSelect) .onHover { isHovering = $0 } @@ -229,15 +229,6 @@ private struct SourceHeaderRow: View { private var availabilityBadgeEmphasis: Bool { source.availability == .limited } - - private var backgroundStyle: AnyShapeStyle { - if isHovering && !isSelected { - return AnyShapeStyle(.secondary.opacity(0.08)) - } - - return AnyShapeStyle(.clear) - } - @ViewBuilder private var statusIndicator: some View { if source.isScanning { diff --git a/World Manager for Minecraft/SourceAccess/ConnectedDevice/ConnectedDeviceSourcePickerView.swift b/World Manager for Minecraft/SourceAccess/ConnectedDevice/ConnectedDeviceSourcePickerView.swift index 4db30e0..53f65b9 100644 --- a/World Manager for Minecraft/SourceAccess/ConnectedDevice/ConnectedDeviceSourcePickerView.swift +++ b/World Manager for Minecraft/SourceAccess/ConnectedDevice/ConnectedDeviceSourcePickerView.swift @@ -284,7 +284,7 @@ struct ConnectedDeviceSourcePickerView: View { .foregroundStyle(.secondary) } .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16, style: .continuous)) + .appCardSurface(.placeholder) } private func emptyState(_ title: String) -> some View { @@ -298,6 +298,6 @@ struct ConnectedDeviceSourcePickerView: View { .multilineTextAlignment(.center) } .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 16, style: .continuous)) + .appCardSurface(.placeholder) } }