* rebuild keyboard navigation lists * add new keyboard navigation components * remove references to boundless-arrow-key-navigation * fix aria-labels on paginated lists everywhere
89 lines
2.0 KiB
TypeScript
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);
|