Skip to content

Commit 884fd68

Browse files
committed
Merge #151: remove dropdown when clicked away from
200eadb remove dropdown when clicked away from (Graeme Byrne) Pull request description: * When the user clicks out of the input box in `SearchBar.svelte`, the dropdown disappears. This change brings the `SearchBar.svelte` here in line with how it is implemented in https://github.com/nautilus-cyberneering/nautilus-website * From the issue nautilus-cyberneering/nautilus-website#38 ACKs for top commit: josecelano: ACK 200eadb Tree-SHA512: 4e77eb38807cbfb8b8e9dc1a5b103a0259afa7b4b89eab6742414a0976f91601b2bfb9ec37ff69d2230548814dd5d3a312b2aae5df95705b235146f3aacb571b
2 parents 541ad7b + 200eadb commit 884fd68

File tree

2 files changed

+70
-46
lines changed

2 files changed

+70
-46
lines changed

src/lib/components/singletons/SearchBar.svelte

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<script lang="ts">
2-
import { createEventDispatcher } from 'svelte';
32
import type { BlogPost } from '$lib/utils/types';
4-
import { onMount } from 'svelte';
53
import { createPostsIndex, searchPostsIndex } from '$lib/utils/search';
64
import Icon from '@iconify/svelte';
5+
import { onMount, onDestroy } from 'svelte';
6+
import { tick } from 'svelte';
77
88
export let searchTerm = '';
99
export let blogPosts: BlogPost[] = [];
1010
11-
const dispatch = createEventDispatcher();
1211
let showInput = true;
13-
let searchInput: HTMLInputElement;
12+
let searchInput: HTMLInputElement | null = null;
13+
let dropdownOpen = false;
1414
1515
interface SearchResult {
1616
slug: string;
@@ -25,27 +25,54 @@
2525
function handleInput(event: Event) {
2626
const input = event.target as HTMLInputElement;
2727
searchTerm = input.value;
28-
dispatch('search', searchTerm);
28+
dropdownOpen = searchTerm.length > 0;
2929
}
3030
3131
function clearSearch() {
3232
searchTerm = '';
33+
dropdownOpen = false;
3334
showInput = false;
3435
}
3536
37+
function handleClickOutside(event: MouseEvent) {
38+
if (searchInput && !searchInput.contains(event.target as Node)) {
39+
dropdownOpen = false;
40+
}
41+
}
42+
43+
function handleKeyDown(event: KeyboardEvent) {
44+
if (event.key === 'Escape') {
45+
dropdownOpen = false;
46+
}
47+
}
48+
3649
onMount(async () => {
3750
createPostsIndex(blogPosts);
3851
search = 'ready';
52+
if (typeof window !== 'undefined') {
53+
window.addEventListener('click', handleClickOutside);
54+
window.addEventListener('keydown', handleKeyDown);
55+
}
56+
});
57+
58+
onDestroy(() => {
59+
if (typeof window !== 'undefined') {
60+
window.removeEventListener('click', handleClickOutside);
61+
window.removeEventListener('keydown', handleKeyDown);
62+
}
3963
});
4064
4165
$: {
4266
if (showInput && searchInput) {
43-
searchInput.focus();
67+
tick().then(() => {
68+
searchInput?.focus();
69+
});
4470
}
4571
}
4672
4773
$: if (search === 'ready') {
4874
results = searchPostsIndex(searchTerm);
75+
dropdownOpen = results.length > 0;
4976
}
5077
</script>
5178

@@ -72,7 +99,7 @@
7299
</div>
73100
{/if}
74101

75-
{#if search === 'ready' && searchTerm}
102+
{#if search === 'ready' && dropdownOpen}
76103
<div class="dropdown">
77104
{#if results.length > 0}
78105
<ul>
@@ -81,22 +108,19 @@
81108
<a href="/blog/{result.slug}" on:click={clearSearch}>
82109
<div>
83110
<div>
84-
<!-- Displaying result title -->
85111
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
86112
{@html result.title}
87113
</div>
88114
<div>
89-
<!-- Displaying result content snippet -->
90115
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
91116
<p>{@html result.content}</p>
92117
</div>
93118
</div>
94119
<div class="tag-container">
95120
{#each result.tags as tag}
96-
<!-- Highlight matching tags -->
97121
{#if tag.toLowerCase().includes(searchTerm.toLowerCase())}
98122
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
99-
<p class="tag" style="color: black;">{@html tag}</p>
123+
<p class="tag">{@html tag}</p>
100124
{/if}
101125
{/each}
102126
</div>

static/blogMetadata.json

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
11
[
2+
{
3+
"title": "Benchmarking the Torrust BitTorrent Tracker",
4+
"slug": "benchmarking-the-torrust-bittorrent-tracker",
5+
"contributor": "Jose Celano",
6+
"contributorSlug": "jose-celano",
7+
"date": "2024-03-19T00:00:00.000Z",
8+
"coverImage": "/images/posts/benchmarking-the-torrust-bittorrent-tracker/benchmarking-the-torrust-bittorrent-tracker-banner.webp",
9+
"excerpt": "In the ever-evolving landscape of BitTorrent technology, performance and scalability are paramount. Torrust stands at the forefront, offering a suite of open-source software products designed to enhance peer-to-peer file sharing. At the heart of this suite is the Torrust BitTorrent Tracker, a Rust-based engine crafted for efficiency and speed. This post will introduce you to the benchmarking tools we are using at the moment for the tracker.",
10+
"tags": [
11+
"Performance",
12+
"Benchmarking"
13+
]
14+
},
15+
{
16+
"title": "Contributor Path",
17+
"slug": "contributor-path",
18+
"contributor": "Jose Celano",
19+
"contributorSlug": "jose-celano",
20+
"date": "2024-10-29T09:20:51.608Z",
21+
"coverImage": "/images/posts/contributor-path/rust-crab-going-safe-into-water.webp",
22+
"excerpt": "Ready to contribute to Torrust? Here's your guide to get started and make meaningful contributions, from small fixes to full-fledged features.",
23+
"tags": [
24+
"Community",
25+
"Onboarding",
26+
"Contributors"
27+
]
28+
},
229
{
330
"title": "Containerizing Rust Applications",
431
"slug": "containerizing-rust-applications-best-practices",
@@ -44,34 +71,6 @@
4471
"Sample"
4572
]
4673
},
47-
{
48-
"title": "Deploying Torrust To Production",
49-
"slug": "deploying-torrust-to-production",
50-
"contributor": "Jose Celano",
51-
"contributorSlug": "jose-celano",
52-
"date": "2023-12-20T00:00:00.000Z",
53-
"coverImage": "/images/posts/deploying-torrust-to-production/deploy-torrust-to-a-digital-ocean-droplet.png",
54-
"excerpt": "Dive into our step-by-step tutorial on deploying a BitTorrent Index and Tracker, written in Rust, on a Digital Ocean droplet. From initial server setup to advanced configurations, this guide is designed for both non-developers and tech-savvy users, ensuring a seamless, production-ready deployment.",
55-
"tags": [
56-
"Tutorial",
57-
"Deployment",
58-
"Production"
59-
]
60-
},
61-
{
62-
"title": "Contributor Path",
63-
"slug": "contributor-path",
64-
"contributor": "Jose Celano",
65-
"contributorSlug": "jose-celano",
66-
"date": "2024-10-29T09:20:51.608Z",
67-
"coverImage": "/images/posts/contributor-path/rust-crab-going-safe-into-water.webp",
68-
"excerpt": "Ready to contribute to Torrust? Here's your guide to get started and make meaningful contributions, from small fixes to full-fledged features.",
69-
"tags": [
70-
"Community",
71-
"Onboarding",
72-
"Contributors"
73-
]
74-
},
7574
{
7675
"title": "Help Shape the Torrust 2025 Roadmap!",
7776
"slug": "help-shape-the-torrust-2025-roadmap",
@@ -86,16 +85,17 @@
8685
]
8786
},
8887
{
89-
"title": "Benchmarking the Torrust BitTorrent Tracker",
90-
"slug": "benchmarking-the-torrust-bittorrent-tracker",
88+
"title": "Deploying Torrust To Production",
89+
"slug": "deploying-torrust-to-production",
9190
"contributor": "Jose Celano",
9291
"contributorSlug": "jose-celano",
93-
"date": "2024-03-19T00:00:00.000Z",
94-
"coverImage": "/images/posts/benchmarking-the-torrust-bittorrent-tracker/benchmarking-the-torrust-bittorrent-tracker-banner.webp",
95-
"excerpt": "In the ever-evolving landscape of BitTorrent technology, performance and scalability are paramount. Torrust stands at the forefront, offering a suite of open-source software products designed to enhance peer-to-peer file sharing. At the heart of this suite is the Torrust BitTorrent Tracker, a Rust-based engine crafted for efficiency and speed. This post will introduce you to the benchmarking tools we are using at the moment for the tracker.",
92+
"date": "2023-12-20T00:00:00.000Z",
93+
"coverImage": "/images/posts/deploying-torrust-to-production/deploy-torrust-to-a-digital-ocean-droplet.png",
94+
"excerpt": "Dive into our step-by-step tutorial on deploying a BitTorrent Index and Tracker, written in Rust, on a Digital Ocean droplet. From initial server setup to advanced configurations, this guide is designed for both non-developers and tech-savvy users, ensuring a seamless, production-ready deployment.",
9695
"tags": [
97-
"Performance",
98-
"Benchmarking"
96+
"Tutorial",
97+
"Deployment",
98+
"Production"
9999
]
100100
},
101101
{

0 commit comments

Comments
 (0)