Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(recentSearches): add remove button #326

Merged
merged 11 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
getAlgoliaHits,
reverseHighlightItem,
} from '@algolia/autocomplete-js';
import { createRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
import '@algolia/autocomplete-plugin-recent-searches/style';

const searchClient = algoliasearch(
'latency',
Expand All @@ -14,10 +16,14 @@ const searchClient = algoliasearch(

type QuerySuggestionHit = { query: string };

const recentSearches = createRecentSearchesPlugin({ key: 'recent' });

autocomplete<Hit<QuerySuggestionHit>>({
container: '#autocomplete',
debug: true,
openOnFocus: true,
// dropdownPlacement: 'start',
plugins: [recentSearches],
getSources({ query }) {
return getAlgoliaHits<QuerySuggestionHit>({
searchClient,
Expand All @@ -27,6 +33,7 @@ autocomplete<Hit<QuerySuggestionHit>>({
query,
params: {
hitsPerPage: 10,
facetFilters: [...recentSearches.data.getFacetFilters()],
},
},
],
Expand Down
1 change: 1 addition & 0 deletions examples/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@algolia/autocomplete-js": "^1.0.0-alpha.32",
"@algolia/autocomplete-plugin-recent-searches": "^1.0.0-alpha.32",
"@algolia/client-search": "4.5.1",
"algoliasearch": "4.5.1"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/autocomplete-core/src/createAutocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function createAutocomplete<
setIsOpen,
setStatus,
setContext,
refresh,
});

function refresh() {
Expand All @@ -57,6 +58,7 @@ export function createAutocomplete<
setIsOpen,
setStatus,
setContext,
refresh,
});
}

Expand Down
8 changes: 8 additions & 0 deletions packages/autocomplete-core/src/getPropGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
InternalAutocompleteOptions,
AutocompleteSetters,
AutocompleteStore,
AutocompleteRefresh,
GetDropdownProps,
GetEnvironmentProps,
GetFormProps,
Expand All @@ -18,6 +19,7 @@ import { getHighlightedItem, isOrContainsNode } from './utils';
interface GetPropGettersOptions<TItem> extends AutocompleteSetters<TItem> {
store: AutocompleteStore<TItem>;
props: InternalAutocompleteOptions<TItem>;
refresh: AutocompleteRefresh;
}

export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
Expand All @@ -29,6 +31,7 @@ export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
setIsOpen,
setStatus,
setContext,
refresh,
}: GetPropGettersOptions<TItem>) {
const getEnvironmentProps: GetEnvironmentProps = (getterProps) => {
return {
Expand Down Expand Up @@ -135,6 +138,7 @@ export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
setIsOpen,
setStatus,
setContext,
refresh,
});
}
store.send('reset', null);
Expand Down Expand Up @@ -165,6 +169,7 @@ export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
setIsOpen,
setStatus,
setContext,
refresh,
});
}

Expand Down Expand Up @@ -205,6 +210,7 @@ export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
setIsOpen,
setStatus,
setContext,
refresh,
});
},
onKeyDown: (event) => {
Expand All @@ -218,6 +224,7 @@ export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
setIsOpen,
setStatus,
setContext,
refresh,
});
},
onFocus,
Expand Down Expand Up @@ -351,6 +358,7 @@ export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
setIsOpen,
setStatus,
setContext,
refresh,
nextState: {
isOpen: false,
},
Expand Down
6 changes: 6 additions & 0 deletions packages/autocomplete-core/src/onInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AutocompleteSetters,
AutocompleteState,
AutocompleteStore,
AutocompleteRefresh,
} from './types';
import { getHighlightedItem } from './utils';

Expand All @@ -21,6 +22,7 @@ interface OnInputParams<TItem> extends AutocompleteSetters<TItem> {
* but we want to close the dropdown in that case.
*/
nextState?: Partial<AutocompleteState<TItem>>;
refresh: AutocompleteRefresh;
}

