secant-ios-wallet/modules/Sources/UIComponents/Buttons/ZashiButton.swift

148 lines
4.3 KiB
Swift

//
// ZashiButton.swift
//
//
// Created by Lukáš Korba on 28.09.2023.
//
import SwiftUI
import Generated
public struct ZcashButtonStyle: ButtonStyle {
public enum Appearance {
case primary
case secondary
}
let isEnabled: Bool
let appearance: Appearance
let height: CGFloat
let shadowOffset: CGFloat
@State private var offset = 0.0
public func makeBody(configuration: Self.Configuration) -> some View {
ZStack {
Rectangle()
.fill(
appearance == .primary ? .white
: isEnabled ? Asset.Colors.primary.color : Asset.Colors.shade72.color
)
.frame(height: height)
.border(appearance == .secondary && isEnabled ? Asset.Colors.secondary.color : Asset.Colors.primary.color)
.offset(CGSize(width: shadowOffset, height: shadowOffset))
Rectangle()
.frame(height: height)
.foregroundColor(
appearance == .primary ?
isEnabled ? Asset.Colors.primary.color : Asset.Colors.shade72.color
: Asset.Colors.secondary.color
)
.border(Asset.Colors.primary.color)
.overlay(content: {
configuration.label
.font(.custom(FontFamily.Inter.medium.name, size: 14))
.foregroundColor(
appearance == .primary ? Asset.Colors.secondary.color
: isEnabled ? Asset.Colors.primary.color : Asset.Colors.shade72.color
)
})
.offset(CGSize(width: offset, height: offset))
}
.onChange(of: configuration.isPressed) { newValue in
if newValue {
withAnimation(.easeInOut(duration: 0.05)) { offset = shadowOffset }
withAnimation(.easeInOut(duration: 0.05).delay(0.05)) { offset = 0.0 }
}
}
}
}
struct ZcashButtonModifier: ViewModifier {
@Environment(\.isEnabled) private var isEnabled
let appearance: ZcashButtonStyle.Appearance
let minWidth: CGFloat?
let height: CGFloat
let shadowOffset: CGFloat
func body(content: Content) -> some View {
if let minWidth {
content
.buttonStyle(
ZcashButtonStyle(
isEnabled: isEnabled,
appearance: appearance,
height: height,
shadowOffset: shadowOffset
)
)
.frame(minWidth: minWidth)
} else {
content
.buttonStyle(
ZcashButtonStyle(
isEnabled: isEnabled,
appearance: appearance,
height: height,
shadowOffset: shadowOffset
)
)
}
}
}
extension Button {
public func zcashStyle(
_ appearance: ZcashButtonStyle.Appearance = .primary,
minWidth: CGFloat? = 236,
height: CGFloat = 60,
shadowOffset: CGFloat = 10
) -> some View {
modifier(
ZcashButtonModifier(
appearance: appearance,
minWidth: minWidth,
height: height,
shadowOffset: shadowOffset
)
)
}
}
#Preview {
VStack {
Button { } label: {
Text("PRIMARY".uppercased())
}
.zcashStyle()
.padding(.horizontal, 40)
.padding(.bottom, 20)
.disabled(false)
Button { } label: {
Text("PRIMARY DISABLED".uppercased())
}
.zcashStyle()
.padding(.horizontal, 40)
.padding(.bottom, 20)
.disabled(true)
Button { } label: {
Text("SECONDARY".uppercased())
}
.zcashStyle(.secondary)
.padding(.horizontal, 40)
.padding(.bottom, 20)
.disabled(false)
Button { } label: {
Text("SECONDARY DISABLED".uppercased())
}
.zcashStyle(.secondary)
.padding(.horizontal, 40)
.padding(.bottom, 20)
.disabled(true)
}
}