feat(docsearch): add search suggestions
This commit is contained in:
parent
fa42ab2bd9
commit
a448e9ee72
4 changed files with 87 additions and 7 deletions
|
|
@ -51,6 +51,8 @@ export function DocSearch({
|
|||
getInputProps,
|
||||
getMenuProps,
|
||||
getItemProps,
|
||||
setQuery,
|
||||
refresh,
|
||||
} = React.useMemo(
|
||||
() =>
|
||||
createAutocomplete<
|
||||
|
|
@ -66,7 +68,7 @@ export function DocSearch({
|
|||
onStateChange({ state }) {
|
||||
setState(state as any);
|
||||
},
|
||||
getSources({ query }) {
|
||||
getSources({ query, state, setContext }) {
|
||||
return getAlgoliaHits({
|
||||
searchClient,
|
||||
queries: [
|
||||
|
|
@ -117,6 +119,14 @@ export function DocSearch({
|
|||
});
|
||||
const sources = groupBy(formattedHits, hit => hit.hierarchy.lvl0);
|
||||
|
||||
// We store the `lvl0`s to display them as search suggestions
|
||||
// in the “no results“ screen.
|
||||
if (state.context.searchSuggestions === undefined) {
|
||||
setContext({
|
||||
searchSuggestions: Object.keys(sources),
|
||||
});
|
||||
}
|
||||
|
||||
return Object.values<DocSearchHit[]>(sources).map(items => {
|
||||
return {
|
||||
onSelect() {
|
||||
|
|
@ -220,9 +230,12 @@ export function DocSearch({
|
|||
|
||||
<div className="DocSearch-Dropdown" ref={dropdownRef}>
|
||||
<Dropdown
|
||||
inputRef={inputRef}
|
||||
state={state}
|
||||
getMenuProps={getMenuProps}
|
||||
getItemProps={getItemProps}
|
||||
setQuery={setQuery}
|
||||
refresh={refresh}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ interface DropdownProps {
|
|||
state: AutocompleteState<InternalDocSearchHit>;
|
||||
getMenuProps: GetMenuProps;
|
||||
getItemProps: GetItemProps<InternalDocSearchHit, React.MouseEvent>;
|
||||
setQuery(value: string): void;
|
||||
refresh(): Promise<void>;
|
||||
inputRef: React.MutableRefObject<HTMLInputElement>;
|
||||
}
|
||||
|
||||
export function Dropdown(props: DropdownProps) {
|
||||
|
|
@ -25,7 +28,14 @@ export function Dropdown(props: DropdownProps) {
|
|||
props.state.status === 'idle' &&
|
||||
props.state.suggestions.every(source => source.items.length === 0)
|
||||
) {
|
||||
return <NoResults query={props.state.query} />;
|
||||
return (
|
||||
<NoResults
|
||||
setQuery={props.setQuery}
|
||||
refresh={props.refresh}
|
||||
state={props.state}
|
||||
inputRef={props.inputRef}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,12 +1,58 @@
|
|||
import React from 'react';
|
||||
import { AutocompleteState } from '@francoischalifour/autocomplete-core';
|
||||
|
||||
interface NoResultsProps {
|
||||
query: string;
|
||||
state: AutocompleteState<any>;
|
||||
setQuery(value: string): void;
|
||||
refresh(): Promise<void>;
|
||||
inputRef: React.MutableRefObject<HTMLInputElement>;
|
||||
}
|
||||
|
||||
export function NoResults(props: NoResultsProps) {
|
||||
return <div className="DocSearch-NoResults">
|
||||
<div className="Docsearch-Hit-title">No results for “{props.query}“.</div>
|
||||
<div className="DocSearch-Label">Try another search or if you believe this query should lead to actual results, please let us know with a <a href="">GitHub issue</a>.</div>
|
||||
</div>;
|
||||
return (
|
||||
<div className="DocSearch-NoResults">
|
||||
<p className="Docsearch-Hit-title">
|
||||
No results for “{props.state.query}“.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Try searching for{' '}
|
||||
{(props.state.context.searchSuggestions as string[])
|
||||
.slice(0, 3)
|
||||
.reduce<React.ReactNode[]>(
|
||||
(acc, search) => [
|
||||
...acc,
|
||||
acc.length > 0 ? ', ' : '',
|
||||
'“',
|
||||
<button
|
||||
className="DocSearch-Link"
|
||||
key={search}
|
||||
onClick={() => {
|
||||
props.setQuery(search.toLowerCase() + ' ');
|
||||
props.refresh();
|
||||
props.inputRef.current.focus();
|
||||
}}
|
||||
>
|
||||
{search}
|
||||
</button>,
|
||||
'“',
|
||||
],
|
||||
[]
|
||||
)}
|
||||
.
|
||||
</p>
|
||||
|
||||
<p className="DocSearch-Label">
|
||||
If you believe this query should return results, please{' '}
|
||||
<a
|
||||
href="https://github.com/algolia/docsearch-configs/issues/new?template=Missing_results.md"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
let us know on GitHub
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,6 +169,17 @@ html[data-theme='dark'] {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.DocSearch-Link {
|
||||
appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--docsearch-highlight-color);
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.DocSearch-Modal {
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
|
|
|
|||
Loading…
Reference in a new issue