CasinoGames/Baccarat/Views/ChipSelectorView.swift

80 lines
2.6 KiB
Swift

//
// ChipSelectorView.swift
// Baccarat
//
// Horizontal chip selector for choosing bet denomination.
//
import SwiftUI
/// A horizontal scrollable chip selector.
/// Shows chips based on current balance - higher denomination chips unlock as you win more!
struct ChipSelectorView: View {
@Binding var selectedChip: ChipDenomination
let balance: Int
let maxBet: Int
init(selectedChip: Binding<ChipDenomination>, balance: Int, maxBet: Int = 100_000) {
self._selectedChip = selectedChip
self.balance = balance
self.maxBet = maxBet
}
/// Chips that are unlocked based on current balance.
private var availableChips: [ChipDenomination] {
ChipDenomination.availableChips(forBalance: balance)
.filter { $0.rawValue <= maxBet } // Don't show chips larger than max bet
}
var body: some View {
ScrollView(.horizontal) {
HStack(spacing: Design.Spacing.small) {
ForEach(availableChips) { denomination in
Button {
selectedChip = denomination
} label: {
ChipView(
denomination: denomination,
size: Design.Size.chipSelector,
isSelected: selectedChip == denomination
)
}
.buttonStyle(.plain)
.opacity(balance >= denomination.rawValue ? 1.0 : Design.Opacity.overlay)
.disabled(balance < denomination.rawValue)
}
}
.padding(.horizontal)
.padding(.vertical, Design.Spacing.small) // Extra padding for selection scale effect (1.1x)
}
.scrollIndicators(.hidden)
.onChange(of: balance) { _, newBalance in
// Auto-select highest affordable chip if current selection is now too expensive
if newBalance < selectedChip.rawValue {
if let affordable = availableChips.last(where: { newBalance >= $0.rawValue }) {
selectedChip = affordable
}
}
}
}
}
#Preview {
ZStack {
Color.Table.preview
.ignoresSafeArea()
VStack(spacing: Design.Spacing.xLarge) {
Text("Balance: $50,000")
.foregroundStyle(.white)
ChipSelectorView(
selectedChip: .constant(.fiveThousand),
balance: 50_000,
maxBet: 50_000
)
}
}
}