/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import * as React from 'react'; import {useCallback, useContext, useEffect, useRef} from 'react'; import {TreeDispatcherContext, TreeStateContext} from './TreeContext'; import Button from '../Button'; import ButtonIcon from '../ButtonIcon'; import Icon from '../Icon'; import styles from './SearchInput.css'; type Props = {||}; export default function SearchInput(props: Props) { const {searchIndex, searchResults, searchText} = useContext(TreeStateContext); const dispatch = useContext(TreeDispatcherContext); const inputRef = useRef(null); const handleTextChange = useCallback( ({currentTarget}) => dispatch({type: 'SET_SEARCH_TEXT', payload: currentTarget.value}), [dispatch], ); const resetSearch = useCallback( () => dispatch({type: 'SET_SEARCH_TEXT', payload: ''}), [dispatch], ); const handleKeyDown = useCallback( event => { // For convenience, let up/down arrow keys change Tree selection. switch (event.key) { case 'ArrowDown': dispatch({type: 'SELECT_NEXT_ELEMENT_IN_TREE'}); event.preventDefault(); break; case 'ArrowUp': dispatch({type: 'SELECT_PREVIOUS_ELEMENT_IN_TREE'}); event.preventDefault(); break; default: break; } }, [dispatch], ); const handleInputKeyPress = useCallback( ({key, shiftKey}) => { if (key === 'Enter') { if (shiftKey) { dispatch({type: 'GO_TO_PREVIOUS_SEARCH_RESULT'}); } else { dispatch({type: 'GO_TO_NEXT_SEARCH_RESULT'}); } } }, [dispatch], ); // Auto-focus search input useEffect(() => { if (inputRef.current === null) { return () => {}; } const handleWindowKey = (event: KeyboardEvent) => { const {key, metaKey} = event; if (key === 'f' && metaKey) { if (inputRef.current !== null) { inputRef.current.focus(); event.preventDefault(); event.stopPropagation(); } } }; // It's important to listen to the ownerDocument to support the browser extension. // Here we use portals to render individual tabs (e.g. Profiler), // and the root document might belong to a different window. const ownerDocument = inputRef.current.ownerDocument; ownerDocument.addEventListener('keydown', handleWindowKey); return () => ownerDocument.removeEventListener('keydown', handleWindowKey); }, [inputRef]); return (
{!!searchText && ( {Math.min(searchIndex + 1, searchResults.length)} |{' '} {searchResults.length} )}
); }