feat: Reimplements reset button style.

This commit is contained in:
2024-06-04 18:53:01 -04:00
parent aa40985486
commit dd8f360417
2 changed files with 81 additions and 25 deletions

View File

@@ -14,16 +14,14 @@ public struct InfoButton: View {
Button(action: action) { Button(action: action) {
Label("Info", systemImage: "info.circle") Label("Info", systemImage: "info.circle")
} }
.buttonStyle(.plain) .buttonStyle(infoButtonStyle)
.labelStyle(.iconOnly)
.font(.title2)
.foregroundStyle(Color.accentColor)
// .buttonStyle(infoButtonStyle)
} }
} }
public struct ResetButton: View { public struct ResetButton: View {
@Environment(\.resetButtonStyle) private var resetButtonStyle
let action: () -> Void let action: () -> Void
public init(action: @escaping () -> Void) { public init(action: @escaping () -> Void) {
@@ -34,13 +32,30 @@ public struct ResetButton: View {
Button("Reset", role: .destructive) { Button("Reset", role: .destructive) {
action() action()
} }
.buttonStyle(.borderedProminent) .buttonStyle(resetButtonStyle)
}
}
#if DEBUG
struct ButtonPreview: View {
@State private var lastButtonPressed: String = ""
var body: some View {
VStack {
Text(lastButtonPressed)
InfoButton {
lastButtonPressed = "Info button pressed."
}
ResetButton {
lastButtonPressed = "Reset button pressed."
}
}
} }
} }
#Preview { #Preview {
VStack { ButtonPreview()
InfoButton { }
ResetButton { }
}
} }
#endif

View File

@@ -3,7 +3,24 @@ import SwiftUI
/// A name space for info button styles. /// A name space for info button styles.
public enum InfoButtonType { } public enum InfoButtonType { }
public struct AnyButtonStyle<ButtonType>: PrimitiveButtonStyle { /// A name space for info button styles.
public enum ResetButtonType { }
public struct AnyButtonStyle<ButtonType>: ButtonStyle {
private let _makeBody: (Configuration) -> AnyView
public init<S: ButtonStyle>(_ style: S) {
self._makeBody = { configuration in
AnyView(style.makeBody(configuration: configuration))
}
}
public func makeBody(configuration: Configuration) -> some View {
self._makeBody(configuration)
}
}
public struct AnyPrimitiveButtonStyle<ButtonType>: PrimitiveButtonStyle {
private let _makeBody: (Configuration) -> AnyView private let _makeBody: (Configuration) -> AnyView
public init<S: PrimitiveButtonStyle>(_ style: S) { public init<S: PrimitiveButtonStyle>(_ style: S) {
@@ -18,26 +35,35 @@ public struct AnyButtonStyle<ButtonType>: PrimitiveButtonStyle {
} }
public struct DefaultInfoButtonStyle: PrimitiveButtonStyle {
public struct DefaultInfoButtonStyle<Style: LabelStyle>: ButtonStyle {
let color: Color
let labelStyle: Style
init(
color: Color = .accentColor,
labelStyle: Style
) {
self.color = color
self.labelStyle = labelStyle
}
public func makeBody(configuration: Configuration) -> some View { public func makeBody(configuration: Configuration) -> some View {
configuration.label configuration.label
.buttonStyle(.plain)
.font(.title2) .font(.title2)
.foregroundStyle(Color.accentColor) .foregroundStyle(color.opacity(configuration.isPressed ? 0.5 : 1))
.labelStyle(.iconOnly) .labelStyle(labelStyle)
.scaleEffect(configuration.isPressed ? 0.8 : 1)
} }
} }
extension AnyButtonStyle where ButtonType == InfoButtonType { extension AnyButtonStyle where ButtonType == InfoButtonType {
public static var `default`: Self { public static var `default`: Self {
.init(DefaultInfoButtonStyle()) .init(DefaultInfoButtonStyle<IconOnlyLabelStyle>(labelStyle: .iconOnly))
}
} }
public struct DefaultResetButtonStyle: PrimitiveButtonStyle { public static func `default`<S: LabelStyle>(color: Color, labelStyle: S) -> Self {
public func makeBody(configuration: Configuration) -> some View { .init(DefaultInfoButtonStyle<S>(color: color, labelStyle: labelStyle))
configuration.label
.buttonStyle(.borderedProminent)
} }
} }
@@ -45,12 +71,20 @@ private struct InfoButtonStyleKey: EnvironmentKey {
static var defaultValue = AnyButtonStyle<InfoButtonType>.default static var defaultValue = AnyButtonStyle<InfoButtonType>.default
} }
private struct ResetButtonStyleKey: EnvironmentKey {
static var defaultValue = AnyPrimitiveButtonStyle<ResetButtonType>(BorderedProminentButtonStyle())
}
extension EnvironmentValues { extension EnvironmentValues {
public var infoButtonStyle: AnyButtonStyle<InfoButtonType> { public var infoButtonStyle: AnyButtonStyle<InfoButtonType> {
get { self[InfoButtonStyleKey.self] } get { self[InfoButtonStyleKey.self] }
set { self[InfoButtonStyleKey.self] = newValue } set { self[InfoButtonStyleKey.self] = newValue }
} }
public var resetButtonStyle: AnyPrimitiveButtonStyle<ResetButtonType> {
get { self[ResetButtonStyleKey.self] }
set { self[ResetButtonStyleKey.self] = newValue }
}
} }
extension View { extension View {
@@ -59,8 +93,15 @@ extension View {
environment(\.infoButtonStyle, style) environment(\.infoButtonStyle, style)
} }
public func infoButtonStyle<S: PrimitiveButtonStyle>(_ style: S) -> some View { public func infoButtonStyle<S: ButtonStyle>(_ style: S) -> some View {
infoButtonStyle(AnyButtonStyle(style)) infoButtonStyle(AnyButtonStyle(style))
} }
public func resetButtonStyle(_ style: AnyPrimitiveButtonStyle<ResetButtonType>) -> some View {
environment(\.resetButtonStyle, style)
}
public func resetButtonStyle<S: PrimitiveButtonStyle>(_ style: S) -> some View {
resetButtonStyle(AnyPrimitiveButtonStyle(style))
}
} }