import SwiftUI /// Input fields per `DESIGN (1).md` → Components → Input Fields: "1px solid /// #E2E8F0 bottom-border only... Use `label-caps` for field labels placed /// strictly above the input." Border thickens to 2px while focused — the /// same "shift, don't lift" interaction rule as `ZenithButtonStyle`. /// /// Use this instead of a bare `TextField` + `.textFieldStyle(.roundedBorder)` /// everywhere in the app; `.roundedBorder` fights this design system /// directly (it's rounded and iOS-chrome-grey, the opposite of "sharp, /// monochrome, architectural"). struct ZenithTextField: View { let label: String @Binding var text: String var placeholder: String = "" var isSecure = false var keyboardType: UIKeyboardType = .default var textContentType: UITextContentType? var autocapitalization: TextInputAutocapitalization = .sentences var autocorrectionDisabled = false @FocusState private var isFocused: Bool var body: some View { VStack(alignment: .leading, spacing: ZenithSpacing.unit) { Text(label).zenithLabelCapsStyle() Group { if isSecure { SecureField(placeholder, text: $text) } else { TextField(placeholder, text: $text) } } .font(.zenithBodyMd) .foregroundStyle(.zenithText) .keyboardType(keyboardType) .textContentType(textContentType) .textInputAutocapitalization(autocapitalization) .autocorrectionDisabled(autocorrectionDisabled) .focused($isFocused) .padding(.vertical, ZenithSpacing.unit * 2) .overlay(alignment: .bottom) { Rectangle() .fill(isFocused ? Color.zenithBlack : Color.zenithBorder) .frame(height: isFocused ? 2 : 1) } } } } /// A numeric variant bound to an optional `Double`, for amount fields — free /// text with comma-or-dot decimal entry (matches how receipts are actually /// typed in German usage) rather than a strict `TextField(value:format:)` /// that rejects a comma outright. struct ZenithAmountField: View { let label: String @Binding var value: Double? var placeholder: String = "0,00" private var textProxy: Binding { Binding( get: { value.map { String(format: "%.2f", $0) } ?? "" }, set: { newValue in let normalized = newValue.replacingOccurrences(of: ",", with: ".") value = Double(normalized) } ) } var body: some View { ZenithTextField( label: label, text: textProxy, placeholder: placeholder, keyboardType: .decimalPad ) } }