diff --git a/demo/dev.umd.html b/demo/dev.umd.html
index 04281af..d49ccfa 100644
--- a/demo/dev.umd.html
+++ b/demo/dev.umd.html
@@ -182,6 +182,29 @@
Dummy input to test keyboard nav
minLength: 1,
limit: 10,
retainFocus: true,
+ hooks: {
+ updateHits: async (resultSet) => {
+
+ const response = await fetch(
+ "https://raw.githubusercontent.com/digitalfortress-tech/typeahead-standalone/master/docs/assets/json/superheroes.json",
+ {
+ method: 'GET',
+ }
+ );
+
+ const text = await response.text();
+ const data = text && JSON.parse(text);
+
+ const hits = data.results.slice(0,10)
+
+ // const hits = resultSet.hits.filter(hit => hit.popularity && hit.popularity > 50);
+
+ return {
+ hits,
+ count: hits.length,
+ };
+ }
+ },
templates: {
suggestion: (item) => {
const date = item.release_date
diff --git a/src/common.d.ts b/src/common.d.ts
index 8604e50..7e43f71 100644
--- a/src/common.d.ts
+++ b/src/common.d.ts
@@ -274,6 +274,19 @@ export interface typeaheadConfig {
* It defaults to true.
*/
retainFocus?: boolean;
+ /**
+ * Hooks to be able to perform fine-tuning of results
+ */
+ hooks?: {
+ /**
+ * The updateHits hook allows you to modify/filter/sort the search results before being rendered
+ * @param hits The found results
+ * @returns
+ */
+ updateHits: (
+ resultSet: Pick, 'hits' | 'query' | 'count'>
+ ) => Promise | Promise, 'hits' | 'count'>>;
+ };
}
export interface ResultSet {
diff --git a/src/typeahead-standalone.ts b/src/typeahead-standalone.ts
index 6487f43..6fc6958 100644
--- a/src/typeahead-standalone.ts
+++ b/src/typeahead-standalone.ts
@@ -68,6 +68,9 @@ const typeahead = (config: typeaheadConfig): typeaheadR
...(config.classNames || {}),
};
const listScrollOptions: ScrollIntoViewOptions = { block: 'nearest', ...(config.listScrollOptions || {}) };
+ const hooks = {
+ updateHits: config.hooks?.updateHits || NOOP,
+ };
// validate presence of atleast one data-source
if (!local && !prefetch && !remote) throw new Error('e02');
@@ -305,7 +308,18 @@ const typeahead = (config: typeaheadConfig): typeaheadR
/**
* Responsible for drawing/updating the view
*/
- const update = (): void => {
+ const update = async (): Promise => {
+ // hook to update Hits before displaying results from tree
+ const results_mod = await hooks.updateHits({
+ hits: resultSet.hits,
+ query: resultSet.query,
+ count: resultSet.count,
+ });
+ if (results_mod?.hits?.length) {
+ resultSet.hits = results_mod.hits;
+ resultSet.count = results_mod.count ?? results_mod.hits.length;
+ }
+
// No Matches
if (noSuggestionsHandler()) return;
@@ -521,7 +535,7 @@ const typeahead = (config: typeaheadConfig): typeaheadR
startFetch();
};
- const startFetch = (): void => {
+ const startFetch = async (): Promise => {
clearRemoteDebounceTimer();
const val = input.value.replace(/\s{2,}/g, ' ').trim();
@@ -533,7 +547,7 @@ const typeahead = (config: typeaheadConfig): typeaheadR
// inject default suggestions if they were updated in the empty() template
if (Array.isArray(emptyTemplateResp) && emptyTemplateResp.length) {
resultSet.hits = normalizer(emptyTemplateResp, keys[0]) as T[];
- return update();
+ return await update();
}
// inject empty html template only if default suggestions aren't provided