109 lines
3.0 KiB
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)) {}
|
|
}
|
|
}
|
|
}
|
|
|