macOS: command palette selection tweaks

pull/7153/head
Mitchell Hashimoto 2025-04-21 10:26:18 -07:00
parent 6dad763e69
commit baad082438
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
1 changed files with 17 additions and 21 deletions

View File

@ -45,6 +45,14 @@ struct CommandPaletteView: View {
}
}
var selectedOption: CommandOption? {
if selectedIndex < filteredOptions.count {
filteredOptions[Int(selectedIndex)]
} else {
filteredOptions.last
}
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
CommandPaletteQuery(query: $query) { event in
@ -54,9 +62,7 @@ struct CommandPaletteView: View {
case .submit:
isPresented = false
if selectedIndex < filteredOptions.count {
filteredOptions[Int(selectedIndex)].action()
}
selectedOption?.action()
case .move(.up):
if selectedIndex > 0 {
@ -78,8 +84,7 @@ struct CommandPaletteView: View {
.padding(.bottom, 4)
CommandTable(
options: options,
query: $query,
options: filteredOptions,
selectedIndex: $selectedIndex,
hoveredOptionID: $hoveredOptionID) { option in
isPresented = false
@ -148,23 +153,12 @@ fileprivate struct CommandPaletteQuery: View {
fileprivate struct CommandTable: View {
var options: [CommandOption] = CommandOption.sampleData
@Binding var query: String
@Binding var selectedIndex: UInt
@Binding var hoveredOptionID: UUID?
var action: (CommandOption) -> Void
// The options that we should show, taking into account any filtering from
// the query.
var filteredOptions: [CommandOption] {
if query.isEmpty {
return options
} else {
return options.filter { $0.title.localizedCaseInsensitiveContains(query) }
}
}
var body: some View {
if filteredOptions.isEmpty {
if options.isEmpty {
Text("No matches")
.foregroundStyle(.secondary)
.padding()
@ -172,10 +166,12 @@ fileprivate struct CommandTable: View {
ScrollViewReader { proxy in
ScrollView(showsIndicators: false) {
VStack(alignment: .leading, spacing: 0) {
ForEach(Array(filteredOptions.enumerated()), id: \.1.id) { index, option in
ForEach(Array(options.enumerated()), id: \.1.id) { index, option in
CommandRow(
option: option,
isSelected: selectedIndex == index,
isSelected: selectedIndex == index ||
(selectedIndex >= options.count &&
index == options.count - 1),
hoveredID: $hoveredOptionID
) {
action(option)
@ -185,10 +181,10 @@ fileprivate struct CommandTable: View {
}
.frame(height: 200)
.onChange(of: selectedIndex) { _ in
guard selectedIndex < filteredOptions.count else { return }
guard selectedIndex < options.count else { return }
withAnimation {
proxy.scrollTo(
filteredOptions[Int(selectedIndex)].id,
options[Int(selectedIndex)].id,
anchor: .center)
}
}