Add Search component
This commit is contained in:
parent
b9ffff1791
commit
b3ab1c438e
2 changed files with 85 additions and 2 deletions
81
src/components/Search.astro
Normal file
81
src/components/Search.astro
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
---
|
||||||
|
import '@styles/search.scss'
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
readonly id?: string;
|
||||||
|
readonly className?: string;
|
||||||
|
readonly query?: string;
|
||||||
|
readonly uiOptions?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id, className, query, uiOptions = {} } = Astro.props;
|
||||||
|
const bundlePath = `${import.meta.env.BASE_URL}pagefind/`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
id={id}
|
||||||
|
class:list={[className, "pagefind-init"]}
|
||||||
|
data-pagefind-ui
|
||||||
|
data-bundle-path={bundlePath}
|
||||||
|
data-query={query}
|
||||||
|
data-ui-options={JSON.stringify(uiOptions)}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// @ts-ignore
|
||||||
|
import { PagefindUI } from "@pagefind/default-ui";
|
||||||
|
|
||||||
|
function initPageFind() {
|
||||||
|
const allSelector = "[data-pagefind-ui]";
|
||||||
|
for (const el of document.querySelectorAll(
|
||||||
|
`${allSelector}.pagefind-init`
|
||||||
|
)) {
|
||||||
|
const elSelector = [
|
||||||
|
...(el.id ? [`#${el.id}`] : []),
|
||||||
|
...[...el.classList.values()].map((c) => `.${c}`),
|
||||||
|
allSelector,
|
||||||
|
].join("");
|
||||||
|
const bundlePath = el.getAttribute("data-bundle-path");
|
||||||
|
const opts = JSON.parse(el.getAttribute("data-ui-options") ?? "{}");
|
||||||
|
new PagefindUI({
|
||||||
|
...opts,
|
||||||
|
element: elSelector,
|
||||||
|
bundlePath,
|
||||||
|
});
|
||||||
|
el.classList.remove("pagefind-init");
|
||||||
|
var query = el.getAttribute("data-query");
|
||||||
|
|
||||||
|
// Check if the current URL has any query params
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const params = new URLSearchParams(url.search);
|
||||||
|
if (params.has("q")) {
|
||||||
|
query = params.get("q");
|
||||||
|
}
|
||||||
|
|
||||||
|
const input = el.querySelector<HTMLInputElement>(`input[type="text"]`);
|
||||||
|
|
||||||
|
input?.focus();
|
||||||
|
|
||||||
|
if (input) {
|
||||||
|
input.value = query;
|
||||||
|
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||||
|
|
||||||
|
// Add Listener to update the URL when the input changes
|
||||||
|
input.addEventListener("input", (e) => {
|
||||||
|
const input = e.target as HTMLInputElement;
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const params = new URLSearchParams(url.search);
|
||||||
|
params.set("q", input.value);
|
||||||
|
window.history.replaceState({}, "", `${url.pathname}?${params}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("astro:page-load", initPageFind);
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", initPageFind);
|
||||||
|
} else {
|
||||||
|
initPageFind();
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,14 +1,16 @@
|
||||||
---
|
---
|
||||||
// Settings
|
// Settings
|
||||||
import { SiteSettings, HeaderItems } from '@config'
|
import { SiteSettings, HeaderItems } from '@config'
|
||||||
|
import Search from '@components/Search.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<div class="start">
|
<div class="header-start">
|
||||||
<h2><a style="text-decoration: none;" href="/">{SiteSettings.SiteName}</a></h2>
|
<h2><a style="text-decoration: none;" href="/">{SiteSettings.SiteName}</a></h2>
|
||||||
|
<Search/>
|
||||||
</div>
|
</div>
|
||||||
<div class="end">
|
<div class="header-end">
|
||||||
{HeaderItems.map((item) => (
|
{HeaderItems.map((item) => (
|
||||||
<a href={item.link}>{item.text}</a>
|
<a href={item.link}>{item.text}</a>
|
||||||
))}
|
))}
|
||||||
|
|
Loading…
Reference in a new issue