mirror of
https://github.com/cupcakearmy/nicco.io.git
synced 2025-12-07 22:45:00 +00:00
add search
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
66
src/components/PageSearch.svelte
Normal file
66
src/components/PageSearch.svelte
Normal 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
39
src/pages/search.astro
Normal 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>
|
||||
Reference in New Issue
Block a user