secant-ios-wallet/modules/Sources/UIComponents/TextFields/ZashiTextField.swift

169 lines
5.5 KiB
Swift

//
// ZashiTextField.swift
//
//
// Created by Lukáš Korba on 22.05.2024.
//
import SwiftUI
import Generated
public struct ZashiTextField<PrefixContent, AccessoryContent>: View where PrefixContent: View, AccessoryContent: View {
@Environment(\.colorScheme) private var colorScheme
let addressFont: Bool
var text: Binding<String>
var placeholder: String
var title: String?
var error: String?
let eraseAction: (() -> Void)?
@ViewBuilder let accessoryView: AccessoryContent?
@ViewBuilder let prefixView: PrefixContent?
public init(
addressFont: Bool = false,
text: Binding<String>,
placeholder: String = "",
title: String? = nil,
error: String? = nil,
eraseAction: (() -> Void)? = nil,
accessoryView: AccessoryContent? = EmptyView(),
prefixView: PrefixContent? = EmptyView()
) {
self.addressFont = addressFont
self.text = text
self.placeholder = placeholder
self.title = title
self.error = error
self.eraseAction = eraseAction
self.accessoryView = accessoryView
self.prefixView = prefixView
}
public var body: some View {
VStack(alignment: .leading, spacing: 0) {
if let title {
Text(title)
.lineLimit(1)
.truncationMode(.middle)
.font(.custom(FontFamily.Inter.medium.name, size: 14))
.zForegroundColor(Design.Inputs.Filled.label)
.padding(.bottom, 6)
}
HStack(spacing: 0) {
if let prefixView {
prefixView
.padding(.trailing, 8)
}
TextField(
"",
text: text,
prompt:
Text(placeholder)
.font(.custom(FontFamily.Inter.regular.name, size: 16))
.foregroundColor(Design.Inputs.Default.text.color(colorScheme))
)
.autocapitalization(.none)
.autocorrectionDisabled()
.font(.custom(
addressFont
? FontFamily.RobotoMono.regular.name
: FontFamily.Inter.regular.name,
size: 14)
)
.lineLimit(1)
.truncationMode(.middle)
.accentColor(Asset.Colors.primary.color)
Spacer()
if let accessoryView {
if let eraseAction {
Button {
eraseAction()
} label: {
accessoryView
.padding(.leading, 8)
}
} else {
accessoryView
.padding(.leading, 8)
}
}
}
.padding(.vertical, 12)
.padding(.horizontal, 12)
.background(
RoundedRectangle(cornerRadius: Design.Radius._lg)
.fill(Design.Inputs.Default.bg.color(colorScheme))
.overlay {
RoundedRectangle(cornerRadius: Design.Radius._lg)
.stroke(
error == nil
? Design.Inputs.Default.bg.color(colorScheme)
: Design.Inputs.ErrorFilled.stroke.color(colorScheme)
)
}
)
if let error {
Text(error)
.zForegroundColor(Design.Inputs.ErrorFilled.hint)
.font(.custom(FontFamily.Inter.regular.name, size: 14))
.padding(.top, 6)
}
}
}
}
#Preview {
VStack(spacing: 30) {
StringStateWrapper {
ZashiTextField(
text: $0,
placeholder: "Placeholder"
)
ZashiTextField(
text: $0,
placeholder: "ZEC",
title: "Amount",
prefixView:
ZcashSymbol()
.frame(width: 12, height: 20)
.zForegroundColor(Design.Inputs.Default.text)
)
ZashiTextField(
text: $0,
placeholder: "Placeholder",
title: "Title",
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Inputs.Default.text),
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Inputs.Default.text)
)
ZashiTextField(
text: $0,
placeholder: "Placeholder",
title: "Title",
error: "This contact name exceeds the 32-character limit. Please shorten the name.",
accessoryView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Inputs.Default.text),
prefixView:
Asset.Assets.Icons.key.image
.zImage(size: 20, style: Design.Inputs.Default.text)
)
}
}
.padding()
}