import { useDebouncedCallback } from '@mantine/hooks'; import { SupportedEntry } from 'ontime-types'; import { KeyboardEvent, useState } from 'react'; import Input from '../../../common/components/input/input/Input'; import Kbd from '../../../common/components/kbd/Kbd'; import Modal from '../../../common/components/modal/Modal'; import useFinder from './useFinder'; import style from './Finder.module.scss'; interface FinderProps { isOpen: boolean; onClose: () => void; } export default function Finder({ isOpen, onClose }: FinderProps) { const { find, select, results, error } = useFinder(); const [selected, setSelected] = useState(0); const debouncedFind = useDebouncedCallback(find, 100); const navigate = (event: KeyboardEvent) => { // all operations need results if (results.length === 0) { return; } if (event.key === 'ArrowDown') { setSelected((prev) => (prev + 1) % results.length); } if (event.key === 'ArrowUp') { setSelected((prev) => (prev - 1 + results.length) % results.length); } if (event.key === 'Enter') { event.preventDefault(); event.stopPropagation(); submit(); } }; const submit = () => { const selectedEvent = results[selected]; select(selectedEvent); onClose(); }; const handleMouseMoveEvent = (event: React.MouseEvent) => { const target = event.target as HTMLElement; const li = target.closest('li'); if (li) { const index = Number(li.dataset.index); if (!isNaN(index)) { setSelected(index); } } }; return (
    {error &&
  • {error}
  • } {results.length === 0 &&
  • No results
  • } {results.length > 0 && results.map((entry, index) => { const isSelected = selected === index; const displayIndex = entry.type === SupportedEntry.Event ? entry.eventIndex : '-'; const displayCue = 'cue' in entry ? entry.cue : ''; return (
  • {displayIndex}
    {displayCue}
    {entry.title}
    {isSelected && Go ⏎}
  • ); })}
} footerElements={
Navigate Enter Go Esc Close
Filter by cue, index, or title
} /> ); }