cf2f1c96a3
Arrow up/down cycles through items with highlight. Enter selects the highlighted item. Escape dismisses the dropdown. Index resets when the query changes.
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
import { SLASH_COMMANDS } from "../lib/slashCommands";
|
|
|
|
interface CommandDropdownProps {
|
|
query: string;
|
|
selectedIndex: number;
|
|
onSelect: (command: string) => void;
|
|
}
|
|
|
|
export function CommandDropdown({ query, selectedIndex, onSelect }: CommandDropdownProps) {
|
|
const q = query.toLowerCase();
|
|
const filtered = SLASH_COMMANDS.filter((c) => c.name.startsWith(q)).slice(0, 8);
|
|
|
|
if (filtered.length === 0) return null;
|
|
|
|
return (
|
|
<div className="absolute bottom-full left-0 mb-1 z-50 w-72 max-h-48 overflow-y-auto bg-gb-bg-s border border-gb-bg-t shadow-lg">
|
|
<div className="px-2 py-1 text-xs text-gb-fg-s font-mono border-b border-gb-bg-t">
|
|
COMMANDS
|
|
</div>
|
|
{filtered.map((cmd, i) => (
|
|
<button
|
|
key={cmd.name}
|
|
type="button"
|
|
onMouseDown={(e) => {
|
|
e.preventDefault();
|
|
onSelect(cmd.name);
|
|
}}
|
|
className={`w-full text-left px-2 py-1 text-sm font-mono flex items-center gap-2 transition-colors ${
|
|
i === selectedIndex
|
|
? "bg-gb-orange text-gb-bg"
|
|
: "hover:bg-gb-bg-t text-gb-fg"
|
|
}`}
|
|
>
|
|
<span className={i === selectedIndex ? "text-gb-bg" : "text-gb-orange"}>
|
|
/{cmd.name}
|
|
</span>
|
|
<span className={`text-xs truncate ${i === selectedIndex ? "text-gb-bg" : "text-gb-fg-f"}`}>
|
|
{cmd.description}
|
|
</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|