148 lines
4.3 KiB
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)
|
|
}
|
|
}
|