CasinoGames/Blackjack/Views/Game/ActionButton.swift

109 lines
3.0 KiB
Swift

//
// ActionButton.swift
// Blackjack
//
// Reusable styled button for game actions.
//
import SwiftUI
import CasinoKit
struct ActionButton: View {
let title: String
let icon: String?
let style: ButtonStyle
let action: () -> Void
enum ButtonStyle {
case primary // Gold gradient (Deal, New Round)
case destructive // Red (Clear)
case secondary // Subtle white
case custom(Color) // Game-specific colors (Hit, Stand, etc.)
var foregroundColor: Color {
switch self {
case .primary: return .black
case .destructive, .secondary, .custom: return .white
}
}
}
init(_ title: String, icon: String? = nil, style: ButtonStyle = .primary, action: @escaping () -> Void) {
self.title = title
self.icon = icon
self.style = style
self.action = action
}
var body: some View {
Button(action: action) {
HStack(spacing: Design.Spacing.small) {
if let icon = icon {
Image(systemName: icon)
}
Text(title)
.lineLimit(1)
.minimumScaleFactor(CasinoDesign.MinScaleFactor.relaxed)
}
.font(.system(size: Design.BaseFontSize.large, weight: .semibold))
.foregroundStyle(style.foregroundColor)
.padding(.horizontal, Design.Spacing.large)
.padding(.vertical, Design.Spacing.medium)
.background(backgroundView)
}
.accessibilityLabel(title)
}
@ViewBuilder
private var backgroundView: some View {
switch style {
case .primary:
Capsule()
.fill(
LinearGradient(
colors: [Color.Button.goldLight, Color.Button.goldDark],
startPoint: .top,
endPoint: .bottom
)
)
case .destructive:
Capsule()
.fill(Color.red.opacity(Design.Opacity.heavy))
case .secondary:
Capsule()
.fill(Color.white.opacity(Design.Opacity.hint))
case .custom(let color):
Capsule()
.fill(color)
}
}
}
// MARK: - Previews
#Preview("Primary") {
ZStack {
Color.Table.felt.ignoresSafeArea()
ActionButton("Deal", icon: "play.fill", style: .primary) {}
}
}
#Preview("Destructive") {
ZStack {
Color.Table.felt.ignoresSafeArea()
ActionButton("Clear", icon: "xmark.circle", style: .destructive) {}
}
}
#Preview("Custom Colors") {
ZStack {
Color.Table.felt.ignoresSafeArea()
HStack(spacing: Design.Spacing.medium) {
ActionButton("Hit", style: .custom(Color.Button.hit)) {}
ActionButton("Stand", style: .custom(Color.Button.stand)) {}
ActionButton("Double", style: .custom(Color.Button.doubleDown)) {}
}
}
}