docs: add search bar and libraries page

This commit is contained in:
Kingkor Roy Tirtho 2025-08-14 22:20:09 +06:00
parent 30fd4acf37
commit 3f18f35c0b
7 changed files with 198 additions and 25 deletions

View File

@ -5,6 +5,7 @@ import react from "@astrojs/react";
import mdx from "@astrojs/mdx"; import mdx from "@astrojs/mdx";
import rehypeSlug from "rehype-slug"; import rehypeSlug from "rehype-slug";
import rehypeAutolinkHeadings from "rehype-autolink-headings"; import rehypeAutolinkHeadings from "rehype-autolink-headings";
import pagefind from "astro-pagefind";
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
@ -40,7 +41,7 @@ export default defineConfig({
], ],
], ],
}, },
integrations: [react(), mdx()], integrations: [react(), mdx(), pagefind()],
redirects: { redirects: {
"/docs": "/docs/get-started/introduction", "/docs": "/docs/get-started/introduction",
"/docs/get-started": "/docs/get-started/introduction", "/docs/get-started": "/docs/get-started/introduction",

View File

@ -17,6 +17,7 @@
"@types/react": "^19.1.9", "@types/react": "^19.1.9",
"@types/react-dom": "^19.1.7", "@types/react-dom": "^19.1.7",
"astro": "^5.12.8", "astro": "^5.12.8",
"astro-pagefind": "^1.8.3",
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"react": "^19.1.1", "react": "^19.1.1",

View File

@ -32,6 +32,9 @@ importers:
astro: astro:
specifier: ^5.12.8 specifier: ^5.12.8
version: 5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2) version: 5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2)
astro-pagefind:
specifier: ^1.8.3
version: 1.8.3(astro@5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2))
date-fns: date-fns:
specifier: ^4.1.0 specifier: ^4.1.0
version: 4.1.0 version: 4.1.0
@ -542,6 +545,37 @@ packages:
'@oslojs/encoding@1.1.0': '@oslojs/encoding@1.1.0':
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
'@pagefind/darwin-arm64@1.3.0':
resolution: {integrity: sha512-365BEGl6ChOsauRjyVpBjXybflXAOvoMROw3TucAROHIcdBvXk9/2AmEvGFU0r75+vdQI4LJdJdpH4Y6Yqaj4A==}
cpu: [arm64]
os: [darwin]
'@pagefind/darwin-x64@1.3.0':
resolution: {integrity: sha512-zlGHA23uuXmS8z3XxEGmbHpWDxXfPZ47QS06tGUq0HDcZjXjXHeLG+cboOy828QIV5FXsm9MjfkP5e4ZNbOkow==}
cpu: [x64]
os: [darwin]
'@pagefind/default-ui@1.3.0':
resolution: {integrity: sha512-CGKT9ccd3+oRK6STXGgfH+m0DbOKayX6QGlq38TfE1ZfUcPc5+ulTuzDbZUnMo+bubsEOIypm4Pl2iEyzZ1cNg==}
'@pagefind/linux-arm64@1.3.0':
resolution: {integrity: sha512-8lsxNAiBRUk72JvetSBXs4WRpYrQrVJXjlRRnOL6UCdBN9Nlsz0t7hWstRk36+JqHpGWOKYiuHLzGYqYAqoOnQ==}
cpu: [arm64]
os: [linux]
'@pagefind/linux-x64@1.3.0':
resolution: {integrity: sha512-hAvqdPJv7A20Ucb6FQGE6jhjqy+vZ6pf+s2tFMNtMBG+fzcdc91uTw7aP/1Vo5plD0dAOHwdxfkyw0ugal4kcQ==}
cpu: [x64]
os: [linux]
'@pagefind/windows-x64@1.3.0':
resolution: {integrity: sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ==}
cpu: [x64]
os: [win32]
'@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
'@rolldown/pluginutils@1.0.0-beta.27': '@rolldown/pluginutils@1.0.0-beta.27':
resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==}
@ -985,6 +1019,11 @@ packages:
resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
hasBin: true hasBin: true
astro-pagefind@1.8.3:
resolution: {integrity: sha512-Nfo1TdlEHdkXTiI0KpimLqX6awK3qWTil7IOJvk5Q8x+0VBTpIEp9QvGgoAxXDe3upAHLVsg4y7U1uUPm7GC9w==}
peerDependencies:
astro: ^2.0.4 || ^3 || ^4 || ^5
astro@5.12.8: astro@5.12.8:
resolution: {integrity: sha512-KkJ7FR+c2SyZYlpakm48XBiuQcRsrVtdjG5LN5an0givI/tLik+ePJ4/g3qrAVhYMjJOxBA2YgFQxANPiWB+Mw==} resolution: {integrity: sha512-KkJ7FR+c2SyZYlpakm48XBiuQcRsrVtdjG5LN5an0givI/tLik+ePJ4/g3qrAVhYMjJOxBA2YgFQxANPiWB+Mw==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
@ -1796,6 +1835,10 @@ packages:
package-manager-detector@1.3.0: package-manager-detector@1.3.0:
resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
pagefind@1.3.0:
resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==}
hasBin: true
pako@0.2.9: pako@0.2.9:
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
@ -1984,6 +2027,10 @@ packages:
simple-swizzle@0.2.2: simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
sirv@3.0.1:
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
engines: {node: '>=18'}
sisteransi@1.0.5: sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@ -2048,6 +2095,10 @@ packages:
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
tr46@0.0.3: tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
@ -2819,6 +2870,25 @@ snapshots:
'@oslojs/encoding@1.1.0': {} '@oslojs/encoding@1.1.0': {}
'@pagefind/darwin-arm64@1.3.0':
optional: true
'@pagefind/darwin-x64@1.3.0':
optional: true
'@pagefind/default-ui@1.3.0': {}
'@pagefind/linux-arm64@1.3.0':
optional: true
'@pagefind/linux-x64@1.3.0':
optional: true
'@pagefind/windows-x64@1.3.0':
optional: true
'@polka/url@1.0.0-next.29': {}
'@rolldown/pluginutils@1.0.0-beta.27': {} '@rolldown/pluginutils@1.0.0-beta.27': {}
'@rollup/pluginutils@5.2.0(rollup@4.46.2)': '@rollup/pluginutils@5.2.0(rollup@4.46.2)':
@ -3313,6 +3383,13 @@ snapshots:
astring@1.9.0: {} astring@1.9.0: {}
astro-pagefind@1.8.3(astro@5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2)):
dependencies:
'@pagefind/default-ui': 1.3.0
astro: 5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2)
pagefind: 1.3.0
sirv: 3.0.1
astro@5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2): astro@5.12.8(@types/node@24.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2):
dependencies: dependencies:
'@astrojs/compiler': 2.12.2 '@astrojs/compiler': 2.12.2
@ -4527,6 +4604,14 @@ snapshots:
package-manager-detector@1.3.0: {} package-manager-detector@1.3.0: {}
pagefind@1.3.0:
optionalDependencies:
'@pagefind/darwin-arm64': 1.3.0
'@pagefind/darwin-x64': 1.3.0
'@pagefind/linux-arm64': 1.3.0
'@pagefind/linux-x64': 1.3.0
'@pagefind/windows-x64': 1.3.0
pako@0.2.9: {} pako@0.2.9: {}
parse-entities@4.0.2: parse-entities@4.0.2:
@ -4851,6 +4936,12 @@ snapshots:
is-arrayish: 0.3.2 is-arrayish: 0.3.2
optional: true optional: true
sirv@3.0.1:
dependencies:
'@polka/url': 1.0.0-next.29
mrmime: 2.0.1
totalist: 3.0.1
sisteransi@1.0.5: {} sisteransi@1.0.5: {}
smol-toml@1.4.1: {} smol-toml@1.4.1: {}
@ -4916,6 +5007,8 @@ snapshots:
fdir: 6.4.6(picomatch@4.0.3) fdir: 6.4.6(picomatch@4.0.3)
picomatch: 4.0.3 picomatch: 4.0.3
totalist@3.0.1: {}
tr46@0.0.3: {} tr46@0.0.3: {}
trim-lines@3.0.1: {} trim-lines@3.0.1: {}

