Skip to content

Commit

Permalink
feat(docsearch): introduce favorite searches
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour committed Apr 3, 2020
1 parent 3cc88fa commit 708b470
Show file tree
Hide file tree
Showing 37 changed files with 507 additions and 406 deletions.
File renamed without changes.
58 changes: 43 additions & 15 deletions src/DocSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { getAlgoliaHits } from '@francoischalifour/autocomplete-preset-algolia';
import {
DocSearchHit,
InternalDocSearchHit,
RecentDocSearchHit,
StoredDocSearchHit,
} from './types';
import { createSearchClient, groupBy, noop } from './utils';
import { SearchBox } from './SearchBox';
import { Dropdown } from './Dropdown';
import { ScreenState } from './ScreenState';
import { Footer } from './Footer';

import { createRecentSearches } from './recent-searches';
import { createStoredSearches } from './stored-searches';

interface DocSearchProps {
appId?: string;
Expand Down Expand Up @@ -48,7 +48,18 @@ export function DocSearch({
appId,
apiKey,
]);
const recentSearches = useRef(createRecentSearches<RecentDocSearchHit>());
const recentSearches = useRef(
createStoredSearches<StoredDocSearchHit>({
key: '__DOCSEARCH_RECENT_SEARCHES__',
limit: 5,
})
).current;
const favoriteSearches = useRef(
createStoredSearches<StoredDocSearchHit>({
key: '__DOCSEARCH_FAVORITE_SEARCHES__',
limit: 10,
})
).current;

const autocomplete = React.useMemo(
() =>
Expand Down Expand Up @@ -128,14 +139,26 @@ export function DocSearch({
return [
{
onSelect({ suggestion }) {
recentSearches.current.saveSearch(suggestion);
recentSearches.add(suggestion);
onClose();
},
getSuggestionUrl({ suggestion }) {
return suggestion.url;
},
getSuggestions() {
return recentSearches.current.getSearches();
return recentSearches.getAll();
},
},
{
onSelect({ suggestion }) {
recentSearches.add(suggestion);
onClose();
},
getSuggestionUrl({ suggestion }) {
return suggestion.url;
},
getSuggestions() {
return favoriteSearches.getAll();
},
},
];
Expand All @@ -144,7 +167,7 @@ export function DocSearch({
return Object.values<DocSearchHit[]>(sources).map(items => {
return {
onSelect({ suggestion }) {
recentSearches.current.saveSearch(suggestion);
recentSearches.add(suggestion);
onClose();
},
getSuggestionUrl({ suggestion }) {
Expand Down Expand Up @@ -177,7 +200,14 @@ export function DocSearch({
});
},
}),
[indexName, searchParameters, searchClient, onClose]
[
indexName,
searchParameters,
searchClient,
onClose,
recentSearches,
favoriteSearches,
]
);

const { getEnvironmentProps, getRootProps } = autocomplete;
Expand Down Expand Up @@ -244,18 +274,16 @@ export function DocSearch({
</header>

<div className="DocSearch-Dropdown" ref={dropdownRef}>
<Dropdown
<ScreenState
{...autocomplete}
state={state}
inputRef={inputRef}
recentSearches={recentSearches}
favoriteSearches={favoriteSearches}
onItemClick={item => {
recentSearches.current.saveSearch(item);
recentSearches.add(item);
onClose();
}}
onAction={item => {
recentSearches.current.deleteSearch(item);
autocomplete.refresh();
}}
inputRef={inputRef}
/>
</div>

Expand Down
49 changes: 0 additions & 49 deletions src/Dropdown/Dropdown.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/Dropdown/index.ts

This file was deleted.

110 changes: 110 additions & 0 deletions src/EmptyScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import {
AutocompleteApi,
AutocompleteState,
} from '@francoischalifour/autocomplete-core';

import { StoredDocSearchHit } from './types';
import { StoredSearchPlugin } from './stored-searches';
import { Results } from './Results';
import { ResetIcon, RecentIcon, StarIcon } from './icons';

interface EmptyScreenProps
extends AutocompleteApi<
StoredDocSearchHit,
React.FormEvent,
React.MouseEvent,
React.KeyboardEvent
> {
state: AutocompleteState<StoredDocSearchHit>;
hasSuggestions: boolean;
onItemClick(item: StoredDocSearchHit): void;
recentSearches: StoredSearchPlugin<StoredDocSearchHit>;
favoriteSearches: StoredSearchPlugin<StoredDocSearchHit>;
}

export function EmptyScreen(props: EmptyScreenProps) {
if (props.state.status === 'idle' && props.hasSuggestions === false) {
return (
<div className="DocSearch-EmptyScreen">
<p className="DocSearch-Help">Your search history will appear here.</p>
</div>
);
}

if (props.hasSuggestions === false) {
return null;
}

return (
<div className="DocSearch-Dropdown-Container">
<Results
{...props}
title="Recent"
suggestion={props.state.suggestions[0]}
renderIcon={() => (
<div className="DocSearch-Hit-icon">
<RecentIcon />
</div>
)}
renderAction={({ item }) => (
<>
<div className="DocSearch-Hit-action">
<button
className="DocSearch-Hit-action-button"
title="Save this search"
onClick={event => {
event.preventDefault();
event.stopPropagation();
props.favoriteSearches.add(item);
props.refresh();
}}
>
<StarIcon />
</button>
</div>
<div className="DocSearch-Hit-action">
<button
className="DocSearch-Hit-action-button"
title="Remove this search from history"
onClick={event => {
event.preventDefault();
event.stopPropagation();
props.recentSearches.remove(item);
props.refresh();
}}
>
<ResetIcon />
</button>
</div>
</>
)}
/>

<Results
{...props}
title="Favorites"
suggestion={props.state.suggestions[1]}
renderIcon={() => (
<div className="DocSearch-Hit-icon">
<StarIcon />
</div>
)}
renderAction={({ item }) => (
<button
className="DocSearch-Hit-action-button"
title="Remove this search from favorite"
onClick={event => {
event.preventDefault();
event.stopPropagation();
props.favoriteSearches.remove(item);
props.refresh();
}}
>
<ResetIcon />
</button>
)}
/>
</div>
);
}
Loading

0 comments on commit 708b470

Please sign in to comment.