diff --git a/BusinessCard/BusinessCardApp.swift b/BusinessCard/BusinessCardApp.swift index 8657f5d..ed76070 100644 --- a/BusinessCard/BusinessCardApp.swift +++ b/BusinessCard/BusinessCardApp.swift @@ -109,6 +109,8 @@ struct BusinessCardApp: App { RootTabView() .environment(appState) .preferredColorScheme(appState.preferredColorScheme) + .autocorrectionDisabled(true) + .textInputAutocapitalization(.never) } } } diff --git a/BusinessCard/Design/DesignConstants.swift b/BusinessCard/Design/DesignConstants.swift index f7d49b1..c0187ef 100644 --- a/BusinessCard/Design/DesignConstants.swift +++ b/BusinessCard/Design/DesignConstants.swift @@ -196,3 +196,23 @@ extension Color { /// Legacy alias - use AppText instead typealias Text = AppText } + +// MARK: - Keyboard Dismiss Helpers + +private struct KeyboardDismissModifier: ViewModifier { + func body(content: Content) -> some View { + content + .autocorrectionDisabled(true) + .textInputAutocapitalization(.never) + .scrollDismissesKeyboard(.interactively) + } +} + +extension View { + /// Adds standard iOS keyboard dismissal behavior: + /// - interactive scroll-to-dismiss + /// - keyboard accessory Done button + func keyboardDismissable() -> some View { + modifier(KeyboardDismissModifier()) + } +} diff --git a/BusinessCard/Views/CardEditorView.swift b/BusinessCard/Views/CardEditorView.swift index f790cab..394fa48 100644 --- a/BusinessCard/Views/CardEditorView.swift +++ b/BusinessCard/Views/CardEditorView.swift @@ -240,6 +240,7 @@ struct CardEditorView: View { .safeAreaInset(edge: .bottom) { PreviewCardButton { showingPreview = true } } + .keyboardDismissable() .navigationTitle(isEditing ? String.localized("Edit Card") : String.localized("New Card")) .navigationBarTitleDisplayMode(.inline) .toolbar { @@ -1048,17 +1049,28 @@ private struct AccreditationsRow: View { private struct PreviewCardButton: View { let action: () -> Void + @Environment(\.colorScheme) private var colorScheme var body: some View { Button(action: action) { Text("Preview card") .typography(.heading) - .foregroundStyle(.white) + .foregroundStyle(Color.AppText.inverted) .frame(maxWidth: .infinity) .padding(Design.Spacing.medium) - .background(Color.Text.primary) + .background(AppThemeAccent.primary) .clipShape(.rect(cornerRadius: Design.CornerRadius.large)) + .overlay( + RoundedRectangle(cornerRadius: Design.CornerRadius.large) + .stroke( + colorScheme == .dark + ? Color.white.opacity(Design.Opacity.subtle) + : Color.black.opacity(Design.Opacity.light), + lineWidth: Design.LineWidth.thin + ) + ) } + .buttonStyle(.plain) .padding(.horizontal, Design.Spacing.large) .padding(.vertical, Design.Spacing.medium) .background(.ultraThinMaterial) diff --git a/BusinessCard/Views/Components/ContactFieldPickerView.swift b/BusinessCard/Views/Components/ContactFieldPickerView.swift index 8c18a79..94ccaad 100644 --- a/BusinessCard/Views/Components/ContactFieldPickerView.swift +++ b/BusinessCard/Views/Components/ContactFieldPickerView.swift @@ -13,7 +13,7 @@ struct ContactFieldPickerView: View { HStack { Text("Tap a field below to add it") .typography(.subheading) - .foregroundStyle(Color.Text.primary) + .foregroundStyle(Color.Text.secondary) Spacer() @@ -23,7 +23,7 @@ struct ContactFieldPickerView: View { } .padding(.horizontal, Design.Spacing.medium) .padding(.vertical, Design.Spacing.small) - .background(Color.AppBackground.accent) + .background(Color.AppBackground.secondary) .clipShape(.rect(cornerRadius: Design.CornerRadius.medium)) LazyVGrid(columns: columns, spacing: Design.Spacing.large) { @@ -35,7 +35,12 @@ struct ContactFieldPickerView: View { } } .padding(Design.Spacing.large) - .background(Color.AppBackground.elevated) + .background(Color.AppBackground.secondary) + .clipShape(.rect(cornerRadius: Design.CornerRadius.large)) + .overlay( + RoundedRectangle(cornerRadius: Design.CornerRadius.large) + .stroke(Color.Text.tertiary.opacity(Design.Opacity.subtle), lineWidth: Design.LineWidth.thin) + ) } } diff --git a/BusinessCard/Views/ContactDetailView.swift b/BusinessCard/Views/ContactDetailView.swift index 19af5bf..0860a9e 100644 --- a/BusinessCard/Views/ContactDetailView.swift +++ b/BusinessCard/Views/ContactDetailView.swift @@ -606,6 +606,7 @@ private struct AddNoteSheet: View { .padding(Design.Spacing.medium) .navigationTitle(String.localized("Notes")) .navigationBarTitleDisplayMode(.inline) + .keyboardDismissable() .toolbar { ToolbarItem(placement: .cancellationAction) { Button(String.localized("Cancel")) { diff --git a/BusinessCard/Views/Sheets/AddContactSheet.swift b/BusinessCard/Views/Sheets/AddContactSheet.swift index 15fe061..58bf7c7 100644 --- a/BusinessCard/Views/Sheets/AddContactSheet.swift +++ b/BusinessCard/Views/Sheets/AddContactSheet.swift @@ -187,6 +187,7 @@ struct AddContactSheet: View { } .navigationTitle(String.localized("New contact")) .navigationBarTitleDisplayMode(.inline) + .keyboardDismissable() .sheet(isPresented: $showingPhotoSourcePicker, onDismiss: { guard let action = pendingAction else { return } pendingAction = nil diff --git a/BusinessCard/Views/Sheets/ContactFieldEditorSheet.swift b/BusinessCard/Views/Sheets/ContactFieldEditorSheet.swift index 3a0c18e..42f0cd0 100644 --- a/BusinessCard/Views/Sheets/ContactFieldEditorSheet.swift +++ b/BusinessCard/Views/Sheets/ContactFieldEditorSheet.swift @@ -190,6 +190,7 @@ struct ContactFieldEditorSheet: View { .background(Color.AppBackground.base) .navigationTitle(isEditing ? "Edit \(fieldType.displayName)" : "Add \(fieldType.displayName)") .navigationBarTitleDisplayMode(.inline) + .keyboardDismissable() .toolbar { ToolbarItem(placement: .cancellationAction) { Button { diff --git a/BusinessCard/Views/Sheets/RecordContactSheet.swift b/BusinessCard/Views/Sheets/RecordContactSheet.swift index 405d9ee..64d5a97 100644 --- a/BusinessCard/Views/Sheets/RecordContactSheet.swift +++ b/BusinessCard/Views/Sheets/RecordContactSheet.swift @@ -35,6 +35,7 @@ struct RecordContactSheet: View { } .navigationTitle(String.localized("Track Share")) .navigationBarTitleDisplayMode(.inline) + .keyboardDismissable() .toolbar { ToolbarItem(placement: .cancellationAction) { Button(String.localized("Cancel")) {