fumapress 0.3.1 → 0.5.0

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.
Files changed (55) hide show
  1. package/css/generated.css +65 -11
  2. package/dist/adapters/mdx/schema.d.ts +2 -0
  3. package/dist/client.d.ts +56 -0
  4. package/dist/client.js +16 -0
  5. package/dist/components/blog-panel.js +5 -3
  6. package/dist/components/blog.js +12 -8
  7. package/dist/components/flexsearch-static.js +1 -1
  8. package/dist/components/i18n.js +16 -0
  9. package/dist/components/openapi.js +6 -0
  10. package/dist/components/openapi.payload.js +21 -0
  11. package/dist/components/orama-search-static.js +1 -1
  12. package/dist/config.d.ts +35 -36
  13. package/dist/config.js +20 -23
  14. package/dist/i18n.d.ts +18 -0
  15. package/dist/i18n.js +20 -0
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +3 -2
  18. package/dist/layouts/blog.d.ts +3 -2
  19. package/dist/layouts/blog.index.js +13 -11
  20. package/dist/layouts/blog.js +15 -23
  21. package/dist/layouts/blog.tags.js +29 -47
  22. package/dist/layouts/docs.d.ts +8 -2
  23. package/dist/layouts/docs.js +8 -8
  24. package/dist/layouts/home.d.ts +26 -19
  25. package/dist/layouts/home.js +20 -32
  26. package/dist/layouts/notebook.d.ts +8 -2
  27. package/dist/layouts/notebook.js +8 -8
  28. package/dist/layouts/root.js +18 -15
  29. package/dist/layouts/switch.d.ts +2 -2
  30. package/dist/layouts/switch.js +5 -8
  31. package/dist/lib/join-pathname.js +4 -4
  32. package/dist/lib/shared.d.ts +17 -17
  33. package/dist/lib/shared.js +47 -13
  34. package/dist/lib/types.d.ts +51 -7
  35. package/dist/lib/vitefu.js +1 -1
  36. package/dist/plugins/blog.d.ts +27 -23
  37. package/dist/plugins/blog.js +47 -124
  38. package/dist/plugins/flexsearch.js +7 -5
  39. package/dist/plugins/internal/disable-search.js +15 -0
  40. package/dist/plugins/llms.txt.d.ts +7 -0
  41. package/dist/plugins/llms.txt.js +60 -25
  42. package/dist/plugins/openapi.d.ts +12 -5
  43. package/dist/plugins/openapi.js +63 -8
  44. package/dist/plugins/orama-search.js +7 -5
  45. package/dist/plugins/takumi.d.ts +10 -0
  46. package/dist/plugins/takumi.js +26 -24
  47. package/dist/router/fs.d.ts +36 -0
  48. package/dist/router/fs.js +106 -0
  49. package/dist/router.d.ts +10 -7
  50. package/dist/router.js +100 -63
  51. package/dist/vite.d.ts +1 -1
  52. package/dist/vite.js +26 -3
  53. package/package.json +19 -12
  54. package/dist/adapters/openapi.d.ts +0 -15
  55. package/dist/adapters/openapi.js +0 -22
package/dist/config.js CHANGED
@@ -1,36 +1,33 @@
1
1
  //#region src/config.ts
