diff --git a/Baccarat/Baccarat/Views/Game/GameTableView.swift b/Baccarat/Baccarat/Views/Game/GameTableView.swift index 9a913ff..f30ada8 100644 --- a/Baccarat/Baccarat/Views/Game/GameTableView.swift +++ b/Baccarat/Baccarat/Views/Game/GameTableView.swift @@ -135,7 +135,6 @@ struct GameTableView: View { balance: state.balance, secondaryInfo: settings.showCardsRemaining ? "\(state.engine.shoe.cardsRemaining)" : nil, secondaryIcon: settings.showCardsRemaining ? "rectangle.portrait.on.rectangle.portrait.fill" : nil, - showReset: false, onSettings: { showSettings = true }, onHelp: { showRules = true }, onStats: { showStats = true } @@ -256,7 +255,6 @@ struct GameTableView: View { balance: state.balance, secondaryInfo: settings.showCardsRemaining ? "\(state.engine.shoe.cardsRemaining)" : nil, secondaryIcon: settings.showCardsRemaining ? "rectangle.portrait.on.rectangle.portrait.fill" : nil, - showReset: false, onSettings: { showSettings = true }, onHelp: { showRules = true }, onStats: { showStats = true } diff --git a/Blackjack/Blackjack/Views/Game/GameTableView.swift b/Blackjack/Blackjack/Views/Game/GameTableView.swift index 06f93ce..7ab4920 100644 --- a/Blackjack/Blackjack/Views/Game/GameTableView.swift +++ b/Blackjack/Blackjack/Views/Game/GameTableView.swift @@ -97,7 +97,6 @@ struct GameTableView: View { balance: state.balance, secondaryInfo: settings.showCardsRemaining ? "\(state.engine.cardsRemaining)" : nil, secondaryIcon: settings.showCardsRemaining ? "rectangle.portrait.on.rectangle.portrait.fill" : nil, - showReset: false, onSettings: { showSettings = true }, onHelp: { showRules = true }, onStats: { showStats = true } diff --git a/CasinoKit/README.md b/CasinoKit/README.md index 9687489..4f7343b 100644 --- a/CasinoKit/README.md +++ b/CasinoKit/README.md @@ -126,7 +126,26 @@ TopBarView( balance: 10_500, secondaryInfo: "411", secondaryIcon: "rectangle.portrait.on.rectangle.portrait.fill", - onReset: { resetGame() }, + onSettings: { showSettings = true }, + onHelp: { showRules = true }, + onStats: { showStats = true } +) +``` + +**TopBarButton** - Add custom buttons to the toolbar. + +```swift +// Add game-specific buttons at the front of the toolbar +TopBarView( + balance: 10_500, + leadingButtons: [ + TopBarButton(icon: "arrow.counterclockwise", accessibilityLabel: "Reset Game") { + resetGame() + }, + TopBarButton(icon: "creditcard", accessibilityLabel: "Buy Chips") { + showBuyChips = true + } + ], onSettings: { showSettings = true }, onHelp: { showRules = true }, onStats: { showStats = true } diff --git a/CasinoKit/Sources/CasinoKit/Resources/Localizable.xcstrings b/CasinoKit/Sources/CasinoKit/Resources/Localizable.xcstrings index ce434f6..377b5b2 100644 --- a/CasinoKit/Sources/CasinoKit/Resources/Localizable.xcstrings +++ b/CasinoKit/Sources/CasinoKit/Resources/Localizable.xcstrings @@ -1558,6 +1558,7 @@ } }, "Reset Game" : { + "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { diff --git a/CasinoKit/Sources/CasinoKit/Views/Bars/TopBarView.swift b/CasinoKit/Sources/CasinoKit/Views/Bars/TopBarView.swift index 7ebb2e2..baad2b4 100644 --- a/CasinoKit/Sources/CasinoKit/Views/Bars/TopBarView.swift +++ b/CasinoKit/Sources/CasinoKit/Views/Bars/TopBarView.swift @@ -7,6 +7,31 @@ import SwiftUI +/// A button configuration for the top bar toolbar. +public struct TopBarButton: Identifiable { + public let id = UUID() + + /// The SF Symbol icon name. + public let icon: String + + /// The accessibility label for VoiceOver. + public let accessibilityLabel: String + + /// The action to perform when tapped. + public let action: () -> Void + + /// Creates a toolbar button configuration. + /// - Parameters: + /// - icon: SF Symbol name for the button icon. + /// - accessibilityLabel: VoiceOver label for the button. + /// - action: Closure to execute when tapped. + public init(icon: String, accessibilityLabel: String, action: @escaping () -> Void) { + self.icon = icon + self.accessibilityLabel = accessibilityLabel + self.action = action + } +} + /// A top bar showing balance and customizable toolbar buttons. public struct TopBarView: View { /// The current balance to display. @@ -18,11 +43,8 @@ public struct TopBarView: View { /// Icon for secondary info. public let secondaryIcon: String? - /// Whether to show the reset button. - public let showReset: Bool - - /// Action when reset is tapped. - public let onReset: (() -> Void)? + /// Custom buttons to display at the front of the toolbar (before stats/help/settings). + public let leadingButtons: [TopBarButton] /// Action when settings is tapped. public let onSettings: (() -> Void)? @@ -45,8 +67,7 @@ public struct TopBarView: View { /// - balance: The current balance. /// - secondaryInfo: Optional secondary info text. /// - secondaryIcon: Optional SF Symbol for secondary info. - /// - showReset: Whether to show reset button. - /// - onReset: Reset button action. + /// - leadingButtons: Custom buttons to add at the front of the toolbar. /// - onSettings: Settings button action. /// - onHelp: Help button action. /// - onStats: Stats button action. @@ -54,8 +75,7 @@ public struct TopBarView: View { balance: Int, secondaryInfo: String? = nil, secondaryIcon: String? = nil, - showReset: Bool = true, - onReset: (() -> Void)? = nil, + leadingButtons: [TopBarButton] = [], onSettings: (() -> Void)? = nil, onHelp: (() -> Void)? = nil, onStats: (() -> Void)? = nil @@ -63,8 +83,7 @@ public struct TopBarView: View { self.balance = balance self.secondaryInfo = secondaryInfo self.secondaryIcon = secondaryIcon - self.showReset = showReset - self.onReset = onReset + self.leadingButtons = leadingButtons self.onSettings = onSettings self.onHelp = onHelp self.onStats = onStats @@ -105,6 +124,12 @@ public struct TopBarView: View { // Toolbar buttons HStack(spacing: CasinoDesign.Spacing.medium) { + // Custom leading buttons (game-specific) + ForEach(leadingButtons) { button in + ToolbarButton(icon: button.icon, action: button.action) + .accessibilityLabel(button.accessibilityLabel) + } + if let onStats = onStats { ToolbarButton(icon: "chart.bar.fill", action: onStats) .accessibilityLabel(String(localized: "Statistics", bundle: .module)) @@ -119,11 +144,6 @@ public struct TopBarView: View { ToolbarButton(icon: "gearshape.fill", action: onSettings) .accessibilityLabel(String(localized: "Settings", bundle: .module)) } - - if showReset, let onReset = onReset { - ToolbarButton(icon: "arrow.counterclockwise", action: onReset) - .accessibilityLabel(String(localized: "Reset Game", bundle: .module)) - } } } .padding(.horizontal, CasinoDesign.Spacing.large) @@ -156,7 +176,9 @@ private struct ToolbarButton: View { balance: 10_500, secondaryInfo: "411", secondaryIcon: "rectangle.portrait.on.rectangle.portrait.fill", - onReset: {}, + leadingButtons: [ + TopBarButton(icon: "arrow.counterclockwise", accessibilityLabel: "Reset") {} + ], onSettings: {}, onHelp: {}, onStats: {} diff --git a/GAME_TEMPLATE.md b/GAME_TEMPLATE.md index ff30fcf..97cb18f 100644 --- a/GAME_TEMPLATE.md +++ b/GAME_TEMPLATE.md @@ -75,7 +75,12 @@ struct GameTableView: View { balance: state.balance, secondaryInfo: "\(state.engine.shoe.cardsRemaining)", secondaryIcon: "rectangle.portrait.on.rectangle.portrait.fill", - onReset: { state.resetGame() }, + leadingButtons: [ + // Add game-specific buttons here (optional) + // TopBarButton(icon: "arrow.counterclockwise", accessibilityLabel: "Reset") { + // state.resetGame() + // } + ], onSettings: { showSettings = true }, onHelp: { showRules = true }, onStats: { showStats = true }