Files
blog/src/components/NoteNavSidebar.astro
T
Hadi 1025d5bfa1 Init svelte components
Signed-off-by: Hadi <hadi@example.com>
2026-04-28 16:57:15 +02:00

116 lines
3.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
import { getCategory, extractInlineHashtags } from "../utils/notes";
import type { CollectionEntry } from "astro:content";
interface Props {
notes: CollectionEntry<"notes">[];
currentEntry: CollectionEntry<"notes">;
categories: string[];
}
const { notes, currentEntry, categories } = Astro.props;
---
<style>
/*
* DaisyUI's menu items use display:grid with grid-auto-columns:minmax(auto,max-content)
* which expands to fit content. Override to block so text-overflow:ellipsis works directly.
* Inner <ul> has no w-full so DaisyUI's margin-inline-start/padding-inline-start don't overflow.
*/
.nav-item {
display: block !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
white-space: nowrap !important;
}
</style>
<aside
class="w-56 flex flex-col border-r border-base-300/60 h-[calc(100vh-3rem)]"
style="background: oklch(4% 0 0);"
>
<div class="px-3 py-3 border-b border-base-300/40">
<label
class="input input-sm w-full font-mono text-xs border-base-300/40 bg-base-200/50"
>
<span class="text-base-content/30"></span>
<input
data-search
type="text"
placeholder="search..."
class="text-base-content/70 placeholder:text-base-content/25"
/>
</label>
</div>
<ul
class="nav-sidebar menu menu-xs flex-1 min-h-0 overflow-y-auto overflow-x-hidden px-2 py-2 bg-transparent"
>
{
categories.map((cat) => (
<li class="w-full">
<details open={cat === getCategory(currentEntry)}>
<summary class="font-bold tracking-tight text-sm">
<span class="text-primary/50 font-mono">/</span>
{cat}
</summary>
<ul>
{notes
.filter((n) => getCategory(n) === cat)
.map((n) => (
<li>
<a
href={`/notes/${n.id}`}
class:list={[
"nav-item font-mono text-xs tooltip tooltip-right",
n.id === currentEntry.id ? "active" : "",
]}
data-tip={n.data.title}
data-title={n.data.title.toLowerCase()}
data-tags={[
...n.data.tags,
...extractInlineHashtags(n.body ?? ""),
].join(",")}
>
{n.data.title}
</a>
</li>
))}
</ul>
</details>
</li>
))
}
</ul>
</aside>
<script>
document.addEventListener("astro:page-load", () => {
const navItems = document.querySelectorAll<HTMLElement>(".nav-item");
document
.querySelectorAll<HTMLInputElement>("[data-search]")
.forEach((input) => {
input.addEventListener("input", (e) => {
const target = e.target as HTMLInputElement;
const raw = target.value.toLowerCase().trim();
document
.querySelectorAll<HTMLInputElement>("[data-search]")
.forEach((o) => {
if (o !== target) o.value = target.value;
});
const isTag = raw.startsWith("#");
const search = isTag ? raw.slice(1) : raw;
navItems.forEach((item) => {
const title = item.dataset.title ?? "";
const tags = item.dataset.tags ? item.dataset.tags.split(",") : [];
const match =
!search ||
(isTag
? tags.some((t) => t.includes(search))
: title.includes(search) || tags.join(",").includes(search));
item.style.display = match ? "" : "none";
});
});
});
});
</script>