import { useState, useEffect, useCallback, forwardRef, useImperativeHandle, } from "react"; import type { SlashCommandItem } from "./slash-command-items"; export interface SlashCommandListRef { onKeyDown: (props: { event: KeyboardEvent }) => boolean; } interface SlashCommandListProps { items: SlashCommandItem[]; command: (item: SlashCommandItem) => void; } export const SlashCommandList = forwardRef< SlashCommandListRef, SlashCommandListProps >(({ items, command }, ref) => { const [selectedIndex, setSelectedIndex] = useState(0); useEffect(() => { setSelectedIndex(0); }, [items]); const selectItem = useCallback( (index: number) => { const item = items[index]; if (item) { command(item); } }, [items, command], ); useImperativeHandle(ref, () => ({ onKeyDown: ({ event }: { event: KeyboardEvent }) => { if (event.key === "ArrowUp") { setSelectedIndex((prev) => (prev + items.length - 1) % items.length); return true; } if (event.key === "ArrowDown") { setSelectedIndex((prev) => (prev + 1) % items.length); return true; } if (event.key === "Enter") { selectItem(selectedIndex); return true; } return false; }, })); if (items.length === 0) { return null; } return (
{items.map((item, index) => ( ))}
); }); SlashCommandList.displayName = "SlashCommandList";