add fuse
This commit is contained in:
10
superpage/src/pages/_components/Search.astro
Normal file
10
superpage/src/pages/_components/Search.astro
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
import Search from "./Search";
|
||||
import { getCollection, render } from "astro:content";
|
||||
const courses = await getCollection(
|
||||
"courses",
|
||||
({ data }) => data.draft != true,
|
||||
);
|
||||
---
|
||||
|
||||
<Search client:load searchlist={courses} />
|
||||
60
superpage/src/pages/_components/Search.jsx
Normal file
60
superpage/src/pages/_components/Search.jsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import { useState } from "react";
|
||||
import Fuse from "fuse.js";
|
||||
|
||||
// https://fusejs.io/api/options.html
|
||||
const options = {
|
||||
keys: ["data.title", "data.excerpt", "data.slug"],
|
||||
includeMatches: true,
|
||||
minMatchCharLength: 2,
|
||||
threshold: 0.5,
|
||||
};
|
||||
|
||||
export default function Search({ searchlist }) {
|
||||
const [query, setQuery] = useState("");
|
||||
|
||||
const fuse = new Fuse(searchlist, options);
|
||||
// Set a limit to the items: 5
|
||||
const items = fuse
|
||||
.search(query)
|
||||
.map((result) => result.item)
|
||||
.slice(0, 5);
|
||||
|
||||
const onChange = (e) => {
|
||||
setQuery(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<input
|
||||
id="search"
|
||||
type="text"
|
||||
className="focus:outline-none w-full pr-5 py-3.5"
|
||||
value={query}
|
||||
onChange={onChange}
|
||||
/>
|
||||
{query.length > 1 && (
|
||||
<div className="absolute w-full top-full bg-white mt-2.5 p-5 rounded-xl drop-shadow space-y-2.5">
|
||||
<p>
|
||||
Encontrado {items.length} resultado(s) para '
|
||||
<strong>{query}</strong>'
|
||||
</p>
|
||||
|
||||
{items.length > 1 && (
|
||||
<ul className="list-disc list-inside">
|
||||
{items.map(({ data }, idx) => (
|
||||
<li key={idx}>
|
||||
<a
|
||||
href={`/${data.slug}`}
|
||||
className="font-medium hover:underline"
|
||||
>
|
||||
{data.title}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { Icon } from "astro-icon/components";
|
||||
import Layout from "~/layouts/Layout.astro";
|
||||
import Container from "~/components/Container.astro";
|
||||
import { Clients } from "~/components/Course";
|
||||
import Search from "./_components/Search.astro";
|
||||
|
||||
import mulhercomepi from "~/assets/mulher-com-epi.png";
|
||||
|
||||
@@ -19,7 +20,7 @@ let posts = await res.json();
|
||||
>
|
||||
<div class="col-span-4 flex items-center justify-center">
|
||||
<div class="lg:w-4/6 max-lg:p-5 space-y-6 lg:space-y-12">
|
||||
<form class="space-y-1.5">
|
||||
<div class="space-y-1.5">
|
||||
<label for="search" class="block">
|
||||
<h1
|
||||
class="text-pretty font-semibold text-3xl lg:text-4xl"
|
||||
@@ -29,7 +30,7 @@ let posts = await res.json();
|
||||
</label>
|
||||
|
||||
<div
|
||||
class="flex gap-2.5 border border-black bg-white w-full rounded-lg"
|
||||
class="flex gap-2.5 border border-black bg-white w-full rounded-lg relative"
|
||||
>
|
||||
<label for="search" class="py-3.5 pl-3">
|
||||
<Icon
|
||||
@@ -37,12 +38,9 @@ let posts = await res.json();
|
||||
class="size-6"
|
||||
/>
|
||||
</label>
|
||||
<input
|
||||
id="search"
|
||||
class="focus:outline-none w-full pr-5 py-3.5"
|
||||
/>
|
||||
<Search />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 class="font-bold text-xl flex gap-1">
|
||||
|
||||
Reference in New Issue
Block a user