2026-04-19 16:29:13 +02:00
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
|
|
struct PrimaryActionStyle: ButtonStyle {
|
|
|
|
|
func makeBody(configuration: Configuration) -> some View {
|
|
|
|
|
configuration.label
|
2026-04-19 21:50:03 +02:00
|
|
|
.font(.footnote.weight(.semibold))
|
2026-04-19 16:29:13 +02:00
|
|
|
.frame(maxWidth: .infinity)
|
|
|
|
|
.padding(.horizontal, 12)
|
2026-04-19 21:50:03 +02:00
|
|
|
.padding(.vertical, 10)
|
|
|
|
|
.foregroundStyle(Color.idpPrimaryForeground)
|
2026-04-19 16:29:13 +02:00
|
|
|
.background(
|
|
|
|
|
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
|
2026-04-19 21:50:03 +02:00
|
|
|
.fill(Color.idpPrimary)
|
2026-04-19 16:29:13 +02:00
|
|
|
)
|
2026-04-19 21:50:03 +02:00
|
|
|
.opacity(configuration.isPressed ? 0.85 : 1)
|
2026-04-19 16:29:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct SecondaryActionStyle: ButtonStyle {
|
|
|
|
|
func makeBody(configuration: Configuration) -> some View {
|
|
|
|
|
configuration.label
|
2026-04-19 21:50:03 +02:00
|
|
|
.font(.footnote.weight(.semibold))
|
2026-04-19 16:29:13 +02:00
|
|
|
.frame(maxWidth: .infinity)
|
|
|
|
|
.padding(.horizontal, 12)
|
2026-04-19 21:50:03 +02:00
|
|
|
.padding(.vertical, 10)
|
|
|
|
|
.foregroundStyle(.white)
|
2026-04-19 16:29:13 +02:00
|
|
|
.background(
|
|
|
|
|
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
|
2026-04-19 21:50:03 +02:00
|
|
|
.fill(Color.clear)
|
2026-04-19 16:29:13 +02:00
|
|
|
)
|
|
|
|
|
.overlay(
|
|
|
|
|
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
|
2026-04-19 21:50:03 +02:00
|
|
|
.stroke(Color.white.opacity(0.22), lineWidth: 1)
|
2026-04-19 16:29:13 +02:00
|
|
|
)
|
2026-04-19 21:50:03 +02:00
|
|
|
.opacity(configuration.isPressed ? 0.7 : 1)
|
2026-04-19 16:29:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct DestructiveStyle: ButtonStyle {
|
|
|
|
|
func makeBody(configuration: Configuration) -> some View {
|
|
|
|
|
configuration.label
|
2026-04-19 21:50:03 +02:00
|
|
|
.font(.footnote.weight(.semibold))
|
2026-04-19 16:29:13 +02:00
|
|
|
.frame(maxWidth: .infinity)
|
|
|
|
|
.padding(.horizontal, 12)
|
2026-04-19 21:50:03 +02:00
|
|
|
.padding(.vertical, 10)
|
|
|
|
|
.foregroundStyle(.white)
|
2026-04-19 16:29:13 +02:00
|
|
|
.background(
|
|
|
|
|
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
|
2026-04-19 21:50:03 +02:00
|
|
|
.fill(Color.idpDestructive)
|
2026-04-19 16:29:13 +02:00
|
|
|
)
|
2026-04-19 21:50:03 +02:00
|
|
|
.opacity(configuration.isPressed ? 0.85 : 1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct WatchBadge: View {
|
|
|
|
|
enum Tone {
|
|
|
|
|
case neutral
|
|
|
|
|
case accent
|
|
|
|
|
case ok
|
|
|
|
|
case warn
|
|
|
|
|
case danger
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let title: String
|
|
|
|
|
var tone: Tone = .neutral
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
Text(title)
|
|
|
|
|
.font(.system(size: 9, weight: .bold))
|
|
|
|
|
.tracking(0.5)
|
|
|
|
|
.foregroundStyle(foreground)
|
|
|
|
|
.padding(.horizontal, 6)
|
|
|
|
|
.padding(.vertical, 2)
|
|
|
|
|
.background(background, in: Capsule(style: .continuous))
|
2026-04-19 16:29:13 +02:00
|
|
|
.overlay(
|
2026-04-19 21:50:03 +02:00
|
|
|
Capsule(style: .continuous)
|
|
|
|
|
.stroke(stroke, lineWidth: 1)
|
2026-04-19 16:29:13 +02:00
|
|
|
)
|
2026-04-19 21:50:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private var foreground: Color {
|
|
|
|
|
switch tone {
|
|
|
|
|
case .neutral: return Color.idpMutedForeground
|
|
|
|
|
case .accent: return IdP.tint
|
|
|
|
|
case .ok: return Color.idpOK
|
|
|
|
|
case .warn: return Color.idpWarn
|
|
|
|
|
case .danger: return Color.idpDestructive
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private var background: Color {
|
|
|
|
|
switch tone {
|
|
|
|
|
case .neutral: return Color.white.opacity(0.05)
|
|
|
|
|
default: return .clear
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private var stroke: Color {
|
|
|
|
|
switch tone {
|
|
|
|
|
case .accent: return IdP.tint.opacity(0.45)
|
|
|
|
|
case .ok: return Color.idpOK.opacity(0.45)
|
|
|
|
|
case .warn: return Color.idpWarn.opacity(0.45)
|
|
|
|
|
case .danger: return Color.idpDestructive.opacity(0.55)
|
|
|
|
|
case .neutral: return .clear
|
|
|
|
|
}
|
2026-04-19 16:29:13 +02:00
|
|
|
}
|
|
|
|
|
}
|