feat: upgrade fumadocs

This commit is contained in:
ReaJason
2026-08-30 21:19:42 +08:00
parent 6c41f208ba
commit e11eafe78b
11 changed files with 489 additions and 922 deletions
+4 -11
View File
@@ -1,5 +1,5 @@
import { create } from "@orama/orama";
import { useDocsSearch } from "fumadocs-core/search/client";
import { staticClient } from "fumadocs-core/search/client/orama-static";
import {
SearchDialog,
SearchDialogClose,
@@ -13,19 +13,12 @@ import {
} from "fumadocs-ui/components/dialog/search";
import { useI18n } from "fumadocs-ui/contexts/i18n";
function initOrama() {
return create({
schema: { _: "string" },
language: "english",
});
}
export default function DefaultSearchDialog(props: SharedProps) {
const { locale } = useI18n();
const { search, setSearch, query } = useDocsSearch({
type: "static",
initOrama,
locale,
client: staticClient({
locale,
}),
});
return (
+1 -1
View File
@@ -7,7 +7,7 @@ const EnvSchema = yup.object({
});
type EnvSchema = yup.InferType<typeof EnvSchema>;
function safeParseYup<T>(schema: yup.ObjectSchema<any>, data: unknown) {
function safeParseYup<T>(schema: yup.AnySchema, data: unknown) {
try {
const validatedData = schema.validateSync(data, {
abortEarly: false,
+31 -39
View File
@@ -1,6 +1,5 @@
import type { Route } from "./+types/page";
import browserCollections from "collections/browser";
import { useFumadocsLoader } from "fumadocs-core/source/client";
import { DocsLayout } from "fumadocs-ui/layouts/docs";
import {
@@ -11,13 +10,14 @@ import {
MarkdownCopyButton,
ViewOptionsPopover,
} from "fumadocs-ui/layouts/docs/page";
import { use } from "react";
import { useMDXComponents } from "@/components/mdx";
import { baseOptions } from "@/lib/layout.shared";
import { getPageMarkdownUrl, source } from "@/lib/source";
import { docs, getPageMarkdownUrl, source } from "@/lib/source";
export async function loader({ params }: Route.LoaderArgs) {
const slugs = params["*"].split("/").filter((v: string | any[]) => v.length > 0);
const slugs = params["*"].split("/").filter((v) => v.length > 0);
const page = source.getPage(slugs);
if (!page) throw new Response("Not found", { status: 404 });
@@ -28,48 +28,40 @@ export async function loader({ params }: Route.LoaderArgs) {
};
}
const clientLoader = browserCollections.docs.createClientLoader({
component(
{ toc, frontmatter, default: Mdx },
// you can define props for the component
{
markdownUrl,
path,
}: {
markdownUrl: string;
path: string;
},
) {
return (
<DocsPage toc={toc} tableOfContent={{ style: "clerk" }}>
<title>{frontmatter.title}</title>
<meta name="description" content={frontmatter.description} />
<DocsTitle>{frontmatter.title}</DocsTitle>
<DocsDescription>{frontmatter.description}</DocsDescription>
<div className="-mt-4 flex flex-row items-center gap-2 border-b pb-6">
<MarkdownCopyButton markdownUrl={markdownUrl} />
<ViewOptionsPopover
markdownUrl={markdownUrl}
githubUrl={`https://github.com/ReaJason/MemShellParty/blob/master/web/content/docs/${path}`}
/>
</div>
<DocsBody>
<Mdx components={useMDXComponents()} />
</DocsBody>
</DocsPage>
);
},
});
function Content({ path, markdownUrl }: { path: string; markdownUrl: string }) {
const page = docs.getPage(path);
if (!page) throw new Error(`unknown page: ${path}`);
// content is loaded lazily, call `page.preload()` in the loader to avoid suspending
const { toc } = use(page.load());
const Mdx = page.body;
return (
<DocsPage toc={toc} tableOfContent={{ style: "clerk" }}>
<title>{page.title}</title>
<meta name="description" content={page.description} />
<DocsTitle>{page.title}</DocsTitle>
<DocsDescription>{page.description}</DocsDescription>
<div className="-mt-4 flex flex-row items-center gap-2 border-b pb-6">
<MarkdownCopyButton markdownUrl={markdownUrl} />
<ViewOptionsPopover
markdownUrl={markdownUrl}
githubUrl={`https://github.com/ReaJason/MemShellParty/blob/master/web/content/docs/${path}`}
/>
</div>
<DocsBody>
<Mdx components={useMDXComponents()} />
</DocsBody>
</DocsPage>
);
}
export default function Page({ loaderData }: Route.ComponentProps) {
const { pageTree, path, markdownUrl } = useFumadocsLoader(loaderData);
return (
<DocsLayout {...baseOptions()} tree={pageTree}>
{clientLoader.useContent(loaderData.path, {
markdownUrl,
path,
})}
<Content path={path} markdownUrl={markdownUrl} />
</DocsLayout>
);
}
+1 -10
View File
@@ -1,17 +1,8 @@
import { stopwords as mandarinStopwords } from "@orama/stopwords/mandarin";
import { createTokenizer } from "@orama/tokenizers/mandarin";
import { createFromSource } from "fumadocs-core/search/server";
import { source } from "@/lib/source";
const server = createFromSource(source, {
components: {
tokenizer: createTokenizer({
language: "mandarin",
stopWords: mandarinStopwords,
}),
},
});
const server = createFromSource(source);
export async function loader() {
return server.staticGET();
+11 -1
View File
@@ -1,6 +1,16 @@
import { docs } from "collections/server";
import { loader, type InferPageType } from "fumadocs-core/source";
import { lucideIconsPlugin } from "fumadocs-core/source/lucide-icons";
import { defineDocs } from "fumadocs-mdx/macro";
export const docs = defineDocs({
dir: "content/docs",
docs: {
async: true,
postprocess: {
includeProcessedMarkdown: true,
},
},
});
export const source = loader({
source: docs.toFumadocsSource(),
+2 -5
View File
@@ -53,7 +53,7 @@ const urlPatternIsNeeded = (shellType: string) => {
const isInvalidUrl = (urlPattern: string | undefined) =>
urlPattern === "/" || urlPattern === "/*" || !urlPattern?.startsWith("/") || !urlPattern;
export const useYupValidationResolver = (validationSchema: yup.ObjectSchema<any>, t: TFunction) =>
export const useYupValidationResolver = (validationSchema: yup.AnySchema, t: TFunction) =>
useCallback(
async (data: MemShellFormSchema, _context: any): Promise<ValidationResult> => {
try {
@@ -157,10 +157,7 @@ export const probeShellFormSchema = yup.object().shape({
type ProbeValidationResult = ResolverResult<ProbeShellFormSchema>;
export const useYupValidationProbeResolver = (
validationSchema: yup.ObjectSchema<any>,
t: TFunction,
) =>
export const useYupValidationProbeResolver = (validationSchema: yup.AnySchema, t: TFunction) =>
useCallback(
async (data: ProbeShellFormSchema, _context: any): Promise<ProbeValidationResult> => {
try {