Bruno Pantaleão Gonçalves 2dfbe3c0e5
UI fixes for iOS 26 (#3775)
2025-08-19 21:33:36 -03:00

89 lines
2.2 KiB
Swift

import SwiftUI
public struct CloseButton: View {
public enum Size {
case small
case medium
case large
var size: CGFloat {
if Current.isCatalyst {
switch self {
case .small:
return 24
case .medium:
return 28
case .large:
return 32
}
} else {
switch self {
case .small:
return 20
case .medium:
return 24
case .large:
return 28
}
}
}
}
@Environment(\.dismiss) private var dismiss
private let alternativeAction: (() -> Void)?
private let tint: Color
private let size: Size
/// When alternative action is set, the button will execute this action instead of dismissing the view.
public init(
tint: Color = Color.secondary,
size: Size = .small,
alternativeAction: (() -> Void)? = nil
) {
self.alternativeAction = alternativeAction
self.tint = tint
self.size = size
}
public var body: some View {
if #available(iOS 26.0, *) {
Button(role: .close) {
tapAction()
}
} else {
Button(action: {
tapAction()
}, label: {
Image(systemSymbol: .xmarkCircleFill)
.resizable()
.frame(width: size.size, height: size.size)
.foregroundStyle(tint)
})
.buttonStyle(.plain)
}
}
private func tapAction() {
if let alternativeAction {
alternativeAction()
} else {
dismiss()
}
}
}
#Preview {
VStack {
CloseButton {}
.frame(maxWidth: .infinity, alignment: .trailing)
.padding()
CloseButton(size: .medium) {}
.frame(maxWidth: .infinity, alignment: .trailing)
.padding()
CloseButton(size: .large) {}
.frame(maxWidth: .infinity, alignment: .trailing)
.padding()
Spacer()
}
}