diff --git a/dev/app.js b/dev/app.js index 473a3a8a8..fddc39e5e 100644 --- a/dev/app.js +++ b/dev/app.js @@ -4,9 +4,7 @@ docsearch({ apiKey: 'e3d767b736584dbe6d4c35f7cf7d4633', indexName: 'react-native', inputSelector: '#search-input', - autocompleteOptions: { - debug: true - } + debug: true }); document.getElementById('search-input').focus(); diff --git a/src/lib/DocSearch.js b/src/lib/DocSearch.js index 50877176a..4a219a4d1 100644 --- a/src/lib/DocSearch.js +++ b/src/lib/DocSearch.js @@ -40,9 +40,12 @@ class DocSearch { debug: false, hint: false, autoselect: true - } + }, + transformData = false, + enhancedSearchInput = false, + layout = 'collumns' }) { - DocSearch.checkArguments({apiKey, indexName, inputSelector, debug, algoliaOptions, autocompleteOptions}); + DocSearch.checkArguments({apiKey, indexName, inputSelector, debug, algoliaOptions, autocompleteOptions, transformData, enhancedSearchInput, layout}); this.apiKey = apiKey; this.appId = appId; @@ -52,15 +55,25 @@ class DocSearch { let autocompleteOptionsDebug = autocompleteOptions && autocompleteOptions.debug ? autocompleteOptions.debug: false; autocompleteOptions.debug = debug || autocompleteOptionsDebug; this.autocompleteOptions = autocompleteOptions; + this.autocompleteOptions.cssClasses = { + prefix: 'ds' + }; + + this.isSimpleLayout = (layout === 'simple'); this.client = algoliasearch(this.appId, this.apiKey); this.client.addAlgoliaAgent('docsearch.js ' + version); + if (enhancedSearchInput) { + DocSearch.injectSearchBox(this.input); + } + this.autocomplete = autocomplete(this.input, autocompleteOptions, [{ - source: this.getAutocompleteSource(), + source: this.getAutocompleteSource(transformData), templates: { - suggestion: DocSearch.getSuggestionTemplate(), - footer: templates.footer + suggestion: DocSearch.getSuggestionTemplate(this.isSimpleLayout), + footer: templates.footer, + empty: DocSearch.getEmptyTemplate() } }]); this.autocomplete.on( @@ -89,6 +102,11 @@ class DocSearch { } } + static injectSearchBox(input) { + input.before(templates.searchBox); + input.remove(); + } + /** * Returns the matching input from a CSS selector, null if none matches * @function getInputFromSelector @@ -108,14 +126,18 @@ class DocSearch { * @returns {function} Method to be passed as the `source` option of * autocomplete */ - getAutocompleteSource() { + getAutocompleteSource(transformData) { return (query, callback) => { this.client.search([{ indexName: this.indexName, query: query, params: this.algoliaOptions }]).then((data) => { - callback(DocSearch.formatHits(data.results[0].hits)); + let hits = data.results[0].hits; + if (transformData) { + hits = transformData(hits) || hits; + } + callback(DocSearch.formatHits(hits)); }); }; } @@ -187,10 +209,17 @@ class DocSearch { return null; } - static getSuggestionTemplate() { + static getEmptyTemplate() { + return (args) => { + return Hogan.compile(templates.empty).render(args); + }; + } + + static getSuggestionTemplate(isSimpleLayout) { const template = Hogan.compile(templates.suggestion); return (suggestion) => { - return template.render(suggestion); + isSimpleLayout = isSimpleLayout || false; + return template.render({isSimpleLayout, ...suggestion}); }; } diff --git a/src/lib/templates.js b/src/lib/templates.js index f2ed8b210..32cbc9040 100644 --- a/src/lib/templates.js +++ b/src/lib/templates.js @@ -7,6 +7,7 @@ let templates = {
{{{category}}}
@@ -27,6 +28,55 @@ let templates = {
Search by
+ `, + empty: ` +
+
+
+
+
+ No results found for query {{{query}}} +
+
+
+
+
+ `, + searchBox: ` + + + + + + + + + + + + ` }; diff --git a/src/styles/main.scss b/src/styles/main.scss index c504441d2..552ce416c 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -6,7 +6,7 @@ // - Adding a second colum to let the content breath if enough room available // Main autocomplete wrapper -.aa-dropdown-menu { +.ds-dropdown-menu { background-color: #FFF; border: 1px solid #333; border-radius: 4px; @@ -56,10 +56,10 @@ } // Selected suggestion -.aa-cursor .algolia-docsearch-suggestion--content { +.ds-cursor .algolia-docsearch-suggestion--content { color: $color-selected-text; } -.aa-cursor .algolia-docsearch-suggestion { +.ds-cursor .algolia-docsearch-suggestion { background: $color-selected-background; } @@ -79,10 +79,10 @@ border-top: 1px solid lighten($color-border, 60%); } - .algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--content, - .algolia-docsearch-suggestion__secondary .algolia-docsearch-suggestion--content { - border-top: 0; - } +.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--content, +.algolia-docsearch-suggestion__secondary .algolia-docsearch-suggestion--content { + border-top: 0; +} .algolia-docsearch-suggestion--subcategory-inline { display: inline-block; @@ -121,7 +121,7 @@ // BREAKPOINT 1: // Screen is big enough to display the text snippets @media (min-width: $breakpoint-medium) { - .aa-dropdown-menu { + .ds-dropdown-menu { min-width: $dropdown-min-width-medium; } .algolia-docsearch-suggestion--text { @@ -134,7 +134,7 @@ // BREAKPOINT 2: // Screen is big enough to display results in two columns @media (min-width: $breakpoint-large) { - .aa-dropdown-menu { + .ds-dropdown-menu { min-width: $dropdown-min-width-large; } .algolia-docsearch-suggestion { diff --git a/test/DocSearch-test.js b/test/DocSearch-test.js index 54f961699..9595649c5 100644 --- a/test/DocSearch-test.js +++ b/test/DocSearch-test.js @@ -168,7 +168,7 @@ describe('DocSearch', () => { // Then expect(typeof actual.algoliaOptions).toEqual('object'); expect(actual.algoliaOptions.anOption).toEqual(42); - expect(actual.autocompleteOptions).toEqual({debug: false, anOption: 44}); + expect(actual.autocompleteOptions).toEqual({debug: false, "cssClasses": { "prefix": "ds" }, anOption: 44}); }); it('should instantiate algoliasearch with the correct values', () => { // Given @@ -205,7 +205,7 @@ describe('DocSearch', () => { // Then expect(AutoComplete.calledOnce).toBe(true); - expect(AutoComplete.calledWith($input, {anOption: '44', debug: false})).toBe(true); + expect(AutoComplete.calledWith($input, {anOption: '44', "cssClasses": { "prefix": "ds" }, debug: false})).toBe(true); }); it('should listen to the selected and shown event of autocomplete', () => { // Given @@ -980,11 +980,11 @@ describe('DocSearch', () => { let actual = DocSearch.getSuggestionTemplate(); // When - actual('foo'); + actual({'foo': 'bar'}); // Then expect(render.calledOnce).toBe(true); - expect(render.calledWith('foo')).toBe(true); + expect(render.args[0][0]).toEqual({'isSimpleLayout': false, 'foo': 'bar'}); }); }); });