Files
outline/app/scenes/Search/components/SearchInput.tsx
Nan Yu d1b28499c6 chore: new arrow key navigation (#3229)
* rebuild keyboard navigation lists
* add new keyboard navigation components
* remove references to boundless-arrow-key-navigation
* fix aria-labels on paginated lists everywhere
2022-03-15 10:36:10 -07:00

89 lines
2.0 KiB
TypeScript

import { SearchIcon } from "outline-icons";
import * as React from "react";
import styled, { useTheme } from "styled-components";
import Flex from "~/components/Flex";
type Props = React.HTMLAttributes<HTMLInputElement> & {
defaultValue?: string;
placeholder?: string;
};
function SearchInput(
{ defaultValue, ...rest }: Props,
ref: React.RefObject<HTMLInputElement>
) {
const theme = useTheme();
const focusInput = React.useCallback(() => {
ref.current?.focus();
}, [ref]);
React.useEffect(() => {
// ensure that focus is placed at end of input
const len = (defaultValue || "").length;
ref.current?.setSelectionRange(len, len);
const timeoutId = setTimeout(() => {
focusInput();
}, 100); // arbitrary number
return () => {
clearTimeout(timeoutId);
};
}, [ref, defaultValue, focusInput]);
return (
<Wrapper align="center">
<StyledIcon size={46} color={theme.textTertiary} onClick={focusInput} />
<StyledInput
{...rest}
defaultValue={defaultValue}
ref={ref}
spellCheck="false"
type="search"
autoFocus
/>
</Wrapper>
);
}
const Wrapper = styled(Flex)`
position: relative;
margin-bottom: 8px;
`;
const StyledInput = styled.input`
width: 100%;
padding: 10px 10px 10px 60px;
font-size: 36px;
font-weight: 400;
outline: none;
border: 0;
background: ${(props) => props.theme.sidebarBackground};
transition: ${(props) => props.theme.backgroundTransition};
border-radius: 4px;
color: ${(props) => props.theme.text};
::-webkit-search-cancel-button {
-webkit-appearance: none;
}
::-webkit-input-placeholder {
color: ${(props) => props.theme.placeholder};
}
:-moz-placeholder {
color: ${(props) => props.theme.placeholder};
}
::-moz-placeholder {
color: ${(props) => props.theme.placeholder};
}
:-ms-input-placeholder {
color: ${(props) => props.theme.placeholder};
}
`;
const StyledIcon = styled(SearchIcon)`
position: absolute;
left: 8px;
`;
export default React.forwardRef(SearchInput);