| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- // LoopFollow
- // AppBannerView.swift
- import SwiftUI
- /// Dismissable banner shown at the top of the app, above the tab content.
- struct AppBannerView: View {
- let message: BannerMessage
- var body: some View {
- HStack(alignment: .top, spacing: 12) {
- Image(systemName: iconName)
- .font(.title3)
- .foregroundColor(iconColor)
- Text(message.text)
- .font(.callout)
- .lineLimit(3)
- .fixedSize(horizontal: false, vertical: true)
- .frame(maxWidth: .infinity, alignment: .leading)
- Button {
- BannerManager.shared.dismissCurrent()
- } label: {
- Image(systemName: "xmark.circle.fill")
- .font(.title3)
- .foregroundColor(.secondary)
- }
- .accessibilityLabel("Dismiss")
- }
- .padding()
- .background(
- RoundedRectangle(cornerRadius: 12, style: .continuous)
- .fill(tint)
- )
- .overlay(
- RoundedRectangle(cornerRadius: 12, style: .continuous)
- .stroke(border, lineWidth: 1)
- )
- .padding(.horizontal, 10)
- .padding(.vertical, 4)
- }
- private var iconName: String {
- switch message.severity {
- case .info: return "info.circle.fill"
- case .warning: return "exclamationmark.triangle.fill"
- case .error: return "xmark.octagon.fill"
- }
- }
- private var iconColor: Color {
- switch message.severity {
- case .info: return .blue
- case .warning: return .orange
- case .error: return .red
- }
- }
- private var tint: Color {
- switch message.severity {
- case .info: return Color.blue.opacity(0.20)
- case .warning: return Color.orange.opacity(0.20)
- case .error: return Color.red.opacity(0.20)
- }
- }
- private var border: Color {
- switch message.severity {
- case .info: return Color.blue.opacity(0.40)
- case .warning: return Color.orange.opacity(0.40)
- case .error: return Color.red.opacity(0.40)
- }
- }
- }
|