fix(docsearch): limit query size
This commit is contained in:
parent
80983f5245
commit
49c6347d8a
4 changed files with 27 additions and 20 deletions
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
1
src/constants.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const MAX_QUERY_SIZE = 64;
|
||||
Loading…
Reference in a new issue