fumapress 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,108 @@
1
+ @source inline("@orama/orama");
2
+ @source inline("absolutePath");
3
+ @source inline("adapter");
4
+ @source inline("as");
5
+ @source inline("async");
6
+ @source inline("await");
7
+ @source inline("body");
8
+ @source inline("border-b");
9
+ @source inline("children");
10
+ @source inline("className");
11
+ @source inline("client");
12
+ @source inline("const");
13
+ @source inline("core:docs-layout");
14
+ @source inline("core:home-layout");
15
+ @source inline("core:notebook-layout");
16
+ @source inline("core:provider");
17
+ @source inline("core:render-body");
18
+ @source inline("core:render-toc");
19
+ @source inline("create");
20
+ @source inline("createDocsLayout");
21
+ @source inline("createHomeLayout");
22
+ @source inline("createNotebookLayout");
23
+ @source inline("createRootLayout");
24
+ @source inline("data");
25
+ @source inline("data-version");
26
+ @source inline("date");
27
+ @source inline("default");
28
+ @source inline("else");
29
+ @source inline("empty");
30
+ @source inline("en");
31
+ @source inline("english");
32
+ @source inline("export");
33
+ @source inline("extends");
34
+ @source inline("flex");
35
+ @source inline("flex-col");
36
+ @source inline("flex-row");
37
+ @source inline("flexsearchStaticClient");
38
+ @source inline("for");
39
+ @source inline("from");
40
+ @source inline("fumadocs-core/source");
41
+ @source inline("fumadocs-core/toc");
42
+ @source inline("function");
43
+ @source inline("gap-2");
44
+ @source inline("githubUrl");
45
+ @source inline("hook");
46
+ @source inline("hooks");
47
+ @source inline("i18n");
48
+ @source inline("i18nConfig");
49
+ @source inline("if");
50
+ @source inline("import");
51
+ @source inline("in");
52
+ @source inline("interface");
53
+ @source inline("isLoading");
54
+ @source inline("items");
55
+ @source inline("items-center");
56
+ @source inline("lang");
57
+ @source inline("language");
58
+ @source inline("languages");
59
+ @source inline("lastModified");
60
+ @source inline("layoutData");
61
+ @source inline("layoutProps");
62
+ @source inline("let");
63
+ @source inline("loaderConfig");
64
+ @source inline("locale");
65
+ @source inline("locales");
66
+ @source inline("markdownUrl");
67
+ @source inline("mb-0");
68
+ @source inline("min-h-screen");
69
+ @source inline("name");
70
+ @source inline("new");
71
+ @source inline("of");
72
+ @source inline("onSearchChange");
73
+ @source inline("option");
74
+ @source inline("page");
75
+ @source inline("pageProps");
76
+ @source inline("pb-6");
77
+ @source inline("props");
78
+ @source inline("providerProps");
79
+ @source inline("pt-2");
80
+ @source inline("query");
81
+ @source inline("r");
82
+ @source inline("react");
83
+ @source inline("render");
84
+ @source inline("renderCtx");
85
+ @source inline("renderRootMeta");
86
+ @source inline("result");
87
+ @source inline("return");
88
+ @source inline("root");
89
+ @source inline("satisfies");
90
+ @source inline("schema");
91
+ @source inline("search");
92
+ @source inline("source");
93
+ @source inline("specify");
94
+ @source inline("static");
95
+ @source inline("string");
96
+ @source inline("styles");
97
+ @source inline("the");
98
+ @source inline("this");
99
+ @source inline("throw");
100
+ @source inline("toc");
101
+ @source inline("translations");
102
+ @source inline("tree");
103
+ @source inline("type");
104
+ @source inline("undefined");
105
+ @source inline("unstable_notFound");
106
+ @source inline("use");
107
+ @source inline("useDocsSearch");
108
+ @source inline("useI18n");
@@ -0,0 +1,12 @@
1
+ import { AppContext } from "../lib/shared.js";
2
+ import { ConfigContext } from "../config.js";
3
+ import { Adapter, Awaitable } from "../lib/types.js";
4
+ import { MDXComponents } from "mdx/types";
5
+
6
+ //#region src/adapters/mdx.d.ts
7
+ interface MdxAdapterOptions<C extends ConfigContext = ConfigContext> {
8
+ getMdxComponents?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<MDXComponents>;
9
+ }
10
+ declare function fumadocsMdx<C extends ConfigContext = ConfigContext>(options?: MdxAdapterOptions<C>): Adapter<C>;
11
+ //#endregion
12
+ export { MdxAdapterOptions, fumadocsMdx };
@@ -0,0 +1,37 @@
1
+ import { createElement } from "react";
2
+ import defaultMdxComponents, { createRelativeLink } from "fumadocs-ui/mdx";
3
+ //#region src/adapters/mdx.ts
4
+ function fumadocsMdx(options) {
5
+ const getMdxComponents = options?.getMdxComponents;
6
+ return {
7
+ async "core:get-text"(page) {
8
+ if (isAsyncEntry(page.data) || isSyncEntry(page.data)) return page.data.getText("processed");
9
+ },
10
+ async "core:get-structured-data"(page) {
11
+ if (isSyncEntry(page.data)) return page.data.structuredData;
12
+ if (isAsyncEntry(page.data)) return (await page.data.load()).structuredData;
13
+ },
14
+ async "core:render-body"(page) {
15
+ let body;
16
+ if (isSyncEntry(page.data)) body = page.data.body;
17
+ else if (isAsyncEntry(page.data)) body = (await page.data.load()).body;
18
+ else return;
19
+ return createElement(body, getMdxComponents ? await getMdxComponents.call(this, page) : { components: {
20
+ ...defaultMdxComponents,
21
+ a: createRelativeLink(await this.getLoader(), page)
22
+ } });
23
+ },
24
+ async "core:render-toc"(page) {
25
+ if (isSyncEntry(page.data)) return page.data.toc;
26
+ if (isAsyncEntry(page.data)) return (await page.data.load()).toc;
27
+ }
28
+ };
29
+ }
30
+ function isSyncEntry(v) {
31
+ return "info" in v && typeof v.info === "object" && "_exports" in v && typeof v._exports === "object";
32
+ }
33
+ function isAsyncEntry(v) {
34
+ return "info" in v && typeof v.info === "object" && "load" in v && typeof v.load === "function";
35
+ }
36
+ //#endregion
37
+ export { fumadocsMdx };
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { SearchDialog, SearchDialogClose, SearchDialogContent, SearchDialogHeader, SearchDialogIcon, SearchDialogInput, SearchDialogList, SearchDialogOverlay } from "fumadocs-ui/components/dialog/search";
4
+ import { useDocsSearch } from "fumadocs-core/search/client";
5
+ import { flexsearchStaticClient } from "fumadocs-core/search/client/flexsearch-static";
6
+ import { useI18n } from "fumadocs-ui/contexts/i18n";
7
+ //#region src/components/flexsearch-static.tsx
8
+ function DefaultSearchDialog(props) {
9
+ const { locale } = useI18n();
10
+ const { search, setSearch, query } = useDocsSearch({ client: flexsearchStaticClient({ locale }) });
11
+ return /* @__PURE__ */ jsxs(SearchDialog, {
12
+ search,
13
+ onSearchChange: setSearch,
14
+ isLoading: query.isLoading,
15
+ ...props,
16
+ children: [/* @__PURE__ */ jsx(SearchDialogOverlay, {}), /* @__PURE__ */ jsxs(SearchDialogContent, { children: [/* @__PURE__ */ jsxs(SearchDialogHeader, { children: [
17
+ /* @__PURE__ */ jsx(SearchDialogIcon, {}),
18
+ /* @__PURE__ */ jsx(SearchDialogInput, {}),
19
+ /* @__PURE__ */ jsx(SearchDialogClose, {})
20
+ ] }), /* @__PURE__ */ jsx(SearchDialogList, { items: query.data !== "empty" ? query.data : null })] })]
21
+ });
22
+ }
23
+ //#endregion
24
+ export { DefaultSearchDialog as default };
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { SearchDialog, SearchDialogClose, SearchDialogContent, SearchDialogHeader, SearchDialogIcon, SearchDialogInput, SearchDialogList, SearchDialogOverlay } from "fumadocs-ui/components/dialog/search";
4
+ import { useDocsSearch } from "fumadocs-core/search/client";
5
+ import { useI18n } from "fumadocs-ui/contexts/i18n";
6
+ import { create } from "@orama/orama";
7
+ //#region src/components/orama-search-static.tsx
8
+ function initOrama() {
9
+ return create({
10
+ schema: { _: "string" },
11
+ language: "english"
12
+ });
13
+ }
14
+ function DefaultSearchDialog(props) {
15
+ const { locale } = useI18n();
16
+ const { search, setSearch, query } = useDocsSearch({
17
+ type: "static",
18
+ initOrama,
19
+ locale
20
+ });
21
+ return /* @__PURE__ */ jsxs(SearchDialog, {
22
+ search,
23
+ onSearchChange: setSearch,
24
+ isLoading: query.isLoading,
25
+ ...props,
26
+ children: [/* @__PURE__ */ jsx(SearchDialogOverlay, {}), /* @__PURE__ */ jsxs(SearchDialogContent, { children: [/* @__PURE__ */ jsxs(SearchDialogHeader, { children: [
27
+ /* @__PURE__ */ jsx(SearchDialogIcon, {}),
28
+ /* @__PURE__ */ jsx(SearchDialogInput, {}),
29
+ /* @__PURE__ */ jsx(SearchDialogClose, {})
30
+ ] }), /* @__PURE__ */ jsx(SearchDialogList, { items: query.data !== "empty" ? query.data : null })] })]
31
+ });
32
+ }
33
+ //#endregion
34
+ export { DefaultSearchDialog as default };
@@ -0,0 +1,84 @@
1
+ import { AppContext } from "./lib/shared.js";
2
+ import { Adapter, Awaitable, ServerPlugin } from "./lib/types.js";
3
+ import { ComponentType, ReactNode } from "react";
4
+ import { TranslationsOption } from "fumadocs-ui/contexts/i18n";
5
+ import { LoaderConfig, LoaderOutput } from "fumadocs-core/source";
6
+ import { I18nConfig } from "fumadocs-core/i18n";
7
+
8
+ //#region src/config.d.ts
9
+ interface ConfigContext {
10
+ loaderConfig: LoaderConfig;
11
+ lang: string;
12
+ }
13
+ type BuildMode = "static" | "dynamic" | "default";
14
+ interface Config<C extends ConfigContext = ConfigContext> {
15
+ /**
16
+ * - `static`: always prefer static, including search etc.
17
+ * - `dynamic`: always prefer dynamic.
18
+ * - `default`: only certain parts like search routes are dynamic.
19
+ */
20
+ mode?: BuildMode;
21
+ /** the default content loader */
22
+ loader: LoaderOutput<C["loaderConfig"]> | (() => Awaitable<LoaderOutput<C["loaderConfig"]>>);
23
+ site?: SiteConfig;
24
+ layouts?: Partial<Layouts>;
25
+ plugins?: ServerPlugin[];
26
+ /** adapter for content sources, use `fumadocs-mdx` if not specified */
27
+ adapters?: Adapter[];
28
+ i18n?: I18nConfig$1<C["lang"]>;
29
+ meta?: {
30
+ /** render meta tags for any pages */root?: (this: AppContext<C>) => ReactNode; /** render meta tags for page */
31
+ page?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => ReactNode;
32
+ };
33
+ }
34
+ interface Layouts<C extends ConfigContext = ConfigContext> {
35
+ root: ComponentType<AppContext<C> & {
36
+ lang?: string;
37
+ children: ReactNode;
38
+ }>;
39
+ page: ComponentType<AppContext<C> & {
40
+ lang?: string;
41
+ slugs: string[];
42
+ }>;
43
+ notFound: ComponentType<AppContext<C> & {
44
+ lang?: string;
45
+ }>;
46
+ }
47
+ interface I18nConfig$1<Lang extends string = string> extends Pick<I18nConfig<NoInfer<Lang>>, "fallbackLanguage" | "parser"> {
48
+ /** locale code -> language info */
49
+ languages: { [K in Lang]: {
50
+ displayName: string;
51
+ translations?: TranslationsOption;
52
+ } };
53
+ defaultLanguage: NoInfer<Lang>;
54
+ }
55
+ interface SiteConfig {
56
+ /** full URL of app, used for metadata generation*/
57
+ baseUrl?: string;
58
+ name?: string;
59
+ git?: {
60
+ user: string;
61
+ repo: string;
62
+ branch: string; /** the root directory of git repo */
63
+ rootDir?: string;
64
+ };
65
+ }
66
+ interface I18nConfigBuilder<Lang extends string> extends I18nConfig$1<Lang> {
67
+ /** convert Fumapress i18n config to core i18n config */
68
+ toCore: () => I18nConfig<Lang>;
69
+ }
70
+ interface ConfigBuilder<C extends ConfigContext> extends Config<C> {
71
+ usePlugins: (...plugins: ServerPlugin<C>[]) => ConfigBuilder<C>;
72
+ useLayouts: (layouts: Partial<Layouts<C>>) => ConfigBuilder<C>;
73
+ useAdapters: (...adapters: Adapter[]) => ConfigBuilder<C>;
74
+ }
75
+ declare function defineConfig<C extends LoaderConfig, L extends string = string>(config: Config<{
76
+ loaderConfig: C;
77
+ lang: L;
78
+ }>): ConfigBuilder<{
79
+ loaderConfig: C;
80
+ lang: L;
81
+ }>;
82
+ declare function defineI18nConfig<Lang extends string>(config: I18nConfig$1<Lang>): I18nConfigBuilder<Lang>;
83
+ //#endregion
84
+ export { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig$1 as I18nConfig, I18nConfigBuilder, Layouts, SiteConfig, defineConfig, defineI18nConfig };
package/dist/config.js ADDED
@@ -0,0 +1,36 @@
1
+ //#region src/config.ts
2
+ function defineConfig(config) {
3
+ return {
4
+ ...config,
5
+ useAdapters(...adapters) {
6
+ this.adapters ??= [];
7
+ this.adapters.push(...adapters);
8
+ return this;
9
+ },
10
+ useLayouts(layouts) {
11
+ this.layouts ??= {};
12
+ Object.assign(this.layouts, layouts);
13
+ return this;
14
+ },
15
+ usePlugins(...plugins) {
16
+ this.plugins ??= [];
17
+ this.plugins.push(...plugins);
18
+ return this;
19
+ }
20
+ };
21
+ }
22
+ function defineI18nConfig(config) {
23
+ return {
24
+ ...config,
25
+ toCore() {
26
+ return {
27
+ defaultLanguage: this.defaultLanguage,
28
+ fallbackLanguage: this.fallbackLanguage,
29
+ parser: this.parser,
30
+ languages: Object.keys(this.languages)
31
+ };
32
+ }
33
+ };
34
+ }
35
+ //#endregion
36
+ export { defineConfig, defineI18nConfig };
@@ -0,0 +1,4 @@
1
+ import { AppContext, AppContextData } from "./lib/shared.js";
2
+ import { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig, I18nConfigBuilder, Layouts, SiteConfig, defineConfig, defineI18nConfig } from "./config.js";
3
+ import { Adapter, RouteFns, ServerPlugin } from "./lib/types.js";
4
+ export { type Adapter, type AppContext, type AppContextData, BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig, I18nConfigBuilder, Layouts, type RouteFns, type ServerPlugin, SiteConfig, defineConfig, defineI18nConfig };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { defineConfig, defineI18nConfig } from "./config.js";
2
+ export { defineConfig, defineI18nConfig };
@@ -0,0 +1,37 @@
1
+ import { AppContext, TransformChildren } from "../lib/shared.js";
2
+ import { ConfigContext, Layouts } from "../config.js";
3
+ import { Awaitable } from "../lib/types.js";
4
+ import { ReactNode } from "react";
5
+ import { DocsLayoutProps } from "fumadocs-ui/layouts/docs";
6
+ import { DocsPageProps } from "fumadocs-ui/layouts/docs/page";
7
+ import { Page } from "fumadocs-core/source";
8
+
9
+ //#region src/layouts/docs.d.ts
10
+ interface DocsLayoutOptions<C extends ConfigContext = ConfigContext> {
11
+ render?: (this: AppContext<C> & {
12
+ lang?: string;
13
+ }, page: C["loaderConfig"]["page"]) => Awaitable<{
14
+ markdownUrl?: string;
15
+ lastModified?: Date | null;
16
+ body?: ReactNode;
17
+ layoutProps?: TransformChildren<Partial<DocsLayoutProps>>;
18
+ pageProps?: TransformChildren<DocsPageProps>;
19
+ }>;
20
+ }
21
+ interface DocsLayoutRenderData {
22
+ markdownUrl?: string;
23
+ lastModified?: Date | null;
24
+ body: ReactNode;
25
+ layoutProps: TransformChildren<DocsLayoutProps>;
26
+ pageProps: TransformChildren<DocsPageProps>;
27
+ }
28
+ interface DocsLayoutContextData {
29
+ renderers?: ((this: {
30
+ page: Page;
31
+ }, data: DocsLayoutRenderData) => Awaitable<DocsLayoutRenderData>)[];
32
+ }
33
+ declare function createDocsLayout<C extends ConfigContext = ConfigContext>({
34
+ render
35
+ }?: DocsLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
36
+ //#endregion
37
+ export { DocsLayoutContextData, DocsLayoutOptions, DocsLayoutRenderData, createDocsLayout };
@@ -0,0 +1,83 @@
1
+ import { TransformChildrenSlot, baseOptions, getGitHubFileUrl, renderPageMeta } from "../lib/shared.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { unstable_notFound } from "waku/router/server";
4
+ import { DocsLayout } from "fumadocs-ui/layouts/docs";
5
+ import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, PageLastUpdate, ViewOptionsPopover } from "fumadocs-ui/layouts/docs/page";
6
+ //#region src/layouts/docs.tsx
7
+ function createDocsLayout({ render } = {}) {
8
+ async function defaultRender(page) {
9
+ let body;
10
+ let toc;
11
+ for (const adapter of this.adapters) {
12
+ body = await adapter["core:render-body"]?.call(this, page);
13
+ if (body !== void 0) break;
14
+ }
15
+ for (const adapter of this.adapters) {
16
+ toc = await adapter["core:render-toc"]?.call(this, page);
17
+ if (toc !== void 0) break;
18
+ }
19
+ if (body === void 0) throw new Error("[Fumapress] Please specify the `render` option in createDocsLayout()");
20
+ return {
21
+ body,
22
+ pageProps: { toc }
23
+ };
24
+ }
25
+ return async function Layout(props) {
26
+ const { slugs, lang, getLoader, data: { "core:docs-layout": layoutData } } = props;
27
+ const source = await getLoader();
28
+ const page = source.getPage(slugs, lang);
29
+ if (!page) unstable_notFound();
30
+ const _raw = await (render ?? defaultRender).call(props, page);
31
+ let result;
32
+ if (_raw.body === void 0 || _raw.pageProps === void 0) {
33
+ const _default = await defaultRender.call(props, page);
34
+ result = {
35
+ markdownUrl: _raw.markdownUrl,
36
+ pageProps: _raw.pageProps ?? _default.pageProps,
37
+ body: _raw.body ?? _default.body,
38
+ layoutProps: {
39
+ tree: source.getPageTree(lang),
40
+ ..._raw.layoutProps ?? baseOptions(props)
41
+ }
42
+ };
43
+ } else result = {
44
+ body: _raw.body,
45
+ pageProps: _raw.pageProps,
46
+ markdownUrl: _raw.markdownUrl,
47
+ layoutProps: {
48
+ tree: source.getPageTree(lang),
49
+ ..._raw.layoutProps ?? baseOptions(props)
50
+ }
51
+ };
52
+ if (layoutData?.renderers) {
53
+ const renderCtx = { page };
54
+ for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
55
+ }
56
+ return /* @__PURE__ */ jsxs(TransformChildrenSlot, {
57
+ Comp: DocsLayout,
58
+ props: result.layoutProps,
59
+ children: [renderPageMeta(page, props), /* @__PURE__ */ jsxs(TransformChildrenSlot, {
60
+ Comp: DocsPage,
61
+ props: result.pageProps,
62
+ children: [
63
+ /* @__PURE__ */ jsx(DocsTitle, { children: page.data.title }),
64
+ /* @__PURE__ */ jsx(DocsDescription, {
65
+ className: "mb-0",
66
+ children: page.data.description
67
+ }),
68
+ /* @__PURE__ */ jsxs("div", {
69
+ className: "flex flex-row gap-2 items-center border-b pt-2 pb-6",
70
+ children: [result.markdownUrl && /* @__PURE__ */ jsx(MarkdownCopyButton, { markdownUrl: result.markdownUrl }), /* @__PURE__ */ jsx(ViewOptionsPopover, {
71
+ markdownUrl: result.markdownUrl,
72
+ githubUrl: page.absolutePath ? getGitHubFileUrl(props, page.absolutePath) : void 0
73
+ })]
74
+ }),
75
+ /* @__PURE__ */ jsx(DocsBody, { children: result.body }),
76
+ result.lastModified && /* @__PURE__ */ jsx(PageLastUpdate, { date: result.lastModified })
77
+ ]
78
+ })]
79
+ });
80
+ };
81
+ }
82
+ //#endregion
83
+ export { createDocsLayout };
@@ -0,0 +1,28 @@
1
+ import { AppContext, TransformChildren } from "../lib/shared.js";
2
+ import { ConfigContext, Layouts } from "../config.js";
3
+ import { Awaitable } from "../lib/types.js";
4
+ import { ReactNode } from "react";
5
+ import { HomeLayoutProps } from "fumadocs-ui/layouts/home";
6
+ import { Page } from "fumadocs-core/source";
7
+
8
+ //#region src/layouts/home.d.ts
9
+ interface HomeLayoutOptions<C extends ConfigContext = ConfigContext> {
10
+ render?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<{
11
+ body?: ReactNode;
12
+ layoutProps?: TransformChildren<Partial<HomeLayoutProps>>;
13
+ }>;
14
+ }
15
+ interface HomeLayoutRenderData {
16
+ body: ReactNode;
17
+ layoutProps: TransformChildren<HomeLayoutProps>;
18
+ }
19
+ interface HomeLayoutContextData {
20
+ renderers?: ((this: {
21
+ page: Page;
22
+ }, data: HomeLayoutRenderData) => Awaitable<HomeLayoutRenderData>)[];
23
+ }
24
+ declare function createHomeLayout<C extends ConfigContext = ConfigContext>({
25
+ render
26
+ }: HomeLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
27
+ //#endregion
28
+ export { HomeLayoutContextData, HomeLayoutOptions, HomeLayoutRenderData, createHomeLayout };
@@ -0,0 +1,35 @@
1
+ import { TransformChildrenSlot, baseOptions, renderPageMeta } from "../lib/shared.js";
2
+ import { jsxs } from "react/jsx-runtime";
3
+ import { unstable_notFound } from "waku/router/server";
4
+ import { HomeLayout } from "fumadocs-ui/layouts/home";
5
+ //#region src/layouts/home.tsx
6
+ function createHomeLayout({ render }) {
7
+ async function renderDefault(page) {
8
+ for (const adapter of this.adapters) {
9
+ const body = await adapter["core:render-body"]?.call(this, page);
10
+ if (body !== void 0) return { body };
11
+ }
12
+ throw new Error("[Fumapress] Please specify the `render` option in createHomeLayout()");
13
+ }
14
+ return async function Layout(props) {
15
+ const { slugs, lang, getLoader, data: { "core:home-layout": layoutData } } = props;
16
+ const page = (await getLoader()).getPage(slugs, lang);
17
+ if (!page) unstable_notFound();
18
+ const _raw = await (render ?? renderDefault).call(props, page);
19
+ let result = {
20
+ body: _raw.body === void 0 ? (await renderDefault.call(props, page)).body : _raw.body,
21
+ layoutProps: _raw.layoutProps ?? baseOptions(props)
22
+ };
23
+ if (layoutData?.renderers) {
24
+ const renderCtx = { page };
25
+ for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
26
+ }
27
+ return /* @__PURE__ */ jsxs(TransformChildrenSlot, {
28
+ Comp: HomeLayout,
29
+ props: result.layoutProps,
30
+ children: [renderPageMeta(page, props), result.body]
31
+ });
32
+ };
33
+ }
34
+ //#endregion
35
+ export { createHomeLayout };
@@ -0,0 +1,37 @@
1
+ import { AppContext, TransformChildren } from "../lib/shared.js";
2
+ import { ConfigContext, Layouts } from "../config.js";
3
+ import { Awaitable } from "../lib/types.js";
4
+ import { ReactNode } from "react";
5
+ import { DocsLayoutProps } from "fumadocs-ui/layouts/notebook";
6
+ import { DocsPageProps } from "fumadocs-ui/layouts/notebook/page";
7
+ import { Page } from "fumadocs-core/source";
8
+
9
+ //#region src/layouts/notebook.d.ts
10
+ interface NotebookLayoutOptions<C extends ConfigContext = ConfigContext> {
11
+ render?: (this: AppContext<C> & {
12
+ lang?: string;
13
+ }, page: C["loaderConfig"]["page"]) => Awaitable<{
14
+ markdownUrl?: string;
15
+ lastModified?: Date | null;
16
+ body?: ReactNode;
17
+ layoutProps?: TransformChildren<Partial<DocsLayoutProps>>;
18
+ pageProps?: TransformChildren<DocsPageProps>;
19
+ }>;
20
+ }
21
+ interface NotebookLayoutRenderData {
22
+ markdownUrl?: string;
23
+ lastModified?: Date | null;
24
+ body: ReactNode;
25
+ layoutProps: TransformChildren<DocsLayoutProps>;
26
+ pageProps: TransformChildren<DocsPageProps>;
27
+ }
28
+ interface NotebookLayoutContextData {
29
+ renderers?: ((this: {
30
+ page: Page;
31
+ }, data: NotebookLayoutRenderData) => Awaitable<NotebookLayoutRenderData>)[];
32
+ }
33
+ declare function createNotebookLayout<C extends ConfigContext = ConfigContext>({
34
+ render
35
+ }?: NotebookLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
36
+ //#endregion
37
+ export { NotebookLayoutContextData, NotebookLayoutOptions, NotebookLayoutRenderData, createNotebookLayout };
@@ -0,0 +1,83 @@
1
+ import { TransformChildrenSlot, baseOptions, getGitHubFileUrl, renderPageMeta } from "../lib/shared.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { unstable_notFound } from "waku/router/server";
4
+ import { DocsLayout } from "fumadocs-ui/layouts/notebook";
5
+ import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, PageLastUpdate, ViewOptionsPopover } from "fumadocs-ui/layouts/notebook/page";
6
+ //#region src/layouts/notebook.tsx
7
+ function createNotebookLayout({ render } = {}) {
8
+ async function defaultRender(page) {
9
+ let body;
10
+ let toc;
11
+ for (const adapter of this.adapters) {
12
+ body = await adapter["core:render-body"]?.call(this, page);
13
+ if (body !== void 0) break;
14
+ }
15
+ for (const adapter of this.adapters) {
16
+ toc = await adapter["core:render-toc"]?.call(this, page);
17
+ if (toc !== void 0) break;
18
+ }
19
+ if (body === void 0) throw new Error("[Fumapress] Please specify the `render` option in createNotebookLayout()");
20
+ return {
21
+ body,
22
+ pageProps: { toc }
23
+ };
24
+ }
25
+ return async function Layout(props) {
26
+ const { slugs, lang, getLoader, data: { "core:notebook-layout": layoutData } } = props;
27
+ const source = await getLoader();
28
+ const page = source.getPage(slugs, lang);
29
+ if (!page) unstable_notFound();
30
+ const _raw = await (render ?? defaultRender).call(props, page);
31
+ let result;
32
+ if (_raw.body === void 0 || _raw.pageProps === void 0) {
33
+ const _default = await defaultRender.call(props, page);
34
+ result = {
35
+ markdownUrl: _raw.markdownUrl,
36
+ pageProps: _raw.pageProps ?? _default.pageProps,
37
+ body: _raw.body ?? _default.body,
38
+ layoutProps: {
39
+ tree: source.getPageTree(lang),
40
+ ..._raw.layoutProps ?? baseOptions(props)
41
+ }
42
+ };
43
+ } else result = {
44
+ body: _raw.body,
45
+ pageProps: _raw.pageProps,
46
+ markdownUrl: _raw.markdownUrl,
47
+ layoutProps: {
48
+ tree: source.getPageTree(lang),
49
+ ..._raw.layoutProps ?? baseOptions(props)
50
+ }
51
+ };
52
+ if (layoutData?.renderers) {
53
+ const renderCtx = { page };
54
+ for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
55
+ }
56
+ return /* @__PURE__ */ jsxs(TransformChildrenSlot, {
57
+ Comp: DocsLayout,
58
+ props: result.layoutProps,
59
+ children: [renderPageMeta(page, props), /* @__PURE__ */ jsxs(TransformChildrenSlot, {
60
+ Comp: DocsPage,
61
+ props: result.pageProps,
62
+ children: [
63
+ /* @__PURE__ */ jsx(DocsTitle, { children: page.data.title }),
64
+ /* @__PURE__ */ jsx(DocsDescription, {
65
+ className: "mb-0",
66
+ children: page.data.description
67
+ }),
68
+ /* @__PURE__ */ jsxs("div", {
69
+ className: "flex flex-row gap-2 items-center border-b pt-2 pb-6",
70
+ children: [result.markdownUrl && /* @__PURE__ */ jsx(MarkdownCopyButton, { markdownUrl: result.markdownUrl }), /* @__PURE__ */ jsx(ViewOptionsPopover, {
71
+ markdownUrl: result.markdownUrl,
72
+ githubUrl: page.absolutePath ? getGitHubFileUrl(props, page.absolutePath) : void 0
73
+ })]
74
+ }),
75
+ /* @__PURE__ */ jsx(DocsBody, { children: result.body }),
76
+ result.lastModified && /* @__PURE__ */ jsx(PageLastUpdate, { date: result.lastModified })
77
+ ]
78
+ })]
79
+ });
80
+ };
81
+ }
82
+ //#endregion
83
+ export { createNotebookLayout };
@@ -0,0 +1,10 @@
1
+ import { ConfigContext, Layouts } from "../config.js";
2
+ import { RootProviderProps } from "fumadocs-ui/provider/waku";
3
+
4
+ //#region src/layouts/root.d.ts
5
+ interface RootLayoutOptions {
6
+ providerProps?: Omit<RootProviderProps, "children">;
7
+ }
8
+ declare function createRootLayout<C extends ConfigContext = ConfigContext>(options?: RootLayoutOptions): Layouts<C>["root"];
9
+ //#endregion
10
+ export { RootLayoutOptions, createRootLayout };