2
2
  function defineConfig(config) {
3
+ const plugins = [];
4
+ const layouts = {};
5
+ const adapters = [];
3
6
  return {
4
7
  ...config,
5
- useAdapters(...adapters) {
6
- this.adapters ??= [];
7
- this.adapters.push(...adapters);
8
+ $context: void 0,
9
+ getPlugins() {
10
+ return plugins;
11
+ },
12
+ getAdapters() {
13
+ return adapters;
14
+ },
15
+ getLayouts() {
16
+ return layouts;
17
+ },
18
+ useAdapters(...values) {
19
+ adapters.push(...values);
8
20
  return this;
9
21
  },
10
- useLayouts(layouts) {
11
- this.layouts ??= {};
12
- Object.assign(this.layouts, layouts);
22
+ useLayouts(overrides) {
23
+ Object.assign(layouts, overrides);
13
24
  return this;
14
25
  },
15
- usePlugins(...plugins) {
16
- this.plugins ??= [];
17
- this.plugins.push(...plugins);
26
+ usePlugins(...values) {
27
+ plugins.push(...values);
18
28
  return this;
19
29
  }
20
30
  };
21
31
  }
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
32
  //#endregion
36
- export { defineConfig, defineI18nConfig };
33
+ export { defineConfig };
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { TranslationValue, TranslationsAPIExtension } from "fumadocs-core/i18n";
2
+
3
+ //#region src/i18n.d.ts
4
+ declare const defaultTranslations: {
5
+ blog: string;
6
+ allTags: string;
7
+ tagsInTotal: TranslationValue<"count">;
8
+ tagTitle: TranslationValue<"tag">;
9
+ matchingBlogPosts: TranslationValue<"count">;
10
+ backToHome: string;
11
+ tableOfContents: string;
12
+ share: string;
13
+ copied: string;
14
+ };
15
+ type Translations = typeof defaultTranslations;
16
+ declare function fumapressTranslations(): TranslationsAPIExtension<"fumapress", Translations>;
17
+ //#endregion
18
+ export { Translations, defaultTranslations, fumapressTranslations };
package/dist/i18n.js ADDED
@@ -0,0 +1,20 @@
1
+ //#region src/i18n.ts
2
+ const defaultTranslations = {
3
+ blog: "Blog",
4
+ allTags: "All Tags",
5
+ tagsInTotal: "{count} tags in total.",
6
+ tagTitle: "Tag \"{tag}\"",
7
+ matchingBlogPosts: "{count} matching blog posts.",
8
+ backToHome: "Back to Home",
9
+ tableOfContents: "Table of Contents",
10
+ share: "Share",
11
+ copied: "Copied"
12
+ };
13
+ function fumapressTranslations() {
14
+ return {
15
+ namespace: "fumapress",
16
+ defaultValue: defaultTranslations
17
+ };
18
+ }
19
+ //#endregion
20
+ export { defaultTranslations, fumapressTranslations };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppContext, AppContextData } from "./lib/shared.js";
2
- import { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig, I18nConfigBuilder, Layouts, MetaConfig, 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, MetaConfig, type RouteFns, type ServerPlugin, SiteConfig, defineConfig, defineI18nConfig };
1
+ import { AppContext, getPressContext } from "./lib/shared.js";
2
+ import { BuildMode, Config, ConfigBuilder, ConfigContext, Layouts, MetaConfig, SiteConfig, defineConfig } from "./config.js";
3
+ import { Adapter, AppContextData, RouteConfig, RouteFns, ServerPlugin, ServerPluginOption } from "./lib/types.js";
4
+ export { type Adapter, type AppContext, type AppContextData, BuildMode, Config, ConfigBuilder, ConfigContext, Layouts, MetaConfig, type RouteConfig, type RouteFns, type ServerPlugin, type ServerPluginOption, SiteConfig, defineConfig, getPressContext };
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- import { defineConfig, defineI18nConfig } from "./config.js";
2
- export { defineConfig, defineI18nConfig };
1
+ import { defineConfig } from "./config.js";
2
+ import { getPressContext } from "./lib/shared.js";
3
+ export { defineConfig, getPressContext };
@@ -1,13 +1,14 @@
1
- import { HomeLayoutOptions } from "./home.js";
2
1
  import { AppContext } from "../lib/shared.js";
3
2
  import { ConfigContext } from "../config.js";
3
+ import { HomeLayoutOptions } from "./home.js";
4
4
  import { Awaitable } from "../lib/types.js";
5
5
  import { BlogLayout, BlogLayoutPage } from "../plugins/blog.js";
6
6
  import { ReactNode } from "react";
7
7
  import { TOCItemType } from "fumadocs-core/toc";
8
8
 
9
9
  //#region src/layouts/blog.d.ts
10
- declare function createBlogLayout<C extends ConfigContext = ConfigContext>(options?: HomeLayoutOptions<C>): BlogLayout<C>;
10
+ /** You can use `createHomeLayout()` directly, this is only a wrapper */
11
+ declare function createBlogLayout<C extends ConfigContext>(options?: HomeLayoutOptions<C>): BlogLayout<C>;
11
12
  interface BlogLayoutPageRenderData {
12
13
  creationDate?: Date;
13
14
  toc: TOCItemType[];
@@ -1,35 +1,37 @@
1
+ import { getPressContext } from "../lib/shared.js";
1
2
  import { cn } from "../lib/cn.js";
3
+ import { I18nLabel } from "../components/i18n.js";
2
4
  import { joinPathname } from "../lib/join-pathname.js";
5
+ import { getBlogContext } from "../plugins/blog.js";
3
6
  import { OrderedBlogGrid } from "../components/blog.js";
4
- import { Link } from "waku";
5
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
- import { buttonVariants } from "fumadocs-ui/components/ui/button";
8
+ import { Link } from "waku";
7
9
  import { ListIcon } from "lucide-react";
10
+ import { buttonVariants } from "fumadocs-ui/components/ui/button";
8
11
  //#region src/layouts/blog.index.tsx
9
12
  function createBlogIndexPage({ heading, description } = {}) {
10
- return async function BlogIndexPage({ lang, blog, ctx }) {
13
+ return async function BlogIndexPage({ lang }) {
14
+ const ctx = getPressContext();
15
+ const { tagsPath, isBlog } = getBlogContext();
11
16
  const source = await ctx.getLoader();
12
17
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
13
18
  className: "flex flex-col gap-4 items-start border-2 border-dashed border-fd-primary rounded-xl bg-fd-primary/10 p-4 z-2 md:p-8",
14
19
  children: [
15
20
  /* @__PURE__ */ jsx("h1", {
16
21
  className: "text-3xl font-semibold",
17
- children: heading ?? "Blog"
22
+ children: heading ?? /* @__PURE__ */ jsx(I18nLabel, { label: "blog" })
18
23
  }),
19
24
  /* @__PURE__ */ jsx("p", {
20
25
  className: "text-fd-primary overline decoration-fd-primary empty:hidden",
21
26
  children: description
22
27
  }),
23
- blog.tagsPath !== false && /* @__PURE__ */ jsxs(Link, {
24
- to: lang ? joinPathname(lang, blog.tagsPath) : blog.tagsPath,
28
+ tagsPath !== false && /* @__PURE__ */ jsxs(Link, {
29
+ to: lang ? joinPathname(lang, tagsPath) : tagsPath,
25
30
  className: cn(buttonVariants({ variant: "primary" }), "gap-2"),
26
- children: [/* @__PURE__ */ jsx(ListIcon, { className: "size-4" }), "All Tags"]
31
+ children: [/* @__PURE__ */ jsx(ListIcon, { className: "size-4" }), /* @__PURE__ */ jsx(I18nLabel, { label: "allTags" })]
27
32
  })
28
33
  ]
29
- }), /* @__PURE__ */ jsx(OrderedBlogGrid, {
30
- posts: source.getPages(lang).filter((page) => blog.isBlog.call(ctx, page)),
31
- ctx
32
- })] });
34
+ }), /* @__PURE__ */ jsx(OrderedBlogGrid, { posts: source.getPages(lang).filter(isBlog.bind(ctx)) })] });
33
35
  };
