fix(ui): keep command picker highlight in sync
This commit is contained in:
@@ -103,6 +103,7 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
|
|||||||
let scrollContainerRef: HTMLDivElement | undefined
|
let scrollContainerRef: HTMLDivElement | undefined
|
||||||
let lastWorkspaceId: string | null = null
|
let lastWorkspaceId: string | null = null
|
||||||
let lastQuery = ""
|
let lastQuery = ""
|
||||||
|
let lastCommandQuery = ""
|
||||||
let inflightWorkspaceId: string | null = null
|
let inflightWorkspaceId: string | null = null
|
||||||
let inflightSnapshotPromise: Promise<FileItem[]> | null = null
|
let inflightSnapshotPromise: Promise<FileItem[]> | null = null
|
||||||
let activeRequestId = 0
|
let activeRequestId = 0
|
||||||
@@ -243,6 +244,7 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
|
|||||||
setLoadingState("idle")
|
setLoadingState("idle")
|
||||||
lastWorkspaceId = null
|
lastWorkspaceId = null
|
||||||
lastQuery = ""
|
lastQuery = ""
|
||||||
|
lastCommandQuery = ""
|
||||||
activeRequestId = 0
|
activeRequestId = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,8 +275,6 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (!props.open) return
|
if (!props.open) return
|
||||||
if (mode() !== "mention") return
|
if (mode() !== "mention") return
|
||||||
@@ -303,6 +303,37 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (!props.open) return
|
||||||
|
if (mode() !== "command") return
|
||||||
|
|
||||||
|
const query = props.searchQuery
|
||||||
|
const count = filteredCommands().length
|
||||||
|
|
||||||
|
if (query !== lastCommandQuery) {
|
||||||
|
lastCommandQuery = query
|
||||||
|
setSelectedIndex(0)
|
||||||
|
resetScrollPosition()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count <= 0) {
|
||||||
|
if (selectedIndex() !== 0) {
|
||||||
|
setSelectedIndex(0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const current = selectedIndex()
|
||||||
|
if (current < 0) {
|
||||||
|
setSelectedIndex(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (current >= count) {
|
||||||
|
setSelectedIndex(count - 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const allItems = (): PickerItem[] => {
|
const allItems = (): PickerItem[] => {
|
||||||
const items: PickerItem[] = []
|
const items: PickerItem[] = []
|
||||||
if (mode() === "command") {
|
if (mode() === "command") {
|
||||||
@@ -335,20 +366,24 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
|
|||||||
|
|
||||||
if (e.key === "ArrowDown") {
|
if (e.key === "ArrowDown") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
setSelectedIndex((prev) => Math.min(prev + 1, items.length - 1))
|
setSelectedIndex((prev) => Math.min(prev + 1, items.length - 1))
|
||||||
scrollToSelected()
|
scrollToSelected()
|
||||||
} else if (e.key === "ArrowUp") {
|
} else if (e.key === "ArrowUp") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
setSelectedIndex((prev) => Math.max(prev - 1, 0))
|
setSelectedIndex((prev) => Math.max(prev - 1, 0))
|
||||||
scrollToSelected()
|
scrollToSelected()
|
||||||
} else if (e.key === "Enter" || e.key === "Tab") {
|
} else if (e.key === "Enter" || e.key === "Tab") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
const selected = items[selectedIndex()]
|
const selected = items[selectedIndex()]
|
||||||
if (selected) {
|
if (selected) {
|
||||||
handleSelect(selected)
|
handleSelect(selected)
|
||||||
}
|
}
|
||||||
} else if (e.key === "Escape") {
|
} else if (e.key === "Escape") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
props.onClose()
|
props.onClose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,12 +437,12 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
|
|||||||
<Show when={mode() === "command" && commandCount() > 0}>
|
<Show when={mode() === "command" && commandCount() > 0}>
|
||||||
<div class="dropdown-section-header">{t("unifiedPicker.sections.commands")}</div>
|
<div class="dropdown-section-header">{t("unifiedPicker.sections.commands")}</div>
|
||||||
<For each={filteredCommands()}>
|
<For each={filteredCommands()}>
|
||||||
{(command) => {
|
{(command, index) => {
|
||||||
const itemIndex = allItems().findIndex((item) => item.type === "command" && item.command.name === command.name)
|
const isSelected = () => index() === selectedIndex()
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={`dropdown-item ${itemIndex === selectedIndex() ? "dropdown-item-highlight" : ""}`}
|
class={`dropdown-item ${isSelected() ? "dropdown-item-highlight" : ""}`}
|
||||||
data-picker-selected={itemIndex === selectedIndex()}
|
data-picker-selected={isSelected()}
|
||||||
onClick={() => handleSelect({ type: "command", command })}
|
onClick={() => handleSelect({ type: "command", command })}
|
||||||
>
|
>
|
||||||
<div class="flex items-start gap-2">
|
<div class="flex items-start gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user