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

402 lines
12 KiB
Swift

//
// ZashiButton.swift
// Zashi
//
// Created by Lukáš Korba on 09-12-2024.
//
import SwiftUI
import Generated
public struct ZashiButton<PrefixContent, AccessoryContent>: View where PrefixContent: View, AccessoryContent: View {
public enum `Type` {
case primary
case secondary
case tertiary
case quaternary
case destructive1
case destructive2
case brand
case ghost
}
@Environment(\.isEnabled) var isEnabled
@Environment(\.colorScheme) private var colorScheme
let title: String
let type: `Type`
let infinityWidth: Bool
@ViewBuilder let prefixView: PrefixContent?
@ViewBuilder let accessoryView: AccessoryContent?
let action: () -> Void
public init(
_ title: String,
type: `Type` = .primary,
infinityWidth: Bool = true,
prefixView: PrefixContent? = EmptyView(),
accessoryView: AccessoryContent? = EmptyView(),
action: @escaping () -> Void
) {
self.title = title
self.type = type
self.infinityWidth = infinityWidth
self.accessoryView = accessoryView
self.prefixView = prefixView
self.action = action
}
public var body: some View {
Button {
action()
} label: {
HStack(spacing: 0) {
if let prefixView {
prefixView
.padding(.trailing, 8)
}
Text(title)
.font(.custom(FontFamily.Inter.semiBold.name, size: 16))
.fixedSize()
.minimumScaleFactor(0.5)
if let accessoryView {
accessoryView
.padding(.leading, 8)
}
}
.zForegroundColor(fgColor())
.padding(.horizontal, 18)
.padding(.vertical, 12)
.frame(maxWidth: infinityWidth ? .infinity : nil)
.background {
RoundedRectangle(cornerRadius: Design.Radius._xl)
.fill(bgColor().color(colorScheme))
.overlay {
RoundedRectangle(cornerRadius: Design.Radius._xl)
.stroke(strokeColor().color(colorScheme))
}
}
}
}
private func bgColor() -> Colorable {
switch type {
case .primary:
return isEnabled
? Design.Btns.Primary.bg
: Design.Btns.Primary.bgDisabled
case .secondary:
return isEnabled
? Design.Btns.Secondary.bg
: Design.Btns.Secondary.bgDisabled
case .tertiary:
return isEnabled
? Design.Btns.Tertiary.bg
: Design.Btns.Tertiary.bgDisabled
case .quaternary:
return isEnabled
? Design.Btns.Quaternary.bg
: Design.Btns.Quaternary.bgDisabled
case .destructive1:
return isEnabled
? Design.Btns.Destructive1.bg
: Design.Btns.Destructive1.bgDisabled
case .destructive2:
return isEnabled
? Design.Btns.Destructive2.bg
: Design.Btns.Destructive2.bgDisabled
case .brand:
return isEnabled
? Design.Btns.Brand.bg
: Design.Btns.Brand.bgDisabled
case .ghost:
return isEnabled
? Design.Btns.Ghost.bg
: Design.Btns.Ghost.bgDisabled
}
}
private func fgColor() -> Colorable {
switch type {
case .primary:
return isEnabled
? Design.Btns.Primary.fg
: Design.Btns.Primary.fgDisabled
case .secondary:
return isEnabled
? Design.Btns.Secondary.fg
: Design.Btns.Secondary.fgDisabled
case .tertiary:
return isEnabled
? Design.Btns.Tertiary.fg
: Design.Btns.Tertiary.fgDisabled
case .quaternary:
return isEnabled
? Design.Btns.Quaternary.fg
: Design.Btns.Quaternary.fgDisabled
case .destructive1:
return isEnabled
? Design.Btns.Destructive1.fg
: Design.Btns.Destructive1.fgDisabled
case .destructive2:
return isEnabled
? Design.Btns.Destructive2.fg
: Design.Btns.Destructive2.fgDisabled
case .brand:
return isEnabled
? Design.Btns.Brand.fg
: Design.Btns.Brand.fgDisabled
case .ghost:
return isEnabled
? Design.Btns.Ghost.fg
: Design.Btns.Ghost.fgDisabled
}
}
private func strokeColor() -> Colorable {
switch type {
case .primary:
return isEnabled
? Design.Btns.Primary.bg
: Design.Btns.Primary.bgDisabled
case .secondary:
return isEnabled
? Design.Btns.Secondary.border
: Design.Btns.Secondary.bgDisabled
case .tertiary:
return isEnabled
? Design.Btns.Tertiary.bg
: Design.Btns.Tertiary.bgDisabled
case .quaternary:
return isEnabled
? Design.Btns.Quaternary.bg
: Design.Btns.Quaternary.bgDisabled
case .destructive1:
return isEnabled
? Design.Btns.Destructive1.border
: Design.Btns.Destructive1.bgDisabled
case .destructive2:
return isEnabled
? Design.Btns.Destructive2.bg
: Design.Btns.Destructive2.bgDisabled
case .brand:
return isEnabled
? Design.Btns.Brand.bg
: Design.Btns.Brand.bgDisabled
case .ghost:
return isEnabled
? Design.Btns.Ghost.bg
: Design.Btns.Ghost.bgDisabled
}
}
}
#Preview {
VStack(spacing: 15) {
ZashiButton("Button") {}
ZashiButton("Button", type: .secondary) {}
ZashiButton("Button", type: .tertiary) {}
ZashiButton("Button", type: .quaternary) {}
ZashiButton("Button", type: .destructive1) {}
ZashiButton("Button", type: .destructive2) {}
ZashiButton("Button", type: .brand) {}
ZashiButton("Button", type: .ghost) {}
}
.screenHorizontalPadding()
}
#Preview {
VStack(spacing: 15) {
ZashiButton(
"Button",
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .secondary,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .tertiary,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .quaternary,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .destructive1,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .destructive2,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .brand,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
ZashiButton(
"Button",
type: .ghost,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
}
.screenHorizontalPadding()
}
#Preview {
VStack(spacing: 15) {
ZashiButton(
"Button",
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .secondary,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .tertiary,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .quaternary,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .destructive1,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .destructive2,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .brand,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
ZashiButton(
"Button",
type: .ghost,
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary),
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Text.primary)
) {}
.disabled(true)
}
.screenHorizontalPadding()
}