From 9252f218f04bf7cf6c053ca23497e3de48533f6f Mon Sep 17 00:00:00 2001 From: eunjae-lee Date: Wed, 9 Sep 2020 21:38:16 +0200 Subject: [PATCH] resolve getSources from plugins too --- .../autocomplete-core/src/getDefaultProps.ts | 20 +++++++- packages/autocomplete-core/src/types/api.ts | 23 +++++++++ packages/autocomplete-core/src/utils.ts | 24 ++++----- .../package.json | 3 ++ .../rollup.config.js | 1 + .../src/createPlugin.ts | 50 +++++++++++-------- 6 files changed, 84 insertions(+), 37 deletions(-) diff --git a/packages/autocomplete-core/src/getDefaultProps.ts b/packages/autocomplete-core/src/getDefaultProps.ts index 49a4b3648..2bcc44f00 100644 --- a/packages/autocomplete-core/src/getDefaultProps.ts +++ b/packages/autocomplete-core/src/getDefaultProps.ts @@ -3,7 +3,7 @@ import { generateAutocompleteId, getItemsCount, noop, - normalizeGetSources, + getNormalizedSources, } from './utils'; export function getDefaultProps( @@ -41,7 +41,23 @@ export function getDefaultProps( context: {}, ...props.initialState, }, - getSources: normalizeGetSources(props.getSources), + getSources: (options) => { + const getSourcesFromPlugins = (props.plugins || []) + .map((plugin) => plugin.getSources) + .filter((getSources) => getSources !== undefined); + + return Promise.all( + [...getSourcesFromPlugins, props.getSources].map((getSources) => + getNormalizedSources(getSources!, options) + ) + ).then((nested) => + // same as `nested.flat()` + nested.reduce((acc, array) => { + acc = acc.concat(array); + return acc; + }, []) + ); + }, navigator: { navigate({ suggestionUrl }) { environment.location.assign(suggestionUrl); diff --git a/packages/autocomplete-core/src/types/api.ts b/packages/autocomplete-core/src/types/api.ts index f941d95b7..8638e2b19 100644 --- a/packages/autocomplete-core/src/types/api.ts +++ b/packages/autocomplete-core/src/types/api.ts @@ -153,6 +153,25 @@ interface Navigator { }): void; } +export type AutocompletePlugin = { + /** + * The sources to get the suggestions from. + */ + getSources?( + params: GetSourcesParams + ): + | Array> + | Promise>>; + /** + * The function called when the autocomplete form is submitted. + */ + onSubmit?(params: OnSubmitParams): void; + /** + * Function called when an item is selected. + */ + onSelect?(params: OnSelectParams): void; +}; + export interface PublicAutocompleteOptions { /** * Whether to consider the experience in debug mode. @@ -247,6 +266,10 @@ export interface PublicAutocompleteOptions { * updating the state. */ onInput?(params: OnInputParams): void; + /** + * The array of plugins. + */ + plugins?: Array>; } // Props manipulated internally with default values. diff --git a/packages/autocomplete-core/src/utils.ts b/packages/autocomplete-core/src/utils.ts index 29d2c5280..6d798feba 100644 --- a/packages/autocomplete-core/src/utils.ts +++ b/packages/autocomplete-core/src/utils.ts @@ -3,7 +3,6 @@ import { AutocompleteSource, AutocompleteState, AutocompleteSuggestion, - GetSources, PublicAutocompleteOptions, PublicAutocompleteSource, } from './types'; @@ -57,18 +56,17 @@ function normalizeSource( }; } -export function normalizeGetSources( - getSources: PublicAutocompleteOptions['getSources'] -): GetSources { - return (options) => { - return Promise.resolve(getSources(options)).then((sources) => - Promise.all( - sources.filter(Boolean).map((source) => { - return Promise.resolve(normalizeSource(source)); - }) - ) - ); - }; +export function getNormalizedSources( + getSources: PublicAutocompleteOptions['getSources'], + options +): Promise>> { + return Promise.resolve(getSources(options)).then((sources) => + Promise.all( + sources.filter(Boolean).map((source) => { + return Promise.resolve(normalizeSource(source)); + }) + ) + ); } export function getNextHighlightedIndex( diff --git a/packages/autocomplete-plugin-recent-searches/package.json b/packages/autocomplete-plugin-recent-searches/package.json index a7e504ace..30608544a 100644 --- a/packages/autocomplete-plugin-recent-searches/package.json +++ b/packages/autocomplete-plugin-recent-searches/package.json @@ -10,6 +10,9 @@ "umd:main": "dist/umd/index.js", "unpkg": "dist/umd/index.js", "jsdelivr": "dist/umd/index.js", + "peerDependencies": { + "@algolia/autocomplete-core": "^1.0.0-alpha.28" + }, "scripts": { "build:clean": "rm -rf ./dist", "build:esm": "babel src --root-mode upward --extensions '.ts,.tsx' --out-dir dist/esm", diff --git a/packages/autocomplete-plugin-recent-searches/rollup.config.js b/packages/autocomplete-plugin-recent-searches/rollup.config.js index ed757380a..be58b7a35 100644 --- a/packages/autocomplete-plugin-recent-searches/rollup.config.js +++ b/packages/autocomplete-plugin-recent-searches/rollup.config.js @@ -12,5 +12,6 @@ export default { name: pkg.name, banner: getBundleBanner(pkg), }, + external: ['@algolia/autocomplete-core'], plugins, }; diff --git a/packages/autocomplete-plugin-recent-searches/src/createPlugin.ts b/packages/autocomplete-plugin-recent-searches/src/createPlugin.ts index ce83fc05b..a3cfe556e 100644 --- a/packages/autocomplete-plugin-recent-searches/src/createPlugin.ts +++ b/packages/autocomplete-plugin-recent-searches/src/createPlugin.ts @@ -1,14 +1,18 @@ +import { AutocompletePlugin } from '@algolia/autocomplete-core'; + import { createRecentSearchStore } from './createRecentSearchStore'; -type Plugin = { - getSources: Function; - onSubmit: Function; - add: Function; +type PluginOptions = { + limit?: number; }; -type CreatePlugin = (options?: any) => Plugin; +type RecentSearchesPlugin = AutocompletePlugin & { + getFacetFilters: () => string[]; +}; -export const createPlugin: CreatePlugin = ({ limit = 5 } = {}) => { +export function createPlugin({ + limit = 5, +}: PluginOptions = {}): RecentSearchesPlugin { const store = createRecentSearchStore({ key: 'RECENT_SEARCHES', limit, @@ -16,18 +20,20 @@ export const createPlugin: CreatePlugin = ({ limit = 5 } = {}) => { return { getSources: ({ query }) => { - return [ - !query && { - getInputValue: ({ suggestion }) => suggestion.query, - getSuggestions() { - return store.getAll(); - }, - onSelect({ suggestion }) { - store.add(suggestion); - }, - templates: { - item({ item }) { - return ` + return query + ? [] + : [ + { + getInputValue: ({ suggestion }) => suggestion.query, + getSuggestions() { + return store.getAll(); + }, + onSelect({ suggestion }) { + store.add(suggestion); + }, + templates: { + item({ item }) { + return `
@@ -39,10 +45,10 @@ export const createPlugin: CreatePlugin = ({ limit = 5 } = {}) => {
`; + }, + }, }, - }, - }, - ]; + ]; }, onSubmit: ({ state }) => { store.add({ @@ -57,4 +63,4 @@ export const createPlugin: CreatePlugin = ({ limit = 5 } = {}) => { return store.getAll().map((item) => [`objectID:-${item.query}`]); }, }; -}; +}