View File

@ -18,7 +18,7 @@ interface Props {
classList?: string; classList?: string;
bottomGroups?: NavigationGroup[]; bottomGroups?: NavigationGroup[];
} }
const { topGroups, bottomGroups, classList } = Astro.props; const { classList } = Astro.props;
const sortByOrder = (a: CollectionEntry<"docs">, b: CollectionEntry<"docs">) => const sortByOrder = (a: CollectionEntry<"docs">, b: CollectionEntry<"docs">) =>
a.data.order - b.data.order; a.data.order - b.data.order;
@ -33,17 +33,6 @@ async function queryCollection(startsWith: string) {
}) })
).toSorted(sortByOrder); ).toSorted(sortByOrder);
} }
async function queryMetaCollection(startsWith: string) {
return (
await getCollection("docs", (entry) => {
if (!entry.id.startsWith(startsWith)) return false;
if (!entry.id.endsWith("meta")) return false;
return true;
})
).toSorted(sortByOrder);
}
const toNavItems = (entries: CollectionEntry<"docs">[]) => const toNavItems = (entries: CollectionEntry<"docs">[]) =>
entries.map((page) => ({ entries.map((page) => ({
title: page.data.title, title: page.data.title,
@ -63,16 +52,16 @@ const sections: [
]; ];
// Build navigation dynamically // Build navigation dynamically
const navigation: NavigationGroup[] = [ const navigation: NavigationGroup[] = await Promise.all(
...(topGroups ?? []), sections.map(async ([title, prefix, queryFn]) => ({
...(await Promise.all( title,
sections.map(async ([title, prefix, queryFn]) => ({ items: toNavItems(await queryFn(prefix)),
title, }))
items: toNavItems(await queryFn(prefix)), );
}))
)), const pathname = Astro.url.pathname.endsWith("/")
...(bottomGroups ?? []), ? Astro.url.pathname.slice(0, -1)
]; : Astro.url.pathname;
--- ---
<aside class="text-sm grid gap-10" class:list={[classList]}> <aside class="text-sm grid gap-10" class:list={[classList]}>
@ -92,8 +81,8 @@ const navigation: NavigationGroup[] = [
class="grow px-2 py-1 rounded-base" class="grow px-2 py-1 rounded-base"
class:list={[ class:list={[
{ {
"preset-tonal": Astro.url.pathname === item.href, "preset-tonal": pathname === item.href,
anchor: Astro.url.pathname !== item.href, anchor: pathname !== item.href,
}, },
]} ]}
> >

View File

@ -2,6 +2,7 @@
import { routes } from "~/collections/app"; import { routes } from "~/collections/app";
import { FaGithub } from "react-icons/fa6"; import { FaGithub } from "react-icons/fa6";
import SidebarButton from "./sidebar-button"; import SidebarButton from "./sidebar-button";
import Search from "astro-pagefind/components/Search";
const pathname = Astro.url.pathname; const pathname = Astro.url.pathname;
--- ---
@ -19,6 +20,16 @@ const pathname = Astro.url.pathname;
</a> </a>
</h2> </h2>
</div> </div>
<Search
id="search"
className="pagefind-ui"
uiOptions={{
showImages: false,
showSubResults: true,
}}
/>
<a <a
class="mw-2 md:me-4" class="mw-2 md:me-4"
href="https://github.com/KRTirtho/spotube?referrer=spotube.krtirtho.dev" href="https://github.com/KRTirtho/spotube?referrer=spotube.krtirtho.dev"

View File

@ -0,0 +1,15 @@
---
layout: "layouts/DocLayout.astro"
title: Libraries
description: List of libraries for Spotube Plugins.
order: 0
---
- [`hetu_std`][hetu_std] (built-in) - A standard library for hetu_script that provides standard set of functions and utilities.
- [`hetu_spotube_plugin`][hetu_spotube_plugin] (built-in) - Access to Spotube Plugin API, which provides functions to interact with Spotube.
- [`hetu_otp_util`][hetu_otp_util] - A pure hetu_script library for OTP utilities, such as generating and verifying OTPs.
{/* Links */}
[hetu_std]: https://github.com/hetu-community/hetu_std
[hetu_spotube_plugin]: https://github.com/KRTirtho/hetu_spotube_plugin
[hetu_otp_util]: https://github.com/hetu-community/hetu_otp_util

View File

@ -7,6 +7,15 @@
@import "@skeletonlabs/skeleton/optional/presets"; @import "@skeletonlabs/skeleton/optional/presets";
@import "@skeletonlabs/skeleton/themes/wintry"; @import "@skeletonlabs/skeleton/themes/wintry";
h1,
h2,
h3,
h4,
h5,
h6 {
scroll-margin-top: 80px;
}
.prose code::before, .prose code::before,
.prose code::after { .prose code::after {
content: none !important; content: none !important;
@ -19,3 +28,57 @@
.prose a code { .prose a code {
@apply text-primary-500 underline decoration-primary-500; @apply text-primary-500 underline decoration-primary-500;
} }
/* Astro PageFind */
.pagefind-ui {
--pagefind-ui-scale: 0.75;
--pagefind-ui-primary: var(--color-primary-500);
--pagefind-ui-text: var(--color-surface-900-100);
--pagefind-ui-border: var(--color-surface-300-700);
--pagefind-ui-border-width: 1px;
--pagefind-ui-border-radius: 0.5rem;
width: 50%;
}
.pagefind-ui .pagefind-ui__drawer:not(.pagefind-ui__hidden) {
position: absolute;
left: 0;
right: 0;
margin-top: 0px;
z-index: 9999;
padding: 0 2em 1em;
overflow-y: auto;
box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.2),
0 2px 2px 0 rgba(0, 0, 0, 0.1);
border-bottom-right-radius: var(--pagefind-ui-border-radius);
border-bottom-left-radius: var(--pagefind-ui-border-radius);
@apply bg-gray-50 dark:bg-surface-900;
}
.pagefind-ui .pagefind-ui__result-link {
color: var(--pagefind-ui-primary);
}
.pagefind-ui .pagefind-ui__result-excerpt {
@apply font-normal text-surface-900-100;
}
.pagefind-ui .pagefind-ui__search-input {
background-color: var(--color-white) !important;
}
.pagefind-ui .pagefind-ui__search-clear {
background: var(--color-white) !important;
}
@media (prefers-color-scheme: dark) {
.pagefind-ui .pagefind-ui__search-input {
background-color: var(--color-surface-900) !important;
}
.pagefind-ui .pagefind-ui__search-clear {
background: var(--color-surface-900) !important;
}
}