-
Notifications
You must be signed in to change notification settings - Fork 395
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d65cb99
commit bdac9dd
Showing
8 changed files
with
180 additions
and
7,375 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import documentationSearch from '../index.js'; | ||
|
||
documentationSearch({ | ||
apiKey: 'aaa', | ||
indexName: 'bbb', | ||
inputSelector: 'ccc' | ||
apiKey: '7cad300559017ed67717c9c6cba2666d', | ||
indexName: 'stripe', | ||
inputSelector: '#search-input' | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1 @@ | ||
/* global google */ | ||
|
||
function documentationSearch({ | ||
apiKey, | ||
indexName, | ||
inputSelector | ||
}) { | ||
console.info(apiKey, indexName, inputSelector); | ||
} | ||
|
||
export default documentationSearch; | ||
module.exports = require('./src/lib/main.js'); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import Hogan from 'hogan.js'; | ||
import algoliasearch from 'algoliasearch'; | ||
import autocomplete from 'autocomplete.js'; | ||
import groupBy from 'lodash/collection/groupBy'; | ||
import templates from './templates.js'; | ||
import utils from './utils.js'; | ||
import $ from 'npm-zepto'; | ||
|
||
/** | ||
* Adds an autocomplete dropdown to an input fields | ||
* @function documentationSearch | ||
* @param {string} options.apiKey Read-only API key | ||
* @param {string} options.indexName Name of the index to target | ||
* @param {string} options.inputSelector CSS selector that targets the input | ||
* @param {Object} [options.algoliaOptions] Options to pass the underlying Algolia client | ||
* @param {Object} [options.autocompleteOptions] Options to pass to the underlying autocomplete instance | ||
* @return {Object} | ||
*/ | ||
const usage = `Usage: | ||
documentationSearch({ | ||
apiKey, | ||
indexName, | ||
inputSelector, | ||
[ options.{hint,debug} ] | ||
})`; | ||
class DocumentationSearch { | ||
constructor({ | ||
apiKey, | ||
indexName, | ||
inputSelector, | ||
algoliaOptions = { | ||
hitsPerPage: 5 | ||
}, | ||
autocompleteOptions = { | ||
debug: true, | ||
hint: false | ||
} | ||
}) { | ||
this.checkArguments({apiKey, indexName, inputSelector, algoliaOptions, autocompleteOptions}); | ||
|
||
this.client = algoliasearch('BH4D9OD16A', this.apiKey); | ||
this.autocomplete = autocomplete(this.input, autocompleteOptions, [{ | ||
source: this.getSource(), | ||
templates: { | ||
suggestion: this.getSuggestionTemplate() | ||
} | ||
}]); | ||
this.autocomplete.on('autocomplete:selected', this.handleSelected); | ||
} | ||
|
||
// TEST: | ||
// - Usage error if no apiKey or no indexName | ||
// - Error if nothing matches | ||
// - Error if matches are not input | ||
// - apiKey nad indexName are set | ||
// - input is set to the Zepto-wrapped inputSelector | ||
checkArguments(args) { | ||
if (!args.apiKey || !args.indexName) { | ||
throw new Error(usage); | ||
} | ||
|
||
const input = $(args.inputSelector).filter('input'); | ||
if (input.length === 0) { | ||
throw new Error(`Error: No input element in the page matches ${args.inputSelector}`); | ||
} | ||
|
||
this.apiKey = args.apiKey; | ||
this.indexName = args.indexName; | ||
this.input = input; | ||
this.algoliaOptions = args.algoliaOptions; | ||
this.autocompleteOptions = args.autocompleteOptions; | ||
} | ||
|
||
// Returns a `source` method to be used by `autocomplete`. This will query the | ||
// Algolia index. | ||
getSource() { | ||
return (query, callback) => { | ||
this.client.search([{ | ||
indexName: this.indexName, | ||
query: query, | ||
params: this.algoliaOptions | ||
}]).then((data) => { | ||
callback(this.formatHits(data.results[0].hits)); | ||
}); | ||
}; | ||
} | ||
|
||
// Given a list of hits returned by the API, will reformat them to be used in | ||
// a Hogan template | ||
formatHits(hits) { | ||
// Group hits by category / subcategory | ||
var groupedHits = groupBy(hits, 'category'); | ||
groupedHits.each((list, category) => { | ||
var groupedHitsBySubCategory = groupBy(list, 'subcategory'); | ||
var flattenedHits = utils.flattenObject(groupedHitsBySubCategory, 'isSubcategoryHeader'); | ||
groupedHits[category] = flattenedHits; | ||
}); | ||
groupedHits = utils.flattenObject(groupedHits, 'isCategoryHeader'); | ||
|
||
// Translate hits into smaller objects to be send to the template | ||
return groupedHits.map((hit) => { | ||
return { | ||
isCategoryHeader: hit.isCategoryHeader, | ||
isSubcategoryHeader: hit.isSubcategoryHeader, | ||
category: hit._highlightResult.category ? hit._highlightResult.category.value : hit.category, | ||
subcategory: hit._highlightResult.subcategory ? hit._highlightResult.subcategory.value : hit.category, | ||
title: hit._highlightResult.display_title ? hit._highlightResult.display_title.value : hit.display_title, | ||
text: hit._snippetResult ? hit._snippetResult.text.value : hit.text, | ||
url: hit.url | ||
}; | ||
}); | ||
} | ||
|
||
getSuggestionTemplate() { | ||
const template = Hogan.compile(templates.suggestion); | ||
return (suggestion) => { | ||
return template.render(suggestion); | ||
}; | ||
} | ||
|
||
handleSelected(event, suggestion) { | ||
this.autocomplete.autocomplete.setVal(''); | ||
window.location.href = suggestion.url; | ||
} | ||
} | ||
|
||
export default DocumentationSearch; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import toFactory from 'to-factory'; | ||
import DocumentationSearch from './DocumentationSearch'; | ||
|
||
let documentationSearch = toFactory(DocumentationSearch); | ||
|
||
export default documentationSearch; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
let prefix = 'documentationsearch--suggestion'; | ||
|
||
let templates = { | ||
suggestion: ` | ||
<div class="${prefix} {{#isCategoryHeader}}${prefix}__main{{/isCategoryHeader}} {{#isSubcategoryHeader}}${prefix}__secondary{{/isSubcategoryHeader}}"> | ||
<div class="${prefix}--category-header">{{{category}}}</div> | ||
<div class="${prefix}--wrapper"> | ||
<div class="${prefix}--subcategory">{{{subcategory}}}</div> | ||
<div class="${prefix}--content"> | ||
<div class="${prefix}--subcategory">{{{subcategory}}}</div> | ||
<div class="${prefix}--title">{{{title}}}</div> | ||
<div class="${prefix}--text">{{{text}}}</div> | ||
</div> | ||
</div> | ||
</div> | ||
` | ||
}; | ||
|
||
export default templates; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import values from 'lodash/object/values'; | ||
import flatten from 'lodash/array/flatten'; | ||
|
||
let utils = { | ||
// Flatten all values into one array, marking the first element with | ||
// `flagName` | ||
flattenObject(o, flagName) { | ||
values(o).map((value) => { | ||
value[0][flagName] = true; | ||
}); | ||
return flatten(values); | ||
} | ||
}; | ||
|
||
export default utils; |