website: fix astro not compiling because it can't detect server-side component

This commit is contained in:
Kingkor Roy Tirtho 2025-08-15 19:21:40 +06:00
parent a2894db652
commit dbba55606b
6 changed files with 110 additions and 104 deletions

View File

@ -0,0 +1,43 @@
---
import { LuMenu } from "react-icons/lu";
---
<button
id="button-toggle"
class="btn btn-icon"
class:list={[Astro.props.class]}
>
{(<LuMenu />)}
</button>
<div
id="drawer"
class="fixed bg-white dark:bg-surface-800 shadow-lg transition-all duration-300 left-0 top-0 h-screen w-64 -translate-x-[100vw] z-[100]"
>
<button
id="button-close"
class="absolute top-2 right-2 text-gray-500 hover:text-gray-700"
aria-label="Close"
>
&times;
</button>
<div class="p-4">
<slot />
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const buttonToggle = document.getElementById("button-toggle");
const drawer = document.getElementById("drawer");
const buttonClose = document.getElementById("button-close");
buttonToggle?.addEventListener("click", () => {
drawer?.classList.toggle("-translate-x-[100vw]");
});
buttonClose?.addEventListener("click", () => {
drawer?.classList.add("-translate-x-[100vw]");
});
});
</script>

View File

@ -1,45 +0,0 @@
import React, { useState } from "react";
import { LuMenu } from "react-icons/lu";
interface DrawerProps {
buttonLabel?: React.ReactNode;
children: React.ReactNode;
className?: string;
}
export const Drawer: React.FC<DrawerProps> = ({
buttonLabel = <LuMenu />,
children,
className = "",
}) => {
const [open, setOpen] = useState(false);
return (
<>
<button className={`btn btn-icon ${className}`} onClick={() => setOpen(true)}>
{buttonLabel}
</button>
{/* Drawer */}
<div
className={`
fixed bg-white dark:bg-surface-800 shadow-lg transition-all duration-300 left-0 top-0 h-screen w-64
${open ? "-translate-x-5" : "-translate-x-[100vw]"}
`}
>
<button
className="absolute top-2 right-2 text-gray-500 hover:text-gray-700"
onClick={() => setOpen(false)}
aria-label="Close"
>
&times;
</button>
<div className="p-4">{children}</div>
</div>
</>
);
};

View File

@ -1,63 +1,13 @@
---
import type { HTMLAttributes } from "astro/types";
import type { CollectionEntry } from "astro:content";
import { getCollection } from "astro:content";
interface NavigationItem extends HTMLAttributes<"a"> {
title: string;
tag?: string;
}
interface NavigationGroup {
title: string;
items: NavigationItem[];
}
import { getNavigationCollection } from "~/utils/get-collection";
interface Props {
topGroups?: NavigationGroup[];
classList?: string;
bottomGroups?: NavigationGroup[];
classList?: string[];
}
const { classList } = Astro.props;
const sortByOrder = (a: CollectionEntry<"docs">, b: CollectionEntry<"docs">) =>
a.data.order - b.data.order;
async function queryCollection(startsWith: string) {
return (
await getCollection("docs", (entry) => {
if (!entry.id.startsWith(startsWith)) return false;
if (entry.id.split("/").length > 2) return false;
if (entry.id.endsWith("meta")) return false;
return true;
})
).toSorted(sortByOrder);
}
const toNavItems = (entries: CollectionEntry<"docs">[]) =>
entries.map((page) => ({
title: page.data.title,
href: `/docs/${page.id}`,
}));
// Define navigation sections
const sections: [
string,
string,
(prefix: string) => Promise<CollectionEntry<"docs">[]>,
][] = [
["Get Started", "get-started/", queryCollection],
["Developing Plugins", "developing-plugins/", queryCollection],
["Plugin APIs", "plugin-apis/", queryCollection],
["Reference", "reference/", queryCollection],
];
// Build navigation dynamically
const navigation: NavigationGroup[] = await Promise.all(
sections.map(async ([title, prefix, queryFn]) => ({
title,
items: toNavItems(await queryFn(prefix)),
}))
);
const navigation = await getNavigationCollection();
const pathname = Astro.url.pathname.endsWith("/")
? Astro.url.pathname.slice(0, -1)

View File

@ -3,8 +3,6 @@ import { routes } from "~/collections/app";
import { FaGithub } from "react-icons/fa6";
import SidebarButton from "./sidebar-button";
import Search from "astro-pagefind/components/Search";
import { Drawer } from "../drawer/drawer";
import DocSideBar from "./DocSideBar.astro";
const pathname = Astro.url.pathname;
---
@ -16,9 +14,7 @@ const pathname = Astro.url.pathname;
<div class="flex items-center gap-2">
{
pathname.startsWith("/docs") ? (
<Drawer client:only className="md:hidden">
<DocSideBar />
</Drawer>
<div class="h-10 w-10" />
) : (
<SidebarButton client:only />
)

View File

@ -3,6 +3,8 @@ import RootLayout from "layouts/RootLayout.astro";
import type { GetStaticPaths } from "astro";
import { render } from "astro:content";
import { getCollection, getEntry } from "astro:content";
import DocSideBar from "~/components/navigation/DocSideBar.astro";
import Drawer from "~/components/drawer/Drawer.astro";
export const getStaticPaths = (async () => {
const pages = await getCollection("docs");
@ -29,5 +31,8 @@ if (page.id.startsWith("components/") || page.id.startsWith("integrations/")) {
---
<RootLayout>
<Drawer class="fixed top-3 left-2 z-50 md:hidden">
<DocSideBar />
</Drawer>
<Content />
</RootLayout>

View File

@ -0,0 +1,57 @@
import type { HTMLAttributes } from "astro/types";
import { getCollection, type CollectionEntry } from "astro:content";
interface NavigationItem extends HTMLAttributes<"a"> {
title: string;
tag?: string;
}
export interface NavigationGroup {
title: string;
items: NavigationItem[];
}
function sortByOrder(a: CollectionEntry<"docs">, b: CollectionEntry<"docs">) {
return a.data.order - b.data.order;
}
async function queryCollection(startsWith: string) {
return (
await getCollection("docs", (entry) => {
if (!entry.id.startsWith(startsWith)) return false;
if (entry.id.split("/").length > 2) return false;
if (entry.id.endsWith("meta")) return false;
return true;
})
).toSorted(sortByOrder);
}
function toNavItems(entries: CollectionEntry<"docs">[]) {
return entries.map((page) => ({
title: page.data.title,
href: `/docs/${page.id}`,
}));
}
export async function getNavigationCollection() {
// Define navigation sections
const sections: [
string,
string,
(prefix: string) => Promise<CollectionEntry<"docs">[]>
][] = [
["Get Started", "get-started/", queryCollection],
["Developing Plugins", "developing-plugins/", queryCollection],
["Plugin APIs", "plugin-apis/", queryCollection],
["Reference", "reference/", queryCollection],
];
// Build navigation dynamically
const navigation: NavigationGroup[] = await Promise.all(
sections.map(async ([title, prefix, queryFn]) => ({
title,
items: toNavItems(await queryFn(prefix)),
}))
);
return navigation;
}