import { observer } from "mobx-react"; import { SearchIcon } from "outline-icons"; import * as React from "react"; import { useTranslation } from "react-i18next"; import { useHistory } from "react-router-dom"; import styled, { useTheme } from "styled-components"; import useBoolean from "~/hooks/useBoolean"; import useKeyDown from "~/hooks/useKeyDown"; import { isModKey } from "~/utils/keyboard"; import { searchPath } from "~/utils/routeHelpers"; import Input, { Outline } from "./Input"; type Props = { /** A string representing where the search started, for tracking. */ source: string; /** Placeholder text for the input. */ placeholder?: string; /** Label for the input. */ label?: string; /** Whether the label should be hidden. */ labelHidden?: boolean; /** An optional ID of a collection to search within. */ collectionId?: string; /** The current value of the input. */ value?: string; /** Event handler for when the input value changes. */ onChange?: (event: React.ChangeEvent) => unknown; /** Event handler for when a key is pressed. */ onKeyDown?: (event: React.KeyboardEvent) => unknown; }; function InputSearchPage({ onKeyDown, value, onChange, placeholder, label, collectionId, source, }: Props) { const inputRef = React.useRef(null); const theme = useTheme(); const history = useHistory(); const { t } = useTranslation(); const [isFocused, setFocused, setUnfocused] = useBoolean(false); useKeyDown("f", (ev: KeyboardEvent) => { if (isModKey(ev) && document.activeElement !== inputRef.current) { ev.preventDefault(); inputRef.current?.focus(); } }); const handleKeyDown = React.useCallback( (ev: React.KeyboardEvent) => { if (ev.nativeEvent.isComposing) { return; } if (ev.key === "Enter") { ev.preventDefault(); history.push( searchPath(ev.currentTarget.value, { collectionId, ref: source, }) ); } if (ev.key === "Escape") { ev.preventDefault(); inputRef.current?.blur(); } if (onKeyDown) { onKeyDown(ev); } }, [history, collectionId, source, onKeyDown] ); return ( } label={label} onFocus={setFocused} onBlur={setUnfocused} margin={0} labelHidden /> ); } const InputMaxWidth = styled(Input)` max-width: 30vw; ${Outline} { border-radius: 16px; } `; export default observer(InputSearchPage);