### Install ButtonKit with Swift Package Manager Source: https://github.com/dean151/buttonkit/blob/main/README.md Shows how to add ButtonKit as a dependency using Swift Package Manager in your project's Package.swift file. ```Swift dependencies: [ .package(url: "https://github.com/Dean151/ButtonKit.git", from: "0.3.0"), ], targets: [ .target(name: "MyTarget", dependencies: [ .product(name: "ButtonKit", package: "ButtonKit"), ]), ] ``` -------------------------------- ### Apply AsyncButtonStyle for Progress Visualization Source: https://github.com/dean151/buttonkit/blob/main/README.md Demonstrates applying custom `asyncButtonStyle` modifiers like `.trailing` to visualize progress directly on the button. These styles respond to the `configuration.fractionCompleted` property to display progress bars or percentages. ```swift AsyncButton(progress: .discrete(totalUnitCount: files.count)) { progress in for file in files { try await file.doExpensiveComputation() progress.completedUnitCount += 1 } } label: { Text("Process") } .buttonStyle(.borderedProminent) .buttonBorderShape(.roundedRectangle) .asyncButtonStyle(.trailing) ``` -------------------------------- ### Apply Custom Throwable Button Style Source: https://github.com/dean151/buttonkit/blob/main/README.md Demonstrates applying a custom `ThrowableButtonStyle` (e.g., `.tryAgain`) to an `AsyncButton` to customize error feedback. ```Swift AsyncButton { try doSomethingThatCanFail() } label: { Text("Do something") } .throwableButtonStyle(.tryAgain) ``` -------------------------------- ### Implement Discrete Progress Reporting Source: https://github.com/dean151/buttonkit/blob/main/README.md Illustrates how to use `.discrete(totalUnitCount:)` with AsyncButton to report progress based on a total number of units. This allows for visual feedback on long-running tasks, updating the button's state as units are completed. ```swift AsyncButton(progress: .discrete(totalUnitCount: files.count)) { progress in for file in files { try await file.doExpensiveComputation() progress.completedUnitCount += 1 } } label: { Text("Process") } .buttonStyle(.borderedProminent) .buttonBorderShape(.roundedRectangle) ``` -------------------------------- ### Apply AsyncButton Loading Leading Style Source: https://github.com/dean151/buttonkit/blob/main/README.md Applies the `.asyncButtonStyle(.leading)` modifier to an `AsyncButton` to display a `ProgressView` leading the button's label while loading. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonStyle(.leading) ``` -------------------------------- ### Utilize TaskProgress Protocol for Custom Logic Source: https://github.com/dean151/buttonkit/blob/main/README.md Explains how to create custom progress logic by implementing the `TaskProgress` protocol. This allows for advanced progress behaviors, such as logarithmic scaling or mixed indeterminate/deterministic states, similar to system-level progress indicators. ```swift // Example of creating a custom TaskProgress implementation // protocol TaskProgress { // var completedUnitCount: Int64 { get set } // var totalUnitCount: Int64 { get } // } // Available TaskProgress implementations: // - .indeterminate // - .discrete(totalUnitsCount: Int) // - .estimated(for: Duration) // - .progress (bridges to (NS)Progress) ``` -------------------------------- ### React to AsyncButton Task Start/End Source: https://github.com/dean151/buttonkit/blob/main/README.md Demonstrates using `.asyncButtonTaskStarted` and `.asyncButtonTaskEnded` modifiers to react to the lifecycle of the asynchronous task within an `AsyncButton`. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonTaskStarted { task in // Task started } .asyncButtonTaskEnded { // Task ended or was cancelled } ``` -------------------------------- ### Apply AsyncButton Loading Overlay Style Source: https://github.com/dean151/buttonkit/blob/main/README.md Applies the `.asyncButtonStyle(.overlay)` modifier to an `AsyncButton` to display a `ProgressView` overlaying the button's label while loading. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonStyle(.overlay) ``` -------------------------------- ### Use AsyncButton with Throwable Actions Source: https://github.com/dean151/buttonkit/blob/main/README.md Demonstrates using `AsyncButton` with a closure that can throw an error. The button will shake by default when an error occurs. ```Swift AsyncButton { try doSomethingThatCanFail() } label: { Text("Do something") } ``` -------------------------------- ### Use AsyncButton with Asynchronous Actions Source: https://github.com/dean151/buttonkit/blob/main/README.md Shows how to use `AsyncButton` with an `async throws` closure, allowing for asynchronous operations within the button's action. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } ``` -------------------------------- ### Apply AsyncButton Loading Trailing Style Source: https://github.com/dean151/buttonkit/blob/main/README.md Applies the `.asyncButtonStyle(.trailing)` modifier to an `AsyncButton` to display a `ProgressView` trailing the button's label while loading. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonStyle(.trailing) ``` -------------------------------- ### Apply AsyncButton Loading Pulse Style Source: https://github.com/dean151/buttonkit/blob/main/README.md Applies the `.asyncButtonStyle(.pulse)` modifier to an `AsyncButton` to show a pulsing animation on the button's label while loading. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonStyle(.pulse) ``` -------------------------------- ### Control HitTesting on AsyncButton Loading Source: https://github.com/dean151/buttonkit/blob/main/README.md Uses the `.allowsHitTestingWhenLoading(false)` modifier to disable hit testing on an `AsyncButton` while it's loading, preventing accidental re-triggers. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .allowsHitTestingWhenLoading(false) ``` -------------------------------- ### Trigger AsyncButton Externally with Identifiers Source: https://github.com/dean151/buttonkit/blob/main/README.md Demonstrates setting a unique identifier for an AsyncButton and triggering its action externally using the `triggerButton` environment variable in Swift. The button must be on screen and enabled for the trigger to be effective. ```swift enum LoginViewButton: Hashable { case login } struct ContentView: View { var body: some View { AsyncButton(id: LoginViewButton.login) { try await login() } label: { Text("Login") } } } ``` -------------------------------- ### Create Custom Throwable Button Style Source: https://github.com/dean151/buttonkit/blob/main/README.md Defines a custom `ThrowableButtonStyle` protocol implementation to change the button's appearance based on error count, such as displaying 'Try again!'. ```Swift public struct TryAgainThrowableButtonStyle: ThrowableButtonStyle { public init() {} public func makeLabel(configuration: LabelConfiguration) -> some View { if configuration.errorCount > 0 { Text("Try again!") } else { configuration.label } } } extension ThrowableButtonStyle where Self == TryAgainThrowableButtonStyle { public static var tryAgain: TryAgainThrowableButtonStyle { TryAgainThrowableButtonStyle() } } ``` -------------------------------- ### Disable AsyncButton Loading Animation Source: https://github.com/dean151/buttonkit/blob/main/README.md Shows how to disable the default loading animation (e.g., `ProgressView`) for an `AsyncButton` by applying the `.asyncButtonStyle(.none)` modifier. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonStyle(.none) ``` -------------------------------- ### React to AsyncButton Task State Changes Source: https://github.com/dean151/buttonkit/blob/main/README.md Uses the `.asyncButtonTaskChanged` modifier to receive updates on the `AsyncButton`'s task status, allowing for conditional logic based on whether a task is active. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .asyncButtonTaskChanged { task in if let task { // Task started } else { // Task ended or was cancelled } } ``` -------------------------------- ### Access and Use triggerButton Environment Source: https://github.com/dean151/buttonkit/blob/main/README.md Shows how to access the `triggerButton` environment variable in a Swift view to programmatically trigger an AsyncButton identified by its unique ID. Calling `triggerButton` on a disabled or already active button has no effect. ```swift struct ContentView: View { @Environment(\.triggerButton) private var triggerButton ... func performLogin() { triggerButton(LoginViewButton.login) } } ``` -------------------------------- ### Disable AsyncButton on Loading Source: https://github.com/dean151/buttonkit/blob/main/README.md Applies the `.disabledWhenLoading()` modifier to an `AsyncButton` to prevent further interaction while the asynchronous task is in progress. ```Swift AsyncButton { try await doSomethingThatTakeTime() } label: { Text("Do something") } .disabledWhenLoading() ``` -------------------------------- ### Disable Throwable Button Shake Animation Source: https://github.com/dean151/buttonkit/blob/main/README.md Shows how to disable the default shake animation for throwable actions by applying the `.throwableButtonStyle(.none)` modifier to the `AsyncButton`. ```Swift AsyncButton { try doSomethingThatCanFail() } label: { Text("Do something") } .throwableButtonStyle(.none) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.