Impressia/Vernissage/Widgets/ActionButton.swift

60 lines
1.4 KiB
Swift

//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
import SwiftUI
struct ActionButton<Label> : View where Label : View {
@State private var isDuringAction = false
private let action: () async -> Void
private let label: () -> Label
public init(action: @escaping () async -> Void, @ViewBuilder label: @escaping () -> Label) {
self.action = action
self.label = label
}
var body: some View {
Button {
Task {
HapticService.shared.touch()
defer {
Task { @MainActor in
withAnimation {
self.isDuringAction = false
}
}
}
withAnimation {
self.isDuringAction = true
}
await action()
}
} label: {
if isDuringAction {
LoadingIndicator(withText: false)
.transition(.opacity)
} else {
label()
.transition(.opacity)
}
}.disabled(isDuringAction)
}
}
struct ActionButton_Previews: PreviewProvider {
static var previews: some View {
ActionButton {
} label: {
Text("Action")
}
}
}