Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2026-02-10 21:23:06 -06:00
parent 3e9436791a
commit fb5260f603
8 changed files with 48 additions and 5 deletions

View File

@ -109,6 +109,8 @@ struct BusinessCardApp: App {
RootTabView() RootTabView()
.environment(appState) .environment(appState)
.preferredColorScheme(appState.preferredColorScheme) .preferredColorScheme(appState.preferredColorScheme)
.autocorrectionDisabled(true)
.textInputAutocapitalization(.never)
} }
} }
} }

View File

@ -196,3 +196,23 @@ extension Color {
/// Legacy alias - use AppText instead /// Legacy alias - use AppText instead
typealias Text = AppText 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())
}
}

View File

@ -240,6 +240,7 @@ struct CardEditorView: View {
.safeAreaInset(edge: .bottom) { .safeAreaInset(edge: .bottom) {
PreviewCardButton { showingPreview = true } PreviewCardButton { showingPreview = true }
} }
.keyboardDismissable()
.navigationTitle(isEditing ? String.localized("Edit Card") : String.localized("New Card")) .navigationTitle(isEditing ? String.localized("Edit Card") : String.localized("New Card"))
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.toolbar { .toolbar {
@ -1048,17 +1049,28 @@ private struct AccreditationsRow: View {
private struct PreviewCardButton: View { private struct PreviewCardButton: View {
let action: () -> Void let action: () -> Void
@Environment(\.colorScheme) private var colorScheme
var body: some View { var body: some View {
Button(action: action) { Button(action: action) {
Text("Preview card") Text("Preview card")
.typography(.heading) .typography(.heading)
.foregroundStyle(.white) .foregroundStyle(Color.AppText.inverted)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.padding(Design.Spacing.medium) .padding(Design.Spacing.medium)
.background(Color.Text.primary) .background(AppThemeAccent.primary)
.clipShape(.rect(cornerRadius: Design.CornerRadius.large)) .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(.horizontal, Design.Spacing.large)
.padding(.vertical, Design.Spacing.medium) .padding(.vertical, Design.Spacing.medium)
.background(.ultraThinMaterial) .background(.ultraThinMaterial)

View File

@ -13,7 +13,7 @@ struct ContactFieldPickerView: View {
HStack { HStack {
Text("Tap a field below to add it") Text("Tap a field below to add it")
.typography(.subheading) .typography(.subheading)
.foregroundStyle(Color.Text.primary) .foregroundStyle(Color.Text.secondary)
Spacer() Spacer()
@ -23,7 +23,7 @@ struct ContactFieldPickerView: View {
} }
.padding(.horizontal, Design.Spacing.medium) .padding(.horizontal, Design.Spacing.medium)
.padding(.vertical, Design.Spacing.small) .padding(.vertical, Design.Spacing.small)
.background(Color.AppBackground.accent) .background(Color.AppBackground.secondary)
.clipShape(.rect(cornerRadius: Design.CornerRadius.medium)) .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
LazyVGrid(columns: columns, spacing: Design.Spacing.large) { LazyVGrid(columns: columns, spacing: Design.Spacing.large) {
@ -35,7 +35,12 @@ struct ContactFieldPickerView: View {
} }
} }
.padding(Design.Spacing.large) .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)
)
} }
} }

View File

@ -606,6 +606,7 @@ private struct AddNoteSheet: View {
.padding(Design.Spacing.medium) .padding(Design.Spacing.medium)
.navigationTitle(String.localized("Notes")) .navigationTitle(String.localized("Notes"))
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.keyboardDismissable()
.toolbar { .toolbar {
ToolbarItem(placement: .cancellationAction) { ToolbarItem(placement: .cancellationAction) {
Button(String.localized("Cancel")) { Button(String.localized("Cancel")) {

View File

@ -187,6 +187,7 @@ struct AddContactSheet: View {
} }
.navigationTitle(String.localized("New contact")) .navigationTitle(String.localized("New contact"))
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.keyboardDismissable()
.sheet(isPresented: $showingPhotoSourcePicker, onDismiss: { .sheet(isPresented: $showingPhotoSourcePicker, onDismiss: {
guard let action = pendingAction else { return } guard let action = pendingAction else { return }
pendingAction = nil pendingAction = nil

View File

@ -190,6 +190,7 @@ struct ContactFieldEditorSheet: View {
.background(Color.AppBackground.base) .background(Color.AppBackground.base)
.navigationTitle(isEditing ? "Edit \(fieldType.displayName)" : "Add \(fieldType.displayName)") .navigationTitle(isEditing ? "Edit \(fieldType.displayName)" : "Add \(fieldType.displayName)")
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.keyboardDismissable()
.toolbar { .toolbar {
ToolbarItem(placement: .cancellationAction) { ToolbarItem(placement: .cancellationAction) {
Button { Button {

View File

@ -35,6 +35,7 @@ struct RecordContactSheet: View {
} }
.navigationTitle(String.localized("Track Share")) .navigationTitle(String.localized("Track Share"))
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.keyboardDismissable()
.toolbar { .toolbar {
ToolbarItem(placement: .cancellationAction) { ToolbarItem(placement: .cancellationAction) {
Button(String.localized("Cancel")) { Button(String.localized("Cancel")) {