From a9a14ce8158afba7a695838850a6047ec274d90b Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 5 Mar 2026 12:52:06 +0100 Subject: [PATCH] feat: hide search results container if no keyword is given (#1288) feat: hide search results container if no keyword is given and add typing --- assets/scss/partials/layout/search.scss | 6 +++ assets/ts/search.tsx | 61 +++++++++++++++---------- layouts/page/search.html | 2 +- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/assets/scss/partials/layout/search.scss b/assets/scss/partials/layout/search.scss index 8cd9d61..3f74da2 100644 --- a/assets/scss/partials/layout/search.scss +++ b/assets/scss/partials/layout/search.scss @@ -78,4 +78,10 @@ } } +} + +.search-result { + &.hidden { + display: none; + } } \ No newline at end of file diff --git a/assets/ts/search.tsx b/assets/ts/search.tsx index 1c81dd1..e932129 100644 --- a/assets/ts/search.tsx +++ b/assets/ts/search.tsx @@ -26,15 +26,15 @@ const tagsToReplace = { '…': '…' }; -function replaceTag(tag) { - return tagsToReplace[tag] || tag; +function replaceTag(tag: string) { + return (tagsToReplace as Record)[tag] || tag; } -function replaceHTMLEnt(str) { +function replaceHTMLEnt(str: string) { return str.replace(/[&<>"]/g, replaceTag); } -function escapeRegExp(string) { +function escapeRegExp(string: string) { return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); } @@ -45,13 +45,21 @@ class Search { private list: HTMLDivElement; private resultTitle: HTMLHeadElement; private resultTitleTemplate: string; + private container: HTMLDivElement; - constructor({ form, input, list, resultTitle, resultTitleTemplate }) { + constructor({ form, input, list, resultTitle, resultTitleTemplate }: { + form: HTMLFormElement, + input: HTMLInputElement, + list: HTMLDivElement, + resultTitle: HTMLHeadingElement, + resultTitleTemplate: string + }) { this.form = form; this.input = input; this.list = list; this.resultTitle = resultTitle; this.resultTitleTemplate = resultTitleTemplate; + this.container = list.parentElement as HTMLDivElement; /// Check if there's already value in the search input if (this.input.value.trim() !== '') { @@ -203,16 +211,18 @@ class Search { const endTime = performance.now(); this.resultTitle.innerText = this.generateResultTitle(results.length, ((endTime - startTime) / 1000).toPrecision(1)); + + this.container?.classList.remove('hidden'); } - private generateResultTitle(resultLen, time) { - return this.resultTitleTemplate.replace("#PAGES_COUNT", resultLen).replace("#TIME_SECONDS", time); + private generateResultTitle(resultLen: number, time: string) { + return this.resultTitleTemplate.replace("#PAGES_COUNT", resultLen.toString()).replace("#TIME_SECONDS", time); } public async getData() { if (!this.data) { /// Not fetched yet - const jsonURL = this.form.dataset.json; + const jsonURL = this.form.dataset.json as string; this.data = await fetch(jsonURL).then(res => res.json()); const parser = new DOMParser(); @@ -227,7 +237,7 @@ class Search { private bindSearchForm() { let lastSearch = ''; - const eventHandler = (e) => { + const eventHandler = (e: Event) => { e.preventDefault(); const keywords = this.input.value.trim(); @@ -251,6 +261,7 @@ class Search { private clear() { this.list.innerHTML = ''; this.resultTitle.innerText = ''; + this.container.classList.add('hidden'); } private bindQueryStringChange() { @@ -261,7 +272,7 @@ class Search { private handleQueryString() { const pageURL = new URL(window.location.toString()); - const keywords = pageURL.searchParams.get('keyword'); + const keywords = pageURL.searchParams.get('keyword') || ''; this.input.value = keywords; if (keywords) { @@ -291,19 +302,21 @@ class Search { } public static render(item: pageData) { - return + ); } } @@ -316,10 +329,12 @@ declare global { window.addEventListener('load', () => { setTimeout(function () { const searchForm = document.querySelector('.search-form') as HTMLFormElement, - searchInput = searchForm.querySelector('input') as HTMLInputElement, + searchInput = searchForm?.querySelector('input') as HTMLInputElement, searchResultList = document.querySelector('.search-result--list') as HTMLDivElement, searchResultTitle = document.querySelector('.search-result--title') as HTMLHeadingElement; + if (!searchForm || !searchInput || !searchResultList || !searchResultTitle) return; + new Search({ form: searchForm, input: searchInput, diff --git a/layouts/page/search.html b/layouts/page/search.html index fbfb74d..b2e056f 100644 --- a/layouts/page/search.html +++ b/layouts/page/search.html @@ -16,7 +16,7 @@ -
+