import { useEffect, useRef, useState } from "react"; import * as Popover from "@radix-ui/react-popover"; import { NestedCardThemeProvider } from "components/ThemeManager/ThemeProvider"; import { Input } from "./Input"; export const Combobox = ({ results, onSelect, children, onOpenChange, highlighted, setHighlighted, searchValue, setSearchValue, showSearch, trigger, triggerClassName, sideOffset, open: openProp, }: { children: React.ReactNode; trigger?: React.ReactNode; triggerClassName?: string; results: string[]; onSelect?: () => void; onOpenChange?: (open: boolean) => void; highlighted: string | undefined; setHighlighted: (h: string | undefined) => void; searchValue?: string; setSearchValue?: (s: string) => void; showSearch?: boolean; sideOffset?: number; open?: boolean; }) => { let ref = useRef(null); let [internalOpen, setInternalOpen] = useState(false); let open = openProp ?? internalOpen; useEffect(() => { if (!highlighted || !results.find((result) => result === highlighted)) setHighlighted(results[0]); if (results.length === 1) { setHighlighted(results[0]); } }, [results, setHighlighted, highlighted]); useEffect(() => { let listener = async (e: KeyboardEvent) => { let reverseDir = ref.current?.dataset.side === "top"; let currentHighlightIndex = results.findIndex( (result) => highlighted && result === highlighted, ); if (reverseDir ? e.key === "ArrowUp" : e.key === "ArrowDown") { setHighlighted( results[ currentHighlightIndex === results.length - 1 || currentHighlightIndex === undefined ? 0 : currentHighlightIndex + 1 ], ); return; } if (reverseDir ? e.key === "ArrowDown" : e.key === "ArrowUp") { setHighlighted( results[ currentHighlightIndex === 0 || currentHighlightIndex === undefined || currentHighlightIndex === -1 ? results.length - 1 : currentHighlightIndex - 1 ], ); return; } // on enter, select the highlighted item if (e.key === "Enter") { e.preventDefault(); onSelect?.(); setInternalOpen(false); } }; window.addEventListener("keydown", listener); return () => window.removeEventListener("keydown", listener); }, [highlighted, setHighlighted, results]); return ( { setInternalOpen(newOpen); onOpenChange?.(newOpen); }} >
{trigger}
e.preventDefault()} className={` commandMenuContent group/cmd-menu z-20 w-[264px] flex data-[side=top]:items-end items-start `} >
{showSearch && setSearchValue ? ( setSearchValue(e.target.value)} onClick={(e) => e.stopPropagation()} onPointerDown={(e) => e.stopPropagation()} /> ) : null}
{children}
); }; export const ComboboxResult = (props: { result: string; children: React.ReactNode; onSelect: () => void; highlighted: string | undefined; setHighlighted: (state: string | undefined) => void; className?: string; }) => { let isHighlighted = props.highlighted === props.result; return ( ); };