64 lines
1.4 KiB
Swift
64 lines
1.4 KiB
Swift
//
|
|
// TriStateToggle.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 4/7/24.
|
|
// Copyright © 2024 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct TriStateToggle: View {
|
|
let titleKey: LocalizedStringKey
|
|
@Binding var mode: Mode
|
|
let onChange: (Bool) async -> Void
|
|
@State private var isOn: Bool = false
|
|
|
|
var body: some View {
|
|
toggleOrSpinner
|
|
.onChange(of: mode) { newValue in
|
|
switch newValue {
|
|
case .off:
|
|
isOn = false
|
|
case .loading:
|
|
break
|
|
case .on:
|
|
isOn = true
|
|
}
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var toggleOrSpinner: some View {
|
|
if mode == .loading {
|
|
ProgressView()
|
|
} else {
|
|
Toggle(titleKey, isOn: Binding {
|
|
isOn
|
|
} set: { newValue in
|
|
isOn = newValue
|
|
mode = .loading
|
|
Task {
|
|
await onChange(newValue)
|
|
mode = newValue ? .on : .off
|
|
}
|
|
})
|
|
.labelsHidden()
|
|
}
|
|
}
|
|
|
|
enum Mode {
|
|
case off
|
|
case loading
|
|
case on
|
|
}
|
|
}
|
|
|
|
|
|
#Preview {
|
|
@State var mode = TriStateToggle.Mode.on
|
|
return TriStateToggle(titleKey: "", mode: $mode) { _ in
|
|
try! await Task.sleep(nanoseconds: NSEC_PER_SEC)
|
|
}
|
|
}
|