1
0
Fork 0

fix(docsearch): limit query size

This commit is contained in:
François Chalifour 2020-04-04 14:42:41 +02:00
parent 80983f5245
commit 49c6347d8a
4 changed files with 27 additions and 20 deletions

View file

@ -5,18 +5,18 @@ import {
} from '@francoischalifour/autocomplete-core';
import { getAlgoliaHits } from '@francoischalifour/autocomplete-preset-algolia';
import { MAX_QUERY_SIZE } from './constants';
import {
DocSearchHit,
InternalDocSearchHit,
StoredDocSearchHit,
} from './types';
import { createSearchClient, groupBy, noop } from './utils';
import { createStoredSearches } from './stored-searches';
import { SearchBox } from './SearchBox';
import { ScreenState } from './ScreenState';
import { Footer } from './Footer';
import { createStoredSearches } from './stored-searches';
interface DocSearchProps {
appId?: string;
apiKey: string;
@ -44,7 +44,12 @@ export function DocSearch({
const inputRef = React.useRef<HTMLInputElement | null>(null);
const snipetLength = React.useRef<number>(10);
const initialQuery = React.useRef(
typeof window !== 'undefined' ? window.getSelection()!.toString() : ''
typeof window !== 'undefined'
? window
.getSelection()!
.toString()
.slice(0, MAX_QUERY_SIZE)
: ''
).current;
const searchClient = React.useMemo(() => createSearchClient(appId, apiKey), [
@ -234,7 +239,7 @@ export function DocSearch({
]
);
const { getEnvironmentProps, getRootProps } = autocomplete;
const { getEnvironmentProps, getRootProps, refresh } = autocomplete;
React.useEffect(() => {
const isMobileMediaQuery = window.matchMedia('(max-width: 750px)');
@ -250,6 +255,17 @@ export function DocSearch({
}
}, [state.query]);
// We don't focus the input when there's an initial query (i.e. Selection
// Search) because users rather want to see the results directly, without the
// keyboard appearing.
// We therefore need to refresh the autocomplete instance to load all the
// results, which is usually triggered on focus.
React.useEffect(() => {
if (initialQuery.length > 0) {
refresh();
}
}, [initialQuery, refresh]);
React.useEffect(() => {
if (!(searchBoxRef.current && dropdownRef.current && inputRef.current)) {
return undefined;
@ -292,7 +308,7 @@ export function DocSearch({
<SearchBox
{...autocomplete}
state={state}
initialQuery={initialQuery}
autoFocus={initialQuery.length === 0}
onClose={onClose}
inputRef={inputRef}
/>

View file

@ -95,7 +95,7 @@ export function EmptyScreen(props: EmptyScreenProps) {
<div className="DocSearch-Hit-action">
<button
className="DocSearch-Hit-action-button"
title="Remove this search from favorite"
title="Remove this search from favorites"
onClick={event => {
event.preventDefault();
event.stopPropagation();

View file

@ -4,6 +4,7 @@ import {
AutocompleteState,
} from '@francoischalifour/autocomplete-core';
import { MAX_QUERY_SIZE } from './constants';
import { InternalDocSearchHit } from './types';
import { SearchIcon } from './icons/SearchIcon';
import { ResetIcon } from './icons/ResetIcon';
@ -17,7 +18,7 @@ interface SearchBoxProps
React.KeyboardEvent
> {
state: AutocompleteState<InternalDocSearchHit>;
initialQuery: string;
autoFocus: boolean;
inputRef: MutableRefObject<HTMLInputElement | null>;
onClose(): void;
}
@ -26,17 +27,6 @@ export function SearchBox(props: SearchBoxProps) {
const { onSubmit, onReset } = props.getFormProps({
inputElement: props.inputRef.current,
});
const { initialQuery, refresh } = props;
// We don't focus the input when there's an initial query because users
// rather want to see the results directly. We therefore need to refresh
// the autocomplete instance to load all the results, which is usually
// triggered on focus.
React.useEffect(() => {
if (initialQuery.length > 0) {
refresh();
}
}, [initialQuery, refresh]);
return (
<>
@ -60,10 +50,10 @@ export function SearchBox(props: SearchBoxProps) {
className="DocSearch-Input"
ref={props.inputRef}
{...props.getInputProps({
autoFocus: props.initialQuery.length === 0,
autoFocus: props.autoFocus,
inputElement: props.inputRef.current!,
type: 'search',
maxLength: '512',
maxLength: MAX_QUERY_SIZE,
})}
/>

1
src/constants.ts Normal file
View file

@ -0,0 +1 @@
export const MAX_QUERY_SIZE = 64;