add search

This commit is contained in:
2024-12-02 10:45:22 +01:00
parent f1449a157c
commit 940cd5cea9
8 changed files with 128 additions and 7 deletions

View File

@@ -45,5 +45,9 @@ const description = 'Welcome to my website!'
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<script async defer src="https://spectare.nicco.io/unicorn.js" data-website-id="bc7525c5-6928-49e1-9255-aca296947def"
></script>
<script
is:inline
async
defer
src="https://spectare.nicco.io/unicorn.js"
data-website-id="bc7525c5-6928-49e1-9255-aca296947def"></script>

View File

@@ -1,4 +1,5 @@
---
import SearchIcon from '~icons/ion/search-outline'
const { pathname } = Astro.url
const routes = [
@@ -14,11 +15,11 @@ const routes = [
<h1 class:list={{ active: pathname === '/' }}>NB</h1>
</a>
<ul>
<!-- <li>
<li>
<a href="/search">
<Icon icon="search-outline" />
<SearchIcon />
</a>
</li> -->
</li>
{
routes.map(({ href, name }) => (
<li>

View File

@@ -0,0 +1,66 @@
<script lang="ts">
import Fuse from 'fuse.js'
const { entries } = $props()
const fuse = new Fuse(entries, {
keys: ['text', 'url', 'extra'],
includeScore: true,
includeMatches: false,
minMatchCharLength: 2,
threshold: 0.5,
})
let needle = $state('')
const results = $derived(fuse.search(needle))
</script>
<input bind:value={needle} />
<ol>
{#each results as result}
<li>
<a href={result.item.url}>
<span class="meta">
{result.item.type}
</span>
<span class="meta">
{(1 - result.score).toFixed(2)}
</span>
{result.item.title}
</a>
</li>
{/each}
</ol>
<style lang="scss">
input {
background: white;
border: 2px solid var(--clr-primary);
border-bottom-width: 4px;
padding: 1rem;
&:focus,
&:hover {
outline: none;
border-color: var(--clr-secondary);
}
}
a {
display: flex;
flex-direction: row;
align-items: start;
gap: 0.5rem;
}
li {
margin-bottom: 1rem;
}
.meta {
background: var(--clr-secondary);
width: fit-content;
padding: 0 0.25rem;
}
</style>

39
src/pages/search.astro Normal file
View File

@@ -0,0 +1,39 @@
---
import { getCollection } from 'astro:content'
import PageSearch from '../components/PageSearch.svelte'
import PageWithTitle from '../layouts/PageWithTitle.astro'
type Entry = { url: string; type: 'post' | 'page'; title: string; text: string; extra?: any }
const entries: Entry[] = []
const posts = await getCollection('blog')
for (const post of posts) {
const rendered = await post.render()
const text = rendered.remarkPluginFrontmatter.text
entries.push({
url: `/blog/${post.slug}`,
type: 'post',
title: post.data.title,
text,
extra: post.data,
})
}
const pages = await getCollection('page')
for (const page of pages) {
const rendered = await page.render()
const text = rendered.remarkPluginFrontmatter.text
entries.push({
url: `/${page.slug}`,
type: 'page',
title: page.data.title,
text,
extra: page.data,
})
}
---
<PageWithTitle title="Search">
<PageSearch entries={entries} client:only="svelte" />
</PageWithTitle>