export function onInput<TItem>({
Expand All @@ -35,6 +37,7 @@ export function onInput<TItem>({
setStatus,
setContext,
nextState = {},
refresh,
}: OnInputParams<TItem>): Promise<void> {
if (props.onInput) {
return Promise.resolve(
Expand All @@ -47,6 +50,7 @@ export function onInput<TItem>({
setIsOpen,
setStatus,
setContext,
refresh,
})
);
}
Expand Down Expand Up @@ -89,6 +93,7 @@ export function onInput<TItem>({
setIsOpen,
setStatus,
setContext,
refresh,
})
.then((sources) => {
setStatus('loading');
Expand All @@ -106,6 +111,7 @@ export function onInput<TItem>({
setIsOpen,
setStatus,
setContext,
refresh,
})
).then((items) => {
return {
Expand Down
5 changes: 5 additions & 0 deletions packages/autocomplete-core/src/onKeyDown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {
InternalAutocompleteOptions,
AutocompleteSetters,
AutocompleteStore,
AutocompleteRefresh,
} from './types';
import { getHighlightedItem } from './utils';

interface OnKeyDownOptions<TItem> extends AutocompleteSetters<TItem> {
event: KeyboardEvent;
store: AutocompleteStore<TItem>;
props: InternalAutocompleteOptions<TItem>;
refresh: AutocompleteRefresh;
}

export function onKeyDown<TItem>({
Expand All @@ -23,6 +25,7 @@ export function onKeyDown<TItem>({
setIsOpen,
setStatus,
setContext,
refresh,
}: OnKeyDownOptions<TItem>): void {
if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
// Default browser behavior changes the caret placement on ArrowUp and
Expand Down Expand Up @@ -91,6 +94,7 @@ export function onKeyDown<TItem>({
setIsOpen,
setStatus,
setContext,
refresh,
});
}
} else if (event.key === 'Escape') {
Expand Down Expand Up @@ -205,6 +209,7 @@ export function onKeyDown<TItem>({
nextState: {
isOpen: false,
},
refresh,
}).then(() => {
source.onSelect({
suggestion: item,
Expand Down
6 changes: 5 additions & 1 deletion packages/autocomplete-core/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export interface AutocompleteApi<
/**
* Triggers a search to refresh the state.
*/
refresh(): Promise<void>;
refresh: AutocompleteRefresh;
}

export type AutocompleteRefresh = () => Promise<void>;

export interface AutocompleteSuggestion<TItem> {
source: InternalAutocompleteSource<TItem>;
items: TItem[];
Expand All @@ -28,6 +30,7 @@ export interface AutocompleteSuggestion<TItem> {
export interface GetSourcesParams<TItem> extends AutocompleteSetters<TItem> {
query: string;
state: AutocompleteState<TItem>;
refresh: AutocompleteRefresh;
}

interface ItemParams<TItem> {
Expand Down Expand Up @@ -58,6 +61,7 @@ interface OnSubmitParams<TItem> extends AutocompleteSetters<TItem> {
interface OnInputParams<TItem> extends AutocompleteSetters<TItem> {
query: string;
state: AutocompleteState<TItem>;
refresh: AutocompleteRefresh;
}

export interface AutocompleteSource<TItem> {
Expand Down
9 changes: 5 additions & 4 deletions packages/autocomplete-plugin-recent-searches/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@algolia/autocomplete-plugin-recent-searches",
"description": "A plugin to add recent searches to Algolia Autocomplete.",
"version": "1.0.0-alpha.30",
"version": "1.0.0-alpha.32",
"license": "MIT",
"source": "src/index.ts",
"types": "dist/esm/index.d.ts",
Expand All @@ -15,9 +15,9 @@
},
"scripts": {
"build:clean": "rm -rf ./dist",
"build:esm": "babel src --root-mode upward --extensions '.ts,.tsx' --out-dir dist/esm --ignore '**/*/__tests__/'",
"build:esm": "babel src --root-mode upward --extensions '.ts,.tsx' --out-dir dist/esm --ignore '**/*/__tests__/' && cp src/style.css ./dist/esm/",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what to do with the style.css file here, so I just copied it to dist on build at the moment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll think about this as a next step. It'd be nice to be able to do:

import '@algolia/autocomplete-plugin-recent-searches/dist/style.css';

// Like DocSearch, with `root/style.js` importing `root/dist/style.css`
import '@algolia/autocomplete-plugin-recent-searches/style';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you show me where it's done? I will apply it in a separate PR.
So far I've found only this: https://github.com/algolia/docsearch/blob/next/packages/docsearch-react/style/variables.js#L1:L1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I think I've done it: c00d92e
Did I do it right? What is enabling this? @babel/preset-env?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good. That's the style loader of the bundler used that understands it (webpack, Parcel etc.).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay. It's the consuming side which understands it.

"build:types": "tsc -p ./tsconfig.declaration.json --outDir ./dist/esm",
"build:umd": "rollup --config",
"build:umd": "rollup --config && cp src/style.css ./dist/umd/",
"build": "rm -rf ./dist && yarn build:umd && yarn build:esm && yarn build:types",
"on:change": "concurrently \"yarn build:esm\" \"yarn build:types\"",
"prepare": "yarn run build:esm",
Expand All @@ -31,7 +31,8 @@
},
"sideEffects": false,
"files": [
"dist/"
"dist/",
"style/"
],
"dependencies": {
"@algolia/autocomplete-core": "^1.0.0-alpha.31"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { AutocompletePlugin } from '@algolia/autocomplete-core';

import { createRecentSearchesStore } from './createRecentSearchesStore';
import { recentIcon } from './recentIcon';
import { resetIcon } from './resetIcon';

type PluginOptions = {
/**
Expand Down Expand Up @@ -38,7 +40,7 @@ export function createRecentSearchesPlugin({
});

return {
getSources: ({ query }) => {
getSources: ({ query, refresh }) => {
if (query) {
return [];
}
Expand All @@ -50,19 +52,36 @@ export function createRecentSearchesPlugin({
return store.getAll();
},
templates: {
item({ item }) {
return `
<div class="autocomplete-item">
<div>
<svg viewBox="0 0 22 22" width="16" height="16" fill="currentColor">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/>
</svg>
item({ item, root }) {
const container = document.createElement('div');
container.className = 'aa-RecentSearchesItem';

<span>${item.query}</span>
</div>
</div>
`;
const leftItems = document.createElement('div');
leftItems.className = 'leftItems';
const icon = document.createElement('div');
icon.className = 'item-icon icon';
icon.innerHTML = recentIcon;
const title = document.createElement('div');
title.className = 'title';
title.innerText = item.query;
leftItems.appendChild(icon);
leftItems.appendChild(title);

const removeButton = document.createElement('button');
removeButton.className = 'item-icon removeButton';
removeButton.type = 'button';
removeButton.innerHTML = resetIcon;
removeButton.title = 'Remove';

container.appendChild(leftItems);
container.appendChild(removeButton);
root.appendChild(container);

removeButton.addEventListener('click', (event) => {
event.stopPropagation();
store.remove(item);
refresh();
});
},
},
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const recentIcon = `<svg viewBox="0 0 22 22" width="20" height="20" fill="currentColor">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9zm-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8H12z"/>
</svg>`;
11 changes: 11 additions & 0 deletions packages/autocomplete-plugin-recent-searches/src/resetIcon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// copied from autocomplete-js
export const resetIcon = `<svg width="20" height="20" viewBox="0 0 20 20">
<path
d="M10 10l5.09-5.09L10 10l5.09 5.09L10 10zm0 0L4.91 4.91 10 10l-5.09 5.09L10 10z"
stroke="currentColor"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</svg>`;
21 changes: 21 additions & 0 deletions packages/autocomplete-plugin-recent-searches/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.aa-RecentSearchesItem {
display: flex;
flex-grow: 1;
justify-content: space-between;
}

.aa-RecentSearchesItem .leftItems {
display: flex;
}

.aa-RecentSearchesItem .removeButton {
border: 0;
background-color: transparent;
cursor: pointer;
opacity: 0.8;
}

.aa-RecentSearchesItem .removeButton:hover {
opacity: 1;
color: #000;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../dist/esm/style.css';