34
36
  }
35
37
  //#endregion
@@ -1,29 +1,23 @@
1
- import { getCreationDate, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
2
- import { joinPathname } from "../lib/join-pathname.js";
3
- import { LinkToHome } from "../components/blog.js";
4
- import { getTags } from "../lib/shared/blog.js";
1
+ import { getCreationDate, getPressContext, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
5
2
  import { BlogPanel, BlogProvider } from "../components/blog-panel.js";
3
+ import { getTags } from "../lib/shared/blog.js";
4
+ import { joinPathname } from "../lib/join-pathname.js";
6
5
  import { createHomeLayout } from "./home.js";
7
- import { Link } from "waku";
6
+ import { getBlogContext } from "../plugins/blog.js";
7
+ import { LinkToHome } from "../components/blog.js";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { Link } from "waku";
9
10
  import { TagIcon } from "lucide-react";
10
11
  //#region src/layouts/blog.tsx
12
+ /** You can use `createHomeLayout()` directly, this is only a wrapper */
11
13
  function createBlogLayout(options) {
12
- const HomeLayout = createHomeLayout(options);
13
- return function BlogLayout({ children, ctx, lang }) {
14
- return /* @__PURE__ */ jsx(HomeLayout, {
15
- lang,
16
- ctx,
17
- children: /* @__PURE__ */ jsx("main", {
18
- className: "flex flex-col w-full max-w-[1400px] flex-1 px-4 pt-6 pb-20 mx-auto",
19
- children
20
- })
21
- });
22
- };
14
+ return createHomeLayout(options);
23
15
  }
24
16
  function createBlogLayoutPage(options = {}) {
25
17
  const { render } = options;
26
- return async function BlogLayoutPage({ ctx, page, blog, lang }) {
18
+ return async function BlogLayoutPage({ page, lang }) {
19
+ const ctx = getPressContext();
20
+ const { tagsPath } = getBlogContext();
27
21
  const tags = await getTags(ctx, page);
28
22
  const _raw = await render?.call(ctx, page);
29
23
  const result = {
@@ -40,10 +34,7 @@ function createBlogLayoutPage(options = {}) {
40
34
  children: [
41
35
  /* @__PURE__ */ jsx("div", {
42
36
  className: "flex flex-row items-center gap-2 w-full max-w-[900px]",
43
- children: /* @__PURE__ */ jsx(LinkToHome, {
44
- blog,
45
- lang
46
- })
37
+ children: /* @__PURE__ */ jsx(LinkToHome, { lang })
47
38
  }),
48
39
  /* @__PURE__ */ jsx("h1", {
49
40
  className: "font-semibold text-2xl w-full max-w-[900px]",
@@ -56,8 +47,8 @@ function createBlogLayoutPage(options = {}) {
56
47
  tags && tags.length > 0 && /* @__PURE__ */ jsxs("div", {
57
48
  className: "flex flex-row items-center gap-2 flex-wrap w-full max-w-[900px] text-sm text-fd-primary-foreground font-mono",
58
49
  children: [/* @__PURE__ */ jsx(TagIcon, { className: "size-4 text-fd-muted-foreground" }), tags.map((t) => {
59
- if (blog.tagsPath !== false) return /* @__PURE__ */ jsx(Link, {
60
- to: joinPathname(lang ?? "", blog.tagsPath, t),
50
+ if (tagsPath !== false) return /* @__PURE__ */ jsx(Link, {
51
+ to: joinPathname(lang ?? "", tagsPath, t),
61
52
  className: "px-1.5 py-0.5 rounded-lg bg-fd-primary",
62
53
  children: t
63
54
  }, t);
@@ -73,6 +64,7 @@ function createBlogLayoutPage(options = {}) {
73
64
  className: "prose mt-6 mx-auto w-full max-w-[900px]",
74
65
  children: result.body
75
66
  }),
67
+ /* @__PURE__ */ jsx("div", { className: "h-12" }),
76
68
  /* @__PURE__ */ jsx(BlogPanel, {})
77
69
  ]
78
70
  });
@@ -1,35 +1,33 @@
1
- import { LinkToHome, OrderedBlogGrid } from "../components/blog.js";
1
+ import { getPressContext } from "../lib/shared.js";
2
+ import { I18nLabel } from "../components/i18n.js";
2
3
  import { getTags, groupTags } from "../lib/shared/blog.js";
3
- import { Link } from "waku";
4
+ import { getBlogContext } from "../plugins/blog.js";
5
+ import { LinkToHome, OrderedBlogGrid } from "../components/blog.js";
4
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { Link } from "waku";
5
8
  import { NewspaperIcon, TagIcon } from "lucide-react";
6
9
  //#region src/layouts/blog.tags.tsx
7
10
  function createBlogTagsPage({ heading, description } = {}) {
8
- return async function BlogTagsPage({ lang, blog, ctx }) {
9
- const grouped = await groupTags(ctx, (await ctx.getLoader()).getPages(lang).filter((page) => blog.isBlog.call(ctx, page)));
11
+ return async function BlogTagsPage({ lang }) {
12
+ const ctx = getPressContext();
13
+ const { isBlog } = getBlogContext();
14
+ const grouped = await groupTags(ctx, (await ctx.getLoader()).getPages(lang).filter((page) => isBlog.call(ctx, page)));
10
15
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
11
16
  className: "flex flex-col items-start gap-4 border-y px-4 pt-3.5 pb-6 bg-fd-card text-fd-card-foreground shadow-inner max-sm:-mx-4 sm:rounded-xl sm:border",
12
17
  children: [
13
- /* @__PURE__ */ jsx(LinkToHome, {
14
- lang,
15
- blog
16
- }),
18
+ /* @__PURE__ */ jsx(LinkToHome, { lang }),
17
19
  /* @__PURE__ */ jsx("h1", {
18
20
  className: "font-semibold text-2xl",
19
- children: heading ?? "All Tags"
21
+ children: heading ?? /* @__PURE__ */ jsx(I18nLabel, { label: "allTags" })
20
22
  }),
21
23
  /* @__PURE__ */ jsx("p", {
22
24
  className: "text-fd-muted-foreground empty:hidden",
23
25
  children: description ?? /* @__PURE__ */ jsxs("span", {
24
26
  className: "flex items-center gap-1",
25
- children: [
26
- /* @__PURE__ */ jsx(TagIcon, { className: "size-3.5 text-fd-primary" }),
27
- /* @__PURE__ */ jsx("span", {
28
- className: "text-fd-primary font-mono",
29
- children: grouped.size
30
- }),
31
- " tags in total."
32
- ]
27
+ children: [/* @__PURE__ */ jsx(TagIcon, { className: "size-3.5 text-fd-primary" }), /* @__PURE__ */ jsx(I18nLabel, {
28
+ label: "tagsInTotal",
29
+ replacements: { count: String(grouped.size) }
30
+ })]
33
31
  })
34
32
  })
35
33
  ]
@@ -54,11 +52,13 @@ function createBlogTagsPage({ heading, description } = {}) {
54
52
  };
55
53
  }
56
54
  function createBlogTagPage({ heading, description } = {}) {
57
- return async function BlogTagsPage({ lang, tag, blog, ctx }) {
55
+ return async function BlogTagPage({ lang, tag }) {
56
+ const ctx = getPressContext();
57
+ const { isBlog } = getBlogContext();
58
58
  const source = await ctx.getLoader();
59
59
  const posts = [];
60
60
  for (const page of source.getPages(lang)) {
61
- if (!blog.isBlog.call(ctx, page)) continue;
61
+ if (!isBlog.call(ctx, page)) continue;
62
62
  const tags = await getTags(ctx, page);
63
63
  if (!tags || !tags.includes(tag)) continue;
64
64
  posts.push(page);
@@ -66,47 +66,29 @@ function createBlogTagPage({ heading, description } = {}) {
66
66
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
67
67
  className: "flex flex-col items-start gap-4 border-y p-4 pt-3.5 bg-fd-card text-fd-card-foreground shadow-inner max-sm:-mx-4 sm:rounded-xl sm:border",
68
68
  children: [
69
- /* @__PURE__ */ jsx(LinkToHome, {
70
- lang,
71
- blog
72
- }),
69
+ /* @__PURE__ */ jsx(LinkToHome, { lang }),
73
70
  /* @__PURE__ */ jsx("h1", {
74
71
  className: "font-semibold text-2xl",
75
72
  children: heading ?? /* @__PURE__ */ jsxs("span", {
76
73
  className: "inline-flex gap-2 items-center",
77
- children: [
78
- /* @__PURE__ */ jsx(TagIcon, { className: "text-fd-primary size-6" }),
79
- "Tag ",
80
- /* @__PURE__ */ jsxs("span", {
81
- className: "font-mono text-fd-primary",
82
- children: [
83
- "\"",
84
- tag,
85
- "\""
86
- ]
87
- })
88
- ]
74
+ children: [/* @__PURE__ */ jsx(TagIcon, { className: "text-fd-primary size-6" }), /* @__PURE__ */ jsx(I18nLabel, {
75
+ label: "tagTitle",
76
+ replacements: { tag }
77
+ })]
89
78
  })
90
79
  }),
91
80
  /* @__PURE__ */ jsx("p", {
92
81
  className: "text-fd-muted-foreground empty:hidden",
93
82
  children: description ?? /* @__PURE__ */ jsxs("span", {
94
83
  className: "inline-flex items-center gap-1",
95
- children: [
96
- /* @__PURE__ */ jsx(NewspaperIcon, { className: "text-fd-primary size-3.5" }),
97
- /* @__PURE__ */ jsx("span", {
98
- className: "font-mono text-fd-primary",
99
- children: posts.length
100
- }),
101
- " matching blog posts."
102
- ]
84
+ children: [/* @__PURE__ */ jsx(NewspaperIcon, { className: "text-fd-primary size-3.5" }), /* @__PURE__ */ jsx(I18nLabel, {
85
+ label: "matchingBlogPosts",
86
+ replacements: { count: String(posts.length) }
87
+ })]
103
88
  })
104
89
  })
105
90
  ]
106
- }), /* @__PURE__ */ jsx(OrderedBlogGrid, {
107
- posts,
108
- ctx
109
- })] });
91
+ }), /* @__PURE__ */ jsx(OrderedBlogGrid, { posts })] });
110
92
  };
111
93
  }
112
94
  //#endregion
@@ -1,13 +1,16 @@
1
1
  import { AppContext, TransformChildren } from "../lib/shared.js";
2
2
  import { ConfigContext, Layouts } from "../config.js";
3
3
  import { Awaitable } from "../lib/types.js";
4
+ import { Page } from "fumadocs-core/source";
4
5
  import { ReactNode } from "react";
5
6
  import { DocsLayoutProps } from "fumadocs-ui/layouts/docs";
6
7
  import { DocsPageProps } from "fumadocs-ui/layouts/docs/page";
7
- import { Page } from "fumadocs-core/source";
8
8
 
9
9
  //#region src/layouts/docs.d.ts
10
10
  interface DocsLayoutOptions<C extends ConfigContext = ConfigContext> {
11
+ inherit?: {
12
+ layoutProps?: boolean;
13
+ };
11
14
  render?: (this: AppContext<C> & {
12
15
  lang?: string;
13
16
  }, page: C["loaderConfig"]["page"]) => Awaitable<{
@@ -31,7 +34,10 @@ interface DocsLayoutContextData {
31
34
  }, data: DocsLayoutRenderData) => Awaitable<DocsLayoutRenderData>)[];
32
35
  }
33
36
  declare function createDocsLayoutPage<C extends ConfigContext = ConfigContext>({
34
- render
37
+ render,
38
+ inherit: {
39
+ layoutProps: inheritLayoutProps
40
+ }
35
41
  }?: DocsLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
36
42
  //#endregion
37
43
  export { DocsLayoutContextData, DocsLayoutOptions, DocsLayoutRenderData, createDocsLayoutPage };
@@ -1,19 +1,19 @@
1
- import { baseLayoutProps, createTransformChildren, getGitHubFileUrl, getLastModifiedDate, mergeLayoutConfigs, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
1
+ import { baseLayoutProps, createTransformChildren, getGitHubFileUrl, getLastModifiedDate, getPressContext, mergeLayoutConfigs, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { DocsLayout } from "fumadocs-ui/layouts/docs";
4
4
  import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, PageLastUpdate, ViewOptionsPopover } from "fumadocs-ui/layouts/docs/page";
5
5
  //#region src/layouts/docs.tsx
6
- function createDocsLayoutPage({ render } = {}) {
6
+ function createDocsLayoutPage({ render, inherit: { layoutProps: inheritLayoutProps = true } = {} } = {}) {
7
7
  const TDocsLayout = createTransformChildren(DocsLayout);
8
8
  const TDocsPage = createTransformChildren(DocsPage);
9
- return async function Layout({ lang, page, ctx }) {
9
+ return async function Layout({ lang, page }) {
10
+ const ctx = getPressContext();
10
11
  const { getLoader, layouts, data: { "core:docs-layout": layoutData } } = ctx;
11
12
  const source = await getLoader();
12
- async function getLayoutProps(overrides) {
13
- const inherit = await layouts.defaultProps?.call(ctx, { lang });
14
- return mergeLayoutConfigs({ tree: source.getPageTree(lang) }, baseLayoutProps(ctx), inherit, overrides);
15
- }
13
+ const inherited = inheritLayoutProps ? await layouts.defaultProps?.call(ctx, { lang }) : void 0;
16
14
  const _raw = await render?.call(ctx, page);
15
+ const layoutProps = mergeLayoutConfigs(baseLayoutProps(ctx), inherited, _raw?.layoutProps);
16
+ layoutProps.tree ??= source.getPageTree(lang);
17
17
  let result = {
18
18
  ..._raw,
19
19
  lastModified: _raw?.lastModified ?? await getLastModifiedDate(ctx, page),
@@ -22,7 +22,7 @@ function createDocsLayoutPage({ render } = {}) {
22
22
  toc: _raw?.pageProps?.toc ?? await renderToc(ctx, page)
23
23
  },
24
24
  body: _raw?.body ?? await renderBody(ctx, page, "[Fumapress] Please specify the `render` option in createDocsLayoutPage()"),
25
- layoutProps: await getLayoutProps(_raw?.layoutProps)
25
+ layoutProps
26
26
  };
27
27
  if (layoutData?.renderers) {
28
28
  const renderCtx = { page };
@@ -1,40 +1,47 @@
1
1
  import { AppContext, TransformChildren } from "../lib/shared.js";
2
2
  import { ConfigContext, Layouts } from "../config.js";
3
3
  import { Awaitable } from "../lib/types.js";
4
- import { ComponentType, ReactNode } from "react";
4
+ import { FC, ReactNode } from "react";
5
5
  import { HomeLayoutProps } from "fumadocs-ui/layouts/home";
6
- import { Page } from "fumadocs-core/source";
7
6
 
8
7
  //#region src/layouts/home.d.ts
8
+ type LayoutComponent<C extends ConfigContext> = FC<{
9
+ lang?: string | undefined;
10
+ layoutProps?: TransformChildren<HomeLayoutProps> | undefined;
11
+ children: ReactNode;
12
+ }> & {
13
+ $ctx?: C;
14
+ };
9
15
  interface HomeLayoutPageOptions<C extends ConfigContext = ConfigContext> {
16
+ /** swap the outer layout of page content */
17
+ layout?: LayoutComponent<C>;
10
18
  render?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<{
11
19
  body?: ReactNode;
12
20
  layoutProps?: TransformChildren<HomeLayoutProps>;
13
21
  }>;
14
22
  }
23
+ declare function createHomeLayoutPage<C extends ConfigContext = ConfigContext>({
24
+ layout: Container,
25
+ render
26
+ }?: HomeLayoutPageOptions<NoInfer<C>>): Layouts<C>["page"];
27
+ interface HomeLayoutOptions<C extends ConfigContext = ConfigContext> {
28
+ inherit?: {
29
+ layoutProps?: boolean;
30
+ };
31
+ layoutProps?: TransformChildren<HomeLayoutProps> | ((this: AppContext<C>) => Awaitable<TransformChildren<HomeLayoutProps>>);
32
+ }
15
33
  interface HomeLayoutRenderData {
16
34
  body: ReactNode;
17
35
  layoutProps: TransformChildren<HomeLayoutProps>;
18
36
  }
19
37
  interface HomeLayoutContextData {
20
- renderers?: ((this: {
21
- page: Page | undefined;
22
- }, data: HomeLayoutRenderData) => Awaitable<HomeLayoutRenderData>)[];
23
- }
24
- declare function createHomeLayoutPage<C extends ConfigContext = ConfigContext>({
25
- render
26
- }?: HomeLayoutPageOptions<NoInfer<C>>): Layouts<C>["page"];
27
- interface HomeLayoutOptions<C extends ConfigContext = ConfigContext> {
28
- render?: (this: AppContext<C>) => Awaitable<{
29
- layoutProps?: TransformChildren<HomeLayoutProps>;
30
- }>;
38
+ renderers?: ((data: HomeLayoutRenderData) => Awaitable<HomeLayoutRenderData>)[];
31
39
  }
32
40
  declare function createHomeLayout<C extends ConfigContext = ConfigContext>({
33
- render
34
- }?: HomeLayoutOptions<C>): ComponentType<{
35
- lang?: string;
36
- children: ReactNode;
37
- ctx: AppContext<C>;
38
- }>;
41
+ layoutProps: getLayoutProps,
42
+ inherit: {
43
+ layoutProps: inheritLayoutProps
44
+ }
45
+ }?: HomeLayoutOptions<C>): LayoutComponent<C>;
39
46
  //#endregion
40
47
  export { HomeLayoutContextData, HomeLayoutOptions, HomeLayoutPageOptions, HomeLayoutRenderData, createHomeLayout, createHomeLayoutPage };
@@ -1,49 +1,37 @@
1
- import { baseLayoutProps, createTransformChildren, mergeLayoutConfigs, renderBody, renderPageMeta } from "../lib/shared.js";
1
+ import { baseLayoutProps, createTransformChildren, getPressContext, mergeLayoutConfigs, renderBody, renderPageMeta } from "../lib/shared.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { HomeLayout } from "fumadocs-ui/layouts/home";
4
4
  //#region src/layouts/home.tsx
5
- function createHomeLayoutPage({ render } = {}) {
6
- const THomeLayout = createTransformChildren(HomeLayout);
7
- return async function Layout({ lang, page, ctx }) {
8
- const { layouts, data: { "core:home-layout": layoutData } } = ctx;
9
- async function getLayoutProps(overrides) {
10
- const inherit = await layouts.defaultProps?.call(ctx, { lang });
11
- return mergeLayoutConfigs(baseLayoutProps(ctx), inherit, overrides);
12
- }
5
+ function createHomeLayoutPage({ layout: Container = createHomeLayout(), render } = {}) {
6
+ return async function Layout({ lang, page }) {
7
+ const ctx = getPressContext();
13
8
  const _raw = await render?.call(ctx, page);
14
- let result = {
15
- body: _raw?.body ?? await renderBody(ctx, page, "[Fumapress] Please specify the `render` option in createHomeLayoutPage()"),
16
- layoutProps: await getLayoutProps(_raw?.layoutProps)
17
- };
18
- if (layoutData?.renderers) {
19
- const renderCtx = { page };
20
- for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
21
- }
22
- return /* @__PURE__ */ jsxs(THomeLayout, {
23
- props: result.layoutProps,
24
- children: [renderPageMeta(page, ctx), result.body]
9
+ const body = _raw?.body ?? await renderBody(ctx, page, "[Fumapress] Please specify the `render` option in createHomeLayoutPage()");
10
+ return /* @__PURE__ */ jsxs(Container, {
11
+ lang,
12
+ layoutProps: _raw?.layoutProps,
13
+ children: [renderPageMeta(page, ctx), body]
25
14
  });
26
15
  };
27
16
  }
28
- function createHomeLayout({ render } = {}) {
17
+ function createHomeLayout({ layoutProps: getLayoutProps, inherit: { layoutProps: inheritLayoutProps = true } = {} } = {}) {
29
18
  const THomeLayout = createTransformChildren(HomeLayout);
30
- return async function Layout({ lang, children, ctx }) {
19
+ return async function Layout({ lang, layoutProps, children }) {
20
+ const ctx = getPressContext();
31
21
  const { layouts, data: { "core:home-layout": layoutData } } = ctx;
32
- async function getLayoutProps(overrides) {
33
- const inherit = await layouts.defaultProps?.call(ctx, { lang });
34
- return mergeLayoutConfigs(baseLayoutProps(ctx), inherit, overrides);
35
- }
22
+ const inherited = inheritLayoutProps ? await layouts.defaultProps?.call(ctx, { lang }) : void 0;
36
23
  let result = {
37
24
  body: children,
38
- layoutProps: await getLayoutProps((await render?.call(ctx))?.layoutProps)
25
+ layoutProps: mergeLayoutConfigs(baseLayoutProps(ctx), inherited, typeof getLayoutProps === "function" ? await getLayoutProps.call(ctx) : getLayoutProps, layoutProps)
39
26
  };
40
- if (layoutData?.renderers) {
41
- const renderCtx = { page: void 0 };
42
- for (const r of layoutData.renderers) result = await r.call(renderCtx, result);
43
- }
27
+ if (layoutData?.renderers) for (const r of layoutData.renderers) result = await r(result);
44
28
  return /* @__PURE__ */ jsx(THomeLayout, {
45
29
  props: result.layoutProps,
46
- children: result.body
30
+ children: /* @__PURE__ */ jsx("main", {
31
+ "data-fd-home-layout-container": "",
32
+ className: "flex flex-col w-full max-w-[1400px] flex-1 px-4 py-6 mx-auto",
33
+ children: result.body
34
+ })
47
35
  });
48
36
  };
49
37
  }
@@ -1,13 +1,16 @@
1
1
  import { AppContext, TransformChildren } from "../lib/shared.js";
2
2
  import { ConfigContext, Layouts } from "../config.js";
3
3
  import { Awaitable } from "../lib/types.js";
4
+ import { Page } from "fumadocs-core/source";
4
5
  import { ReactNode } from "react";
5
6
  import { DocsLayoutProps } from "fumadocs-ui/layouts/notebook";
6
7
  import { DocsPageProps } from "fumadocs-ui/layouts/notebook/page";
7
- import { Page } from "fumadocs-core/source";
8
8
 
9
9
  //#region src/layouts/notebook.d.ts
10
10
  interface NotebookLayoutOptions<C extends ConfigContext = ConfigContext> {
11
+ inherit?: {
12
+ layoutProps?: boolean;
13
+ };
11
14
  render?: (this: AppContext<C> & {
12
15
  lang?: string;
13
16
  }, page: C["loaderConfig"]["page"]) => Awaitable<{
@@ -31,7 +34,10 @@ interface NotebookLayoutContextData {
31
34
  }, data: NotebookLayoutRenderData) => Awaitable<NotebookLayoutRenderData>)[];
32
35
  }
33
36
  declare function createNotebookLayoutPage<C extends ConfigContext = ConfigContext>({
34
- render
37
+ render,
38
+ inherit: {
39
+ layoutProps: inheritLayoutProps
40
+ }
35
41
  }?: NotebookLayoutOptions<NoInfer<C>>): Layouts<C>["page"];
36
42
  //#endregion
37
43
  export { NotebookLayoutContextData, NotebookLayoutOptions, NotebookLayoutRenderData, createNotebookLayoutPage };
@@ -1,19 +1,19 @@
1
- import { baseLayoutProps, createTransformChildren, getGitHubFileUrl, getLastModifiedDate, mergeLayoutConfigs, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
1
+ import { baseLayoutProps, createTransformChildren, getGitHubFileUrl, getLastModifiedDate, getPressContext, mergeLayoutConfigs, renderBody, renderPageMeta, renderToc } from "../lib/shared.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { DocsLayout } from "fumadocs-ui/layouts/notebook";
4
4
  import { DocsBody, DocsDescription, DocsPage, DocsTitle, MarkdownCopyButton, PageLastUpdate, ViewOptionsPopover } from "fumadocs-ui/layouts/notebook/page";
5
5
  //#region src/layouts/notebook.tsx
6
- function createNotebookLayoutPage({ render } = {}) {
6
+ function createNotebookLayoutPage({ render, inherit: { layoutProps: inheritLayoutProps = true } = {} } = {}) {
7
7
  const TDocsLayout = createTransformChildren(DocsLayout);
8
8
  const TDocsPage = createTransformChildren(DocsPage);
9
- return async function Layout({ lang, page, ctx }) {
9
+ return async function Layout({ lang, page }) {
10
+ const ctx = getPressContext();
10
11
  const { getLoader, layouts, data: { "core:notebook-layout": layoutData } } = ctx;
11
12
  const source = await getLoader();
12
- async function getLayoutProps(overrides) {
13
- const inherit = await layouts.defaultProps?.call(ctx, { lang });
14
- return mergeLayoutConfigs({ tree: source.getPageTree(lang) }, baseLayoutProps(ctx), inherit, overrides);
15
- }
13
+ const inherited = inheritLayoutProps ? await layouts.defaultProps?.call(ctx, { lang }) : void 0;
16
14
  const _raw = await render?.call(ctx, page);
15
+ const layoutProps = mergeLayoutConfigs(baseLayoutProps(ctx), inherited, _raw?.layoutProps);
16
+ layoutProps.tree ??= source.getPageTree(lang);
17
17
  let result = {
18
18
  ..._raw,
19
19
  lastModified: _raw?.lastModified ?? await getLastModifiedDate(ctx, page),
@@ -22,7 +22,7 @@ function createNotebookLayoutPage({ render } = {}) {
22
22
  toc: _raw?.pageProps?.toc ?? await renderToc(ctx, page)
23
23
  },
24
24
  body: _raw?.body ?? await renderBody(ctx, page, "[Fumapress] Please specify the `render` option in createNotebookLayoutPage()"),
25
- layoutProps: await getLayoutProps(_raw?.layoutProps)
25
+ layoutProps
26
26
  };
27
27
  if (layoutData?.renderers) {
28
28
  const renderCtx = { page };