Skip to content

Commit 8a679a3

Browse files
Add project (contextual) filter to search (PR #39)
Co-authored-by: Dan Allen <[email protected]>
1 parent 00c0ee6 commit 8a679a3

File tree

5 files changed

+131
-60
lines changed

5 files changed

+131
-60
lines changed

src/css/header.css

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,40 +41,60 @@ body {
4141
justify-content: flex-end;
4242
}
4343

44-
#search-input {
44+
#search {
45+
display: flex;
4546
color: var(--body-font-color);
46-
font-family: inherit;
47-
font-size: 0.95rem;
48-
width: 200px;
47+
width: 20rem;
48+
}
49+
50+
#search > .algolia-autocomplete {
51+
display: inherit !important;
52+
flex: auto;
53+
}
54+
55+
#search .query {
4956
border: 1px solid var(--navbar-button-border-color);
50-
border-radius: 0.1em;
57+
color: inherit;
58+
font-family: inherit;
59+
font-size: inherit;
5160
line-height: 1.5;
52-
padding: 0 0.25em;
61+
padding: 0.125rem 0.25rem;
62+
width: 10ex;
63+
flex: auto;
5364
}
5465

55-
.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] {
56-
max-height: calc(100vh - var(--navbar-height));
66+
#search .query:focus {
67+
outline: none;
5768
}
5869

59-
@media screen and (max-width: 1023.5px) {
60-
.navbar-start .navbar-item + .navbar-item {
61-
display: none;
62-
}
70+
#search.has-filter .query {
71+
border-right: none;
72+
border-radius: 0.1em 0 0 0.1em;
73+
}
6374

64-
/*
65-
.navbar-start .navbar-item + .navbar-item {
66-
padding-left: 0;
67-
padding-right: 0;
68-
}
75+
#search .filter {
76+
background: var(--color-white) linear-gradient(to bottom, var(--navbar-button-border-color) 0%, var(--navbar-button-border-color) 100%) no-repeat left center / 1px 50%;
77+
border: 1px solid var(--navbar-button-border-color);
78+
border-left: none;
79+
border-radius: 0 0.1em 0.1em 0;
80+
cursor: pointer;
81+
font-size: 0.875em;
82+
display: flex;
83+
align-items: center;
84+
padding: 0 0.5rem;
85+
white-space: nowrap;
86+
overflow: hidden;
87+
}
6988

70-
#search-input {
71-
width: 150px;
72-
}
89+
#search .filter input {
90+
margin: 0 0.25rem 0 0;
91+
cursor: inherit;
92+
}
7393

74-
.algolia-autocomplete .ds-dropdown-menu {
75-
min-width: calc(100vw - var(--navbar-height)) !important;
94+
@media screen and (max-width: 1023.5px) {
95+
.navbar-start .navbar-item + .navbar-item {
96+
display: none;
7697
}
77-
*/
7898
}
7999

80100
@media screen and (min-width: 1024px) {

src/css/vendor/docsearch.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
11
@import "docsearch.js/dist/cdn/docsearch.css";
22
@import "../vars.css";
3+
4+
.algolia-autocomplete .ds-dropdown-menu > :first-child {
5+
max-height: calc(100vh - var(--navbar-height));
6+
}
7+
8+
.algolia-autocomplete .algolia-docsearch-suggestion--title {
9+
font-weight: var(--body-font-weight-bold);
10+
}
11+
12+
/*
13+
@media screen and (max-width: 1023px) {
14+
.algolia-autocomplete .ds-dropdown-menu {
15+
min-width: calc(100vw - var(--navbar-height)) !important;
16+
}
17+
}
18+
*/

src/js/vendor/docsearch.bundle.js

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,63 @@
11
;(function () {
22
'use strict'
33

4-
var docsearch = require('docsearch.js/dist/cdn/docsearch.js')
5-
var config = document.getElementById('search-script').dataset
6-
var link = document.createElement('link')
7-
link.rel = 'stylesheet'
8-
link.href = config.stylesheet
9-
document.head.appendChild(link)
10-
var search = docsearch({
11-
appId: config.appId,
12-
apiKey: config.apiKey,
13-
indexName: config.indexName,
14-
inputSelector: '#search-input',
15-
autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
16-
algoliaOptions: { hitsPerPage: parseInt(config.maxResults) || 5 },
17-
}).autocomplete
18-
var autocomplete = search.autocomplete
19-
search.on(
20-
'autocomplete:updated',
21-
function () {
22-
this.scrollTop = 0
23-
}.bind(autocomplete.getWrapper().firstChild)
24-
)
25-
search.on(
26-
'autocomplete:closed',
27-
function () {
28-
this.setVal()
29-
}.bind(autocomplete)
30-
)
4+
activateSearch(require('docsearch.js/dist/cdn/docsearch.js'), document.getElementById('search-script').dataset)
5+
6+
function activateSearch (docsearch, config) {
7+
appendStylesheet(config.stylesheet)
8+
var algoliaOptions = { hitsPerPage: parseInt(config.maxResults) || 15 }
9+
var searchFieldSelector = '#' + (config.searchFieldId || 'search')
10+
var searchField = document.querySelector(searchFieldSelector)
11+
var filterInput = searchField.querySelector('.filter input')
12+
var controller = docsearch({
13+
appId: config.appId,
14+
apiKey: config.apiKey,
15+
indexName: config.indexName,
16+
inputSelector: searchFieldSelector + ' .query',
17+
autocompleteOptions: { debug: true, hint: false, keyboardShortcuts: ['s'], minLength: 2 },
18+
algoliaOptions: algoliaOptions,
19+
queryHook:
20+
filterInput &&
21+
function (query) {
22+
controller.algoliaOptions = filterInput.checked
23+
? Object.assign({}, algoliaOptions, { facetFilters: [filterInput.dataset.facetFilter] })
24+
: algoliaOptions
25+
},
26+
})
27+
var eventEmitter = controller.autocomplete
28+
var autocomplete = eventEmitter.autocomplete
29+
eventEmitter.on('autocomplete:updated', resetScroll.bind(autocomplete.getWrapper().firstChild))
30+
if (filterInput) filterInput.addEventListener('change', toggleFilter.bind(controller.input))
31+
searchField.addEventListener('click', confineEvent)
32+
document.documentElement.addEventListener('click', resetSearch.bind(autocomplete))
33+
if (controller.input.attr('autofocus')) controller.input.focus()
34+
}
35+
36+
function appendStylesheet (href) {
37+
var link = document.createElement('link')
38+
link.rel = 'stylesheet'
39+
link.href = href
40+
document.head.appendChild(link)
41+
}
42+
43+
function resetScroll () {
44+
this.scrollTop = 0
45+
}
46+
47+
function toggleFilter () {
48+
this.focus()
49+
var dropdown = this.data('aaAutocomplete').dropdown
50+
if (!dropdown.isOpen || !this.val()) return
51+
dropdown.datasets[0].cachedSuggestions.length = 0
52+
dropdown.update(this.val())
53+
}
54+
55+
function confineEvent (e) {
56+
e.stopPropagation()
57+
}
58+
59+
function resetSearch () {
60+
this.close()
61+
this.setVal()
62+
}
3163
})()

src/partials/footer-scripts.hbs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,5 @@ MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
2222
{{/unless}}
2323
{{/with}}
2424
{{#if env.ALGOLIA_API_KEY}}
25-
<script async id="search-script" src="{{{uiRootPath}}}/js/vendor/docsearch.js"{{#if env.ALGOLIA_APP_ID}} data-app-id="{{env.ALGOLIA_APP_ID}}"{{/if}} data-api-key="{{env.ALGOLIA_API_KEY}}" data-index-name="{{env.ALGOLIA_IDX_NAME}}" data-max-results="15" data-stylesheet="{{{uiRootPath}}}/css/vendor/docsearch.css"></script>
26-
{{#if page.home}}
27-
<script>
28-
window.addEventListener('load', function focusSearchInput () {
29-
window.removeEventListener('load', focusSearchInput)
30-
document.querySelector('#search-input').focus()
31-
})
32-
</script>
33-
{{/if}}
25+
<script async id="search-script" src="{{{uiRootPath}}}/js/vendor/docsearch.js"{{#if env.ALGOLIA_APP_ID}} data-app-id="{{env.ALGOLIA_APP_ID}}"{{/if}} data-api-key="{{env.ALGOLIA_API_KEY}}" data-index-name="{{env.ALGOLIA_IDX_NAME}}" data-stylesheet="{{{uiRootPath}}}/css/vendor/docsearch.css"></script>
3426
{{/if}}

src/partials/header-content.hbs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,18 @@
1313
<a class="navbar-item" href="{{#with (and site.url site.homeUrl)}}{{{@root.site.url}}}{{{this}}}{{else}}{{{siteRootPath}}}{{/with}}">{{site.title}}</a>
1414
{{#if env.ALGOLIA_API_KEY}}
1515
<div class="navbar-item hide-for-print">
16-
<input id="search-input" type="text" placeholder="Search docs">
16+
{{#if (and page.component (ne page.component.name 'home'))}}
17+
<div id="search" class="field has-filter">
18+
<input class="query" type="text" placeholder="Search the docs">
19+
<label class="filter checkbox">
20+
<input type="checkbox" data-facet-filter="component:{{page.component.name}}"> In this project
21+
</label>
22+
</div>
23+
{{else}}
24+
<div id="search" class="field">
25+
<input class="query" type="text" placeholder="Search the docs"{{#if page.home}} autofocus{{/if}}>
26+
</div>
27+
{{/if}}
1728
</div>
1829
{{/if}}
1930
</div>

0 commit comments

Comments
 (0)