feat: hide search results container if no keyword is given (#1288)

feat: hide search results container if no keyword is given and add typing
This commit is contained in:
Jimmy
2026-03-05 12:52:06 +01:00
committed by GitHub
parent 0ad02c5c0f
commit a9a14ce815
3 changed files with 45 additions and 24 deletions
+6
View File
@@ -79,3 +79,9 @@
}
}
.search-result {
&.hidden {
display: none;
}
}
+28 -13
View File
@@ -26,15 +26,15 @@ const tagsToReplace = {
'…': '…'
};
function replaceTag(tag) {
return tagsToReplace[tag] || tag;
function replaceTag(tag: string) {
return (tagsToReplace as Record<string, string>)[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,7 +302,8 @@ class Search {
}
public static render(item: pageData) {
return <article>
return (
<article>
<a href={item.permalink}>
<div class="article-details">
<h2 class="article-title" dangerouslySetInnerHTML={{ __html: item.title }}></h2>
@@ -303,7 +315,8 @@ class Search {
</div>
}
</a>
</article>;
</article>
);
}
}
@@ -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,
+1 -1
View File
@@ -16,7 +16,7 @@
</button>
</form>
<div class="search-result">
<div class="search-result hidden">
<h3 class="search-result--title section-title"></h3>
<div class="search-result--list article-list--compact"></div>
</div>