Select First Tag Suggestion using TAB

This commit is contained in:
Otavio Cordeiro 2025-12-28 01:02:45 +01:00 committed by Otávio
parent 4d95a7d40f
commit eaef589399
6 changed files with 72 additions and 3 deletions

View file

@ -74,7 +74,7 @@ struct EditPictureView: View {
.autocorrectionDisabled(true)
.font(.body.monospaced())
.textFieldCard()
.help("Enter a tag and press the return key to add it")
.help("Enter a tag and press the return key to add it, or press tab to select the first suggestion")
.onSubmit {
withAnimation {
viewModel.addTag(viewModel.tagInput)
@ -83,6 +83,14 @@ struct EditPictureView: View {
.onChange(of: viewModel.tagInput) {
viewModel.updateTagSuggestions(from: existingTags.map(\.title))
}
.onKeyPress(.tab) {
do {
try viewModel.selectFistTagSuggestion()
return .handled
} catch {
return .ignored
}
}
}
@ViewBuilder

View file

@ -7,6 +7,13 @@ import PicsRepository
@Observable
final class EditPictureViewModel {
// MARK: - Nested types
enum TagSelectionError: Error {
case noSuggestions
}
// MARK: - Properties
let pictureID: String
@ -108,4 +115,12 @@ final class EditPictureViewModel {
func removeTag(_ tag: String) {
tags.removeAll { $0 == tag }
}
func selectFistTagSuggestion() throws(TagSelectionError) {
guard let tag = suggestedTags.first else {
throw .noSuggestions
}
addTag(tag)
}
}

View file

@ -185,7 +185,7 @@ struct UploadView: View {
.autocorrectionDisabled(true)
.font(.body.monospaced())
.textFieldCard()
.help("Enter a tag and press the return key to add it")
.help("Enter a tag and press the return key to add it, or press tab to select the first suggestion")
.onSubmit {
withAnimation(.easeInOut(duration: 0.2)) {
viewModel.addTag(viewModel.tagInput)
@ -194,6 +194,14 @@ struct UploadView: View {
.onChange(of: viewModel.tagInput) {
viewModel.updateTagSuggestions(from: existingTags.map(\.title))
}
.onKeyPress(.tab) {
do {
try viewModel.selectFistTagSuggestion()
return .handled
} catch {
return .ignored
}
}
}
@ViewBuilder

View file

@ -9,6 +9,13 @@ import UniformTypeIdentifiers
@Observable
final class UploadViewModel {
// MARK: - Nested types
enum TagSelectionError: Error {
case noSuggestions
}
// MARK: - Properties
var caption = ""
@ -145,6 +152,14 @@ final class UploadViewModel {
tags.removeAll { $0 == tag }
}
func selectFistTagSuggestion() throws(TagSelectionError) {
guard let tag = suggestedTags.first else {
throw .noSuggestions
}
addTag(tag)
}
// MARK: - Private
private func setUpObservers() {

View file

@ -122,7 +122,7 @@ struct EditorView: View {
.autocorrectionDisabled(true)
.font(.body.monospaced())
.textFieldCard()
.help("Enter a tag and press the return key to add it")
.help("Enter a tag and press the return key to add it, or press tab to select the first suggestion")
.onSubmit {
withAnimation {
viewModel.addTag(viewModel.tagInput)
@ -131,6 +131,14 @@ struct EditorView: View {
.onChange(of: viewModel.tagInput) {
viewModel.updateTagSuggestions(from: existingTags.map(\.title))
}
.onKeyPress(.tab) {
do {
try viewModel.selectFistTagSuggestion()
return .handled
} catch {
return .ignored
}
}
}
@ViewBuilder

View file

@ -7,6 +7,13 @@ import WeblogRepository
@Observable
final class EditorViewModel {
// MARK: - Nested types
enum TagSelectionError: Error {
case noSuggestions
}
// MARK: - Properties
var body: String
@ -115,4 +122,12 @@ final class EditorViewModel {
func removeTag(_ tag: String) {
tags.removeAll { $0 == tag }
}
func selectFistTagSuggestion() throws(TagSelectionError) {
guard let tag = suggestedTags.first else {
throw .noSuggestions
}
addTag(tag)
}
}