- Create ui/src/lib/slash-commands.ts with SLASH_COMMANDS (5 commands) and resolveAgentFromContent - Create ChatSlashCommandPopover (260px, opens upward, /search greyed with Coming soon) - Add test coverage for routing logic (slash commands, @mentions, fallback)
69 lines
2 KiB
TypeScript
69 lines
2 KiB
TypeScript
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
|
import {
|
|
Command,
|
|
CommandEmpty,
|
|
CommandGroup,
|
|
CommandItem,
|
|
CommandList,
|
|
} from "@/components/ui/command";
|
|
import { SLASH_COMMANDS } from "../lib/slash-commands";
|
|
import { cn } from "../lib/utils";
|
|
|
|
interface ChatSlashCommandPopoverProps {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSelect: (command: string) => void;
|
|
query: string;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export function ChatSlashCommandPopover({
|
|
open,
|
|
onOpenChange,
|
|
onSelect,
|
|
query,
|
|
children,
|
|
}: ChatSlashCommandPopoverProps) {
|
|
const filtered = SLASH_COMMANDS.filter((cmd) =>
|
|
cmd.command.toLowerCase().includes(query.toLowerCase()),
|
|
);
|
|
|
|
return (
|
|
<Popover open={open} onOpenChange={onOpenChange}>
|
|
<PopoverTrigger asChild>{children}</PopoverTrigger>
|
|
<PopoverContent
|
|
className="w-[260px] p-0"
|
|
align="start"
|
|
side="top"
|
|
onOpenAutoFocus={(e) => e.preventDefault()}
|
|
>
|
|
<Command>
|
|
<CommandList>
|
|
<CommandEmpty>No matching commands</CommandEmpty>
|
|
<CommandGroup>
|
|
{filtered.map((cmd) => (
|
|
<CommandItem
|
|
key={cmd.command}
|
|
disabled={cmd.disabled}
|
|
onSelect={() => {
|
|
if (!cmd.disabled) {
|
|
onSelect(cmd.command);
|
|
onOpenChange(false);
|
|
}
|
|
}}
|
|
className={cn("flex flex-col items-start", cmd.disabled && "opacity-50")}
|
|
>
|
|
<span className="text-sm font-medium">{cmd.command}</span>
|
|
<span className="text-[13px] text-muted-foreground">
|
|
{cmd.description}
|
|
{cmd.disabled && " (Coming soon)"}
|
|
</span>
|
|
</CommandItem>
|
|
))}
|
|
</CommandGroup>
|
|
</CommandList>
|
|
</Command>
|
|
</PopoverContent>
|
|
</Popover>
|
|
);
|
|
}
|