import FreeSearchAction from "./FreeSearchAction"; import Icon from "./Icon"; import List from "./List"; import ListItem from "./ListItem"; import React, { ReactNode, useRef, useState, useEffect, Fragment } from "react"; import { RenderLink } from "../types"; import { RenderLinkContext, SearchContext, SelectContext, } from "../lib/context"; import { SearchIcon } from "@heroicons/react/outline"; import { Transition, Dialog } from "@headlessui/react"; import { XCircleIcon } from "@heroicons/react/solid"; interface CommandPaletteProps { onChangeSearch: (search: string) => void; onChangeOpen: (isOpen: boolean) => void; renderLink?: RenderLink; children: ReactNode; isOpen: boolean; search: string; } function CommandPalette({ onChangeSearch, onChangeOpen, renderLink, children, isOpen, search, }: CommandPaletteProps) { const inputRef = useRef(null); const [selected, setSelected] = useState(0); function handleChangeSelected(direction?: "up" | "down") { const items = document.querySelectorAll(".command-palette-list-item"); let index = 0; let newIndex = 0; let newItem: Element; if (direction === "down") { items.forEach((_, i) => { if (i === selected) { index = i; } }); newIndex = index === items.length - 1 ? 0 : index + 1; } else if (direction === "up") { items.forEach((_, i) => { if (i === selected) { index = i; } }); newIndex = !index ? items.length - 1 : index - 1; } else { setSelected(0); } newItem = items[newIndex]; if (newItem && typeof newIndex === "number") { setSelected(newIndex); newItem.scrollIntoView({ behavior: "smooth", block: newIndex ? "center" : "end", }); } } function handleSelect() { const items = document.querySelectorAll( ".command-palette-list-item" ) as NodeListOf; let index = 0; let item: HTMLAnchorElement | HTMLButtonElement; items.forEach((_, i) => { if (i === selected) { index = i; } }); item = items[index]; if (item) { item.click(); } } useEffect(() => { handleChangeSelected(); }, [search]); return (
{ if ( e.key === "ArrowDown" || (e.ctrlKey && e.key === "n") || (e.ctrlKey && e.key === "j") ) { e.preventDefault(); e.stopPropagation(); handleChangeSelected("down"); } else if ( e.key === "ArrowUp" || (e.ctrlKey && e.key === "p") || (e.ctrlKey && e.key === "k") ) { e.preventDefault(); e.stopPropagation(); handleChangeSelected("up"); } else if (e.key === "Enter") { handleSelect(); } }} > { onChangeOpen(false); onChangeSearch(""); }} >
{ onChangeSearch(e.currentTarget.value); }} placeholder="Search" value={search} type="search" autoFocus /> {search && ( )}
{children}
); } CommandPalette.List = List; CommandPalette.ListItem = ListItem; CommandPalette.Icon = Icon; CommandPalette.FreeSearchAction = FreeSearchAction; export default CommandPalette;