import { useEffect, useRef, useState } from "react"; import { ChevronUp, ChevronDown, X } from "lucide-react"; import { COLORS, FONT } from "./theme"; import { getSearch } from "./searchRegistry"; import type { ISearchOptions } from "@xterm/addon-search"; const SEARCH_OPTS: ISearchOptions = { decorations: { matchBackground: COLORS.searchMatch, matchOverviewRuler: COLORS.stWait, activeMatchBackground: COLORS.stWait, activeMatchColorOverviewRuler: COLORS.stWait, }, }; export function SearchBar({ surfaceId, reopenNonce, onClose, }: { surfaceId: string | null; reopenNonce: number; onClose: () => void; }) { const [term, setTerm] = useState(""); const [count, setCount] = useState({ index: -1, total: 0 }); const inputRef = useRef(null); useEffect(() => { inputRef.current?.focus(); inputRef.current?.select(); }, [reopenNonce]); useEffect(() => { inputRef.current?.focus(); if (!surfaceId) return; const addon = getSearch(surfaceId); if (!addon) return; const sub = addon.onDidChangeResults((r) => setCount({ index: r.resultIndex, total: r.resultCount }) ); return () => { sub.dispose(); addon.clearDecorations(); }; }, [surfaceId]); function run(forward: boolean, override?: string) { if (!surfaceId) return; const addon = getSearch(surfaceId); const query = override ?? term; if (!addon || !query) { addon?.clearDecorations(); setCount({ index: -1, total: 0 }); return; } if (forward) addon.findNext(query, SEARCH_OPTS); else addon.findPrevious(query, SEARCH_OPTS); } return (
{ const value = e.target.value; setTerm(value); if (!value) { setCount({ index: -1, total: 0 }); if (surfaceId) getSearch(surfaceId)?.clearDecorations(); } else { run(true, value); // search-as-you-type } }} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); run(!e.shiftKey); } else if (e.key === "Escape") { e.preventDefault(); onClose(); } }} placeholder="Search scrollback" style={{ width: 150, background: "transparent", border: "none", outline: "none", color: COLORS.textPrimary, fontFamily: FONT.ui, fontSize: 13, }} /> {count.total > 0 ? `${count.index + 1}/${count.total}` : "0/0"} run(false)} /> run(true)} />
); }