Skip to content

Commit

Permalink
fix(docsearch): limit query size
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Apr 4, 2020
1 parent 80983f5 commit 49c6347
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 20 deletions.
26 changes: 21 additions & 5 deletions src/DocSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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), [
Expand Down Expand Up @@ -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)');
Expand All @@ -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;
Expand Down Expand Up @@ -292,7 +308,7 @@ export function DocSearch({
<SearchBox
{...autocomplete}
state={state}
initialQuery={initialQuery}
autoFocus={initialQuery.length === 0}
onClose={onClose}
inputRef={inputRef}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/EmptyScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
18 changes: 4 additions & 14 deletions src/SearchBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -17,7 +18,7 @@ interface SearchBoxProps
React.KeyboardEvent
> {
state: AutocompleteState<InternalDocSearchHit>;
initialQuery: string;
autoFocus: boolean;
inputRef: MutableRefObject<HTMLInputElement | null>;
onClose(): void;
}
Expand All @@ -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 (
<>
Expand All @@ -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,
})}
/>

Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MAX_QUERY_SIZE = 64;

0 comments on commit 49c6347

Please sign in to comment.