diff --git a/_sass/_layout.scss b/_sass/_layout.scss index 80cd9a3c..357fffa5 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -230,6 +230,36 @@ font-size: 20px; } +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + clip-path: inset(50%); + white-space: nowrap; + border: 0; +} + +.conference-search { + margin-bottom: 15px; +} + +.conference-search__input { + width: 100%; + padding: 10px 12px; + border: 1px solid $grey-color-light; + border-radius: 4px; + box-sizing: border-box; +} + +.conference-search__results, +.conference-search__empty { + margin: 10px 0 0; +} + .post-list { margin-left: 0; list-style: none; diff --git a/assets/conference-search.js b/assets/conference-search.js new file mode 100644 index 00000000..d7a6ab0b --- /dev/null +++ b/assets/conference-search.js @@ -0,0 +1,57 @@ +document.addEventListener('DOMContentLoaded', function () { + var searchInputs = document.querySelectorAll('[data-conference-search-input]'); + + searchInputs.forEach(function (input) { + var listId = input.getAttribute('aria-controls'); + var list = document.getElementById(listId); + + if (!list) { + return; + } + + var items = Array.from(list.querySelectorAll('li')); + var searchContainer = input.closest('.conference-search'); + if (!searchContainer) { + return; + } + var results = searchContainer.querySelector('[data-conference-search-results]'); + var emptyState = searchContainer.querySelector('[data-conference-search-empty]'); + + items.forEach(function (item) { + item.dataset.searchText = item.textContent.replace(/\s+/g, ' ').trim().toLowerCase(); + }); + + function resultText(visibleCount, query) { + var noun = visibleCount === 1 ? 'result' : 'results'; + + if (query) { + return visibleCount + ' ' + noun + ' for "' + query + '"'; + } + + return ''; + } + + function filterItems() { + var displayQuery = input.value.replace(/\s+/g, ' ').trim(); + var query = displayQuery.toLowerCase(); + var visibleCount = 0; + + items.forEach(function (item) { + var isMatch = !query || item.dataset.searchText.indexOf(query) !== -1; + + item.hidden = !isMatch; + + if (isMatch) { + visibleCount += 1; + } + }); + + results.textContent = resultText(visibleCount, displayQuery); + emptyState.hidden = visibleCount !== 0 || !query; + } + + input.addEventListener('input', filterItems); + input.addEventListener('search', filterItems); + filterItems(); + }); +}); diff --git a/index.html b/index.html index ace0eeb2..adfd7e68 100644 --- a/index.html +++ b/index.html @@ -2,8 +2,20 @@ layout: default ---
No upcoming conferences matched your search.
+No past conferences matched your search.
+