feat: Adds more buttons and reverse label style
This commit is contained in:
@@ -221,9 +221,7 @@ public struct EstimateSettingsFormView: View {
|
||||
HStack {
|
||||
ResetButton { send(.resetButtonTapped) }
|
||||
Spacer()
|
||||
Button("Next") {
|
||||
send(.nextButtonTapped)
|
||||
}
|
||||
NextButton { send(.nextButtonTapped) }
|
||||
.disabled(!store.isValid)
|
||||
}
|
||||
.padding(.top)
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
import SwiftUI
|
||||
|
||||
public struct DoneButton: View {
|
||||
|
||||
let action: () -> Void
|
||||
|
||||
public init(action: @escaping () -> Void) {
|
||||
self.action = action
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
Button(action: action) {
|
||||
Text("Done")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct InfoButton: View {
|
||||
|
||||
@Environment(\.infoButtonStyle) private var infoButtonStyle
|
||||
@@ -18,6 +33,26 @@ public struct InfoButton: View {
|
||||
}
|
||||
}
|
||||
|
||||
public struct NextButton: View {
|
||||
|
||||
@Environment(\.nextButtonStyle) private var nextButtonStyle
|
||||
|
||||
let action: () -> Void
|
||||
|
||||
public init(action: @escaping () -> Void) {
|
||||
self.action = action
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
Button {
|
||||
action()
|
||||
} label: {
|
||||
Label("Next", systemImage: "chevron.right")
|
||||
}
|
||||
.buttonStyle(nextButtonStyle)
|
||||
}
|
||||
}
|
||||
|
||||
public struct ResetButton: View {
|
||||
|
||||
@Environment(\.resetButtonStyle) private var resetButtonStyle
|
||||
@@ -48,6 +83,9 @@ struct ButtonPreview: View {
|
||||
InfoButton {
|
||||
lastButtonPressed = "Info button pressed."
|
||||
}
|
||||
NextButton {
|
||||
lastButtonPressed = "Next button pressed."
|
||||
}
|
||||
ResetButton {
|
||||
lastButtonPressed = "Reset button pressed."
|
||||
}
|
||||
|
||||
@@ -54,9 +54,7 @@ public struct InfoView: View {
|
||||
.padding(.horizontal)
|
||||
.navigationBarBackButtonHidden()
|
||||
.toolbar {
|
||||
Button("Done") {
|
||||
store.send(.dismissButtonTapped)
|
||||
}
|
||||
DoneButton { store.send(.dismissButtonTapped) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,13 @@ import SwiftUI
|
||||
/// A name space for info button styles.
|
||||
public enum InfoButtonType { }
|
||||
|
||||
/// A name space for info button styles.
|
||||
public enum NextButtonType { }
|
||||
|
||||
/// A name space for info button styles.
|
||||
public enum ResetButtonType { }
|
||||
|
||||
/// A type erased button style, used to style buttons in a namespace.
|
||||
public struct AnyButtonStyle<ButtonType>: ButtonStyle {
|
||||
private let _makeBody: (Configuration) -> AnyView
|
||||
|
||||
@@ -20,6 +24,7 @@ public struct AnyButtonStyle<ButtonType>: ButtonStyle {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type erased primitive button style, used to style buttons in a namespace.
|
||||
public struct AnyPrimitiveButtonStyle<ButtonType>: PrimitiveButtonStyle {
|
||||
private let _makeBody: (Configuration) -> AnyView
|
||||
|
||||
@@ -34,36 +39,62 @@ public struct AnyPrimitiveButtonStyle<ButtonType>: PrimitiveButtonStyle {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// The default info button style.
|
||||
public struct DefaultInfoButtonStyle<Style: LabelStyle>: ButtonStyle {
|
||||
let color: Color
|
||||
let font: Font
|
||||
let labelStyle: Style
|
||||
|
||||
init(
|
||||
color: Color = .accentColor,
|
||||
font: Font = .title2,
|
||||
labelStyle: Style
|
||||
) {
|
||||
self.color = color
|
||||
self.font = font
|
||||
self.labelStyle = labelStyle
|
||||
}
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
.font(.title2)
|
||||
.font(font)
|
||||
.foregroundStyle(color.opacity(configuration.isPressed ? 0.5 : 1))
|
||||
.labelStyle(labelStyle)
|
||||
.scaleEffect(configuration.isPressed ? 0.8 : 1)
|
||||
}
|
||||
}
|
||||
|
||||
public struct DefaultNextButtonStyle<ButtonStyle: PrimitiveButtonStyle, Label: LabelStyle>: PrimitiveButtonStyle {
|
||||
let buttonStyle: ButtonStyle
|
||||
let labelStyle: Label
|
||||
|
||||
public init(buttonStyle: ButtonStyle, labelStyle: Label) {
|
||||
self.buttonStyle = buttonStyle
|
||||
self.labelStyle = labelStyle
|
||||
}
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
Button(role: configuration.role, action: configuration.trigger) {
|
||||
configuration.label
|
||||
}
|
||||
.labelStyle(labelStyle)
|
||||
.buttonStyle(buttonStyle)
|
||||
}
|
||||
}
|
||||
|
||||
extension DefaultNextButtonStyle where ButtonStyle == BorderedProminentButtonStyle, Label == ReverseLabelStyle {
|
||||
init() {
|
||||
self.init(buttonStyle: .borderedProminent, labelStyle: .reverse())
|
||||
}
|
||||
}
|
||||
|
||||
extension AnyButtonStyle where ButtonType == InfoButtonType {
|
||||
public static var `default`: Self {
|
||||
.init(DefaultInfoButtonStyle<IconOnlyLabelStyle>(labelStyle: .iconOnly))
|
||||
}
|
||||
|
||||
public static func `default`<S: LabelStyle>(color: Color, labelStyle: S) -> Self {
|
||||
.init(DefaultInfoButtonStyle<S>(color: color, labelStyle: labelStyle))
|
||||
public static func `default`<S: LabelStyle>(color: Color, font: Font, labelStyle: S) -> Self {
|
||||
.init(DefaultInfoButtonStyle<S>(color: color, font: font, labelStyle: labelStyle))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,17 +102,28 @@ private struct InfoButtonStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyButtonStyle<InfoButtonType>.default
|
||||
}
|
||||
|
||||
private struct NextButtonStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyPrimitiveButtonStyle<NextButtonType>(
|
||||
DefaultNextButtonStyle<BorderedProminentButtonStyle, ReverseLabelStyle>()
|
||||
)
|
||||
}
|
||||
|
||||
private struct ResetButtonStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyPrimitiveButtonStyle<ResetButtonType>(BorderedProminentButtonStyle())
|
||||
static var defaultValue = AnyPrimitiveButtonStyle<ResetButtonType>(.borderedProminent)
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
public var infoButtonStyle: AnyButtonStyle<InfoButtonType> {
|
||||
var infoButtonStyle: AnyButtonStyle<InfoButtonType> {
|
||||
get { self[InfoButtonStyleKey.self] }
|
||||
set { self[InfoButtonStyleKey.self] = newValue }
|
||||
}
|
||||
|
||||
public var resetButtonStyle: AnyPrimitiveButtonStyle<ResetButtonType> {
|
||||
var nextButtonStyle: AnyPrimitiveButtonStyle<NextButtonType> {
|
||||
get { self[NextButtonStyleKey.self] }
|
||||
set { self[NextButtonStyleKey.self] = newValue }
|
||||
}
|
||||
|
||||
var resetButtonStyle: AnyPrimitiveButtonStyle<ResetButtonType> {
|
||||
get { self[ResetButtonStyleKey.self] }
|
||||
set { self[ResetButtonStyleKey.self] = newValue }
|
||||
}
|
||||
@@ -89,18 +131,32 @@ extension EnvironmentValues {
|
||||
|
||||
extension View {
|
||||
|
||||
/// Sets the button style for the ``InfoButton`` type.
|
||||
public func infoButtonStyle(_ style: AnyButtonStyle<InfoButtonType>) -> some View {
|
||||
environment(\.infoButtonStyle, style)
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``InfoButton`` type.
|
||||
public func infoButtonStyle<S: ButtonStyle>(_ style: S) -> some View {
|
||||
infoButtonStyle(AnyButtonStyle(style))
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``NextButton`` type.
|
||||
public func nextButtonStyle(_ style: AnyPrimitiveButtonStyle<NextButtonType>) -> some View {
|
||||
environment(\.nextButtonStyle, style)
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``NextButton`` type.
|
||||
public func nextButtonStyle<S: PrimitiveButtonStyle>(_ style: S) -> some View {
|
||||
nextButtonStyle(AnyPrimitiveButtonStyle(style))
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``ResetButton`` type.
|
||||
public func resetButtonStyle(_ style: AnyPrimitiveButtonStyle<ResetButtonType>) -> some View {
|
||||
environment(\.resetButtonStyle, style)
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``ResetButton`` type.
|
||||
public func resetButtonStyle<S: PrimitiveButtonStyle>(_ style: S) -> some View {
|
||||
resetButtonStyle(AnyPrimitiveButtonStyle(style))
|
||||
}
|
||||
|
||||
24
Sources/Styleguide/Styles/ReverseLabelStyle.swift
Normal file
24
Sources/Styleguide/Styles/ReverseLabelStyle.swift
Normal file
@@ -0,0 +1,24 @@
|
||||
import SwiftUI
|
||||
|
||||
/// A label style that puts the title first and icon second.
|
||||
public struct ReverseLabelStyle: LabelStyle {
|
||||
let spacing: CGFloat
|
||||
|
||||
public init(spacing: CGFloat = 3) {
|
||||
self.spacing = spacing
|
||||
}
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
HStack(spacing: spacing) {
|
||||
configuration.title
|
||||
configuration.icon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension LabelStyle where Self == ReverseLabelStyle {
|
||||
|
||||
public static func reverse(spacing: CGFloat = 3) -> Self {
|
||||
.init(spacing: spacing)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user