fumapress 0.2.4 → 0.3.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.
- package/css/generated.css +160 -8
- package/dist/_virtual/_rolldown/runtime.js +24 -0
- package/dist/adapters/mdx/schema.d.ts +39 -0
- package/dist/adapters/mdx/schema.js +9 -0
- package/dist/adapters/mdx.js +18 -0
- package/dist/components/blog-panel.js +56 -0
- package/dist/components/blog.js +60 -0
- package/dist/config.d.ts +22 -10
- package/dist/index.d.ts +3 -3
- package/dist/layouts/blog.d.ts +21 -0
- package/dist/layouts/blog.index.d.ts +15 -0
- package/dist/layouts/blog.index.js +36 -0
- package/dist/layouts/blog.js +85 -0
- package/dist/layouts/blog.tags.d.ts +19 -0
- package/dist/layouts/blog.tags.js +113 -0
- package/dist/layouts/docs.d.ts +9 -7
- package/dist/layouts/docs.js +43 -69
- package/dist/layouts/home.d.ts +20 -8
- package/dist/layouts/home.js +39 -19
- package/dist/layouts/notebook.d.ts +37 -0
- package/dist/layouts/notebook.js +59 -0
- package/dist/layouts/root.d.ts +1 -1
- package/dist/layouts/root.js +5 -6
- package/dist/layouts/switch.d.ts +11 -0
- package/dist/layouts/switch.js +25 -0
- package/dist/lib/cn.js +2 -0
- package/dist/lib/join-pathname.js +9 -0
- package/dist/lib/shared/blog.js +39 -0
- package/dist/lib/shared.d.ts +10 -4
- package/dist/lib/shared.js +51 -5
- package/dist/lib/types.d.ts +18 -6
- package/dist/node_modules/.pnpm/@fastify_deepmerge@3.2.1/node_modules/@fastify/deepmerge/index.js +108 -0
- package/dist/plugins/blog.d.ts +71 -0
- package/dist/plugins/blog.js +168 -0
- package/dist/router.d.ts +3 -4
- package/dist/router.js +32 -29
- package/dist/vite.js +5 -0
- package/package.json +26 -11
package/css/generated.css
CHANGED
|
@@ -1,103 +1,255 @@
|
|
|
1
|
+
@source inline("---spacing");
|
|
2
|
+
@source inline("-translate-x-1/2");
|
|
1
3
|
@source inline("@orama/orama");
|
|
2
4
|
@source inline("absolutePath");
|
|
3
|
-
@source inline("
|
|
5
|
+
@source inline("active:scale-95");
|
|
4
6
|
@source inline("as");
|
|
5
7
|
@source inline("async");
|
|
6
8
|
@source inline("await");
|
|
9
|
+
@source inline("backdrop-blur-sm");
|
|
10
|
+
@source inline("bg-fd-card");
|
|
11
|
+
@source inline("bg-fd-primary");
|
|
12
|
+
@source inline("bg-fd-primary/10");
|
|
13
|
+
@source inline("bg-fd-secondary/80");
|
|
14
|
+
@source inline("blog");
|
|
15
|
+
@source inline("blogPosts");
|
|
7
16
|
@source inline("body");
|
|
17
|
+
@source inline("border");
|
|
18
|
+
@source inline("border-2");
|
|
8
19
|
@source inline("border-b");
|
|
20
|
+
@source inline("border-dashed");
|
|
21
|
+
@source inline("border-fd-primary");
|
|
22
|
+
@source inline("border-y");
|
|
23
|
+
@source inline("bottom-2");
|
|
24
|
+
@source inline("buttonVariants");
|
|
25
|
+
@source inline("children");
|
|
26
|
+
@source inline("class-variance-authority");
|
|
9
27
|
@source inline("className");
|
|
10
28
|
@source inline("client");
|
|
29
|
+
@source inline("cn");
|
|
11
30
|
@source inline("const");
|
|
12
31
|
@source inline("core:docs-layout");
|
|
13
32
|
@source inline("core:home-layout");
|
|
33
|
+
@source inline("core:notebook-layout");
|
|
14
34
|
@source inline("core:provider");
|
|
15
|
-
@source inline("
|
|
16
|
-
@source inline("core:render-toc");
|
|
35
|
+
@source inline("count");
|
|
17
36
|
@source inline("create");
|
|
18
|
-
@source inline("
|
|
37
|
+
@source inline("createBlogIndexPage");
|
|
38
|
+
@source inline("createBlogLayout");
|
|
39
|
+
@source inline("createBlogLayoutPage");
|
|
40
|
+
@source inline("createBlogTagPage");
|
|
41
|
+
@source inline("createBlogTagsPage");
|
|
42
|
+
@source inline("createDocsLayoutPage");
|
|
19
43
|
@source inline("createHomeLayout");
|
|
44
|
+
@source inline("createHomeLayoutPage");
|
|
45
|
+
@source inline("createLayoutSwitch");
|
|
46
|
+
@source inline("createLayoutSwitchAuto");
|
|
47
|
+
@source inline("createNotebookLayoutPage");
|
|
20
48
|
@source inline("createRootLayout");
|
|
49
|
+
@source inline("creationDate");
|
|
50
|
+
@source inline("ctx");
|
|
51
|
+
@source inline("currentDate");
|
|
52
|
+
@source inline("cva");
|
|
21
53
|
@source inline("data");
|
|
22
54
|
@source inline("data-version");
|
|
55
|
+
@source inline("date");
|
|
56
|
+
@source inline("decoration-fd-primary");
|
|
23
57
|
@source inline("default");
|
|
58
|
+
@source inline("detect");
|
|
59
|
+
@source inline("detector");
|
|
60
|
+
@source inline("duration-150");
|
|
24
61
|
@source inline("else");
|
|
25
62
|
@source inline("empty");
|
|
63
|
+
@source inline("empty:hidden");
|
|
26
64
|
@source inline("en");
|
|
27
65
|
@source inline("english");
|
|
28
66
|
@source inline("export");
|
|
29
67
|
@source inline("extends");
|
|
68
|
+
@source inline("false");
|
|
69
|
+
@source inline("fixed");
|
|
30
70
|
@source inline("flex");
|
|
71
|
+
@source inline("flex-1");
|
|
31
72
|
@source inline("flex-col");
|
|
32
73
|
@source inline("flex-row");
|
|
74
|
+
@source inline("flex-wrap");
|
|
33
75
|
@source inline("flexsearchStaticClient");
|
|
76
|
+
@source inline("font-medium");
|
|
77
|
+
@source inline("font-mono");
|
|
78
|
+
@source inline("font-semibold");
|
|
34
79
|
@source inline("for");
|
|
35
80
|
@source inline("from");
|
|
36
81
|
@source inline("fumadocs-core/source");
|
|
37
82
|
@source inline("fumadocs-core/toc");
|
|
38
83
|
@source inline("function");
|
|
84
|
+
@source inline("gap-1");
|
|
39
85
|
@source inline("gap-2");
|
|
86
|
+
@source inline("gap-4");
|
|
87
|
+
@source inline("getCreationDate");
|
|
88
|
+
@source inline("getTags");
|
|
89
|
+
@source inline("ghost");
|
|
40
90
|
@source inline("githubUrl");
|
|
91
|
+
@source inline("grid");
|
|
92
|
+
@source inline("grid-cols-1");
|
|
93
|
+
@source inline("grid-cols-2");
|
|
94
|
+
@source inline("groupTags");
|
|
95
|
+
@source inline("grouped");
|
|
41
96
|
@source inline("hook");
|
|
42
97
|
@source inline("hooks");
|
|
98
|
+
@source inline("hover:bg-fd-accent");
|
|
99
|
+
@source inline("hover:text-fd-accent-foreground");
|
|
100
|
+
@source inline("href");
|
|
43
101
|
@source inline("i18n");
|
|
44
102
|
@source inline("i18nConfig");
|
|
45
103
|
@source inline("if");
|
|
46
104
|
@source inline("import");
|
|
47
105
|
@source inline("in");
|
|
106
|
+
@source inline("inherit");
|
|
107
|
+
@source inline("inline-flex");
|
|
48
108
|
@source inline("interface");
|
|
49
109
|
@source inline("isLoading");
|
|
110
|
+
@source inline("item");
|
|
50
111
|
@source inline("items");
|
|
51
112
|
@source inline("items-center");
|
|
113
|
+
@source inline("items-start");
|
|
114
|
+
@source inline("joinPathname");
|
|
115
|
+
@source inline("key");
|
|
52
116
|
@source inline("lang");
|
|
53
117
|
@source inline("language");
|
|
54
118
|
@source inline("languages");
|
|
119
|
+
@source inline("lastModified");
|
|
120
|
+
@source inline("layout");
|
|
55
121
|
@source inline("layoutData");
|
|
56
122
|
@source inline("layoutProps");
|
|
123
|
+
@source inline("layouts");
|
|
124
|
+
@source inline("left-1/2");
|
|
125
|
+
@source inline("length");
|
|
57
126
|
@source inline("let");
|
|
58
127
|
@source inline("loaderConfig");
|
|
59
128
|
@source inline("locale");
|
|
60
129
|
@source inline("locales");
|
|
130
|
+
@source inline("lucide-react");
|
|
61
131
|
@source inline("markdownUrl");
|
|
132
|
+
@source inline("matching");
|
|
133
|
+
@source inline("max-h-[min(600px,calc(100vh---spacing(30)))]");
|
|
134
|
+
@source inline("max-sm:-mx-4");
|
|
135
|
+
@source inline("max-w-[1400px]");
|
|
136
|
+
@source inline("max-w-[900px]");
|
|
137
|
+
@source inline("max-w-[calc(100%---spacing(4))]");
|
|
62
138
|
@source inline("mb-0");
|
|
139
|
+
@source inline("md:grid-cols-3");
|
|
140
|
+
@source inline("md:grid-cols-4");
|
|
141
|
+
@source inline("md:p-8");
|
|
63
142
|
@source inline("min-h-screen");
|
|
143
|
+
@source inline("min-w-0");
|
|
144
|
+
@source inline("ms-auto");
|
|
145
|
+
@source inline("mt-4");
|
|
146
|
+
@source inline("mt-6");
|
|
147
|
+
@source inline("mt-auto");
|
|
148
|
+
@source inline("mx-auto");
|
|
64
149
|
@source inline("name");
|
|
150
|
+
@source inline("never");
|
|
65
151
|
@source inline("new");
|
|
66
152
|
@source inline("of");
|
|
153
|
+
@source inline("onClick");
|
|
154
|
+
@source inline("onCopy");
|
|
155
|
+
@source inline("onOpenChange");
|
|
67
156
|
@source inline("onSearchChange");
|
|
157
|
+
@source inline("open");
|
|
68
158
|
@source inline("option");
|
|
159
|
+
@source inline("options");
|
|
160
|
+
@source inline("orderedPosts");
|
|
161
|
+
@source inline("overline");
|
|
162
|
+
@source inline("p-1");
|
|
163
|
+
@source inline("p-4");
|
|
69
164
|
@source inline("page");
|
|
70
165
|
@source inline("pageProps");
|
|
166
|
+
@source inline("panelButtonVariants");
|
|
167
|
+
@source inline("pb-20");
|
|
71
168
|
@source inline("pb-6");
|
|
169
|
+
@source inline("posts");
|
|
170
|
+
@source inline("primary");
|
|
171
|
+
@source inline("props");
|
|
172
|
+
@source inline("prose");
|
|
72
173
|
@source inline("providerProps");
|
|
73
174
|
@source inline("pt-2");
|
|
175
|
+
@source inline("pt-3.5");
|
|
176
|
+
@source inline("pt-4");
|
|
177
|
+
@source inline("pt-6");
|
|
178
|
+
@source inline("px-1.5");
|
|
179
|
+
@source inline("px-2");
|
|
180
|
+
@source inline("px-3");
|
|
181
|
+
@source inline("px-4");
|
|
182
|
+
@source inline("py-0.5");
|
|
183
|
+
@source inline("py-1");
|
|
184
|
+
@source inline("py-2");
|
|
74
185
|
@source inline("query");
|
|
75
186
|
@source inline("r");
|
|
76
187
|
@source inline("react");
|
|
77
188
|
@source inline("render");
|
|
78
189
|
@source inline("renderCtx");
|
|
79
|
-
@source inline("renderPageMeta");
|
|
80
190
|
@source inline("renderRootMeta");
|
|
81
191
|
@source inline("result");
|
|
82
192
|
@source inline("return");
|
|
83
193
|
@source inline("root");
|
|
84
|
-
@source inline("
|
|
194
|
+
@source inline("rotate-180");
|
|
195
|
+
@source inline("rounded-2xl");
|
|
196
|
+
@source inline("rounded-lg");
|
|
197
|
+
@source inline("rounded-xl");
|
|
85
198
|
@source inline("schema");
|
|
86
199
|
@source inline("search");
|
|
200
|
+
@source inline("setOpen");
|
|
201
|
+
@source inline("shadow-inner");
|
|
202
|
+
@source inline("shadow-md");
|
|
203
|
+
@source inline("shadow-sm");
|
|
204
|
+
@source inline("shrink-0");
|
|
205
|
+
@source inline("size-3.5");
|
|
206
|
+
@source inline("size-4");
|
|
207
|
+
@source inline("size-6");
|
|
208
|
+
@source inline("sm:border");
|
|
209
|
+
@source inline("sm:bottom-4");
|
|
210
|
+
@source inline("sm:grid-cols-3");
|
|
211
|
+
@source inline("sm:max-w-[400px]");
|
|
212
|
+
@source inline("sm:rounded-xl");
|
|
87
213
|
@source inline("source");
|
|
88
214
|
@source inline("specify");
|
|
89
215
|
@source inline("static");
|
|
90
216
|
@source inline("string");
|
|
91
217
|
@source inline("styles");
|
|
218
|
+
@source inline("tags");
|
|
219
|
+
@source inline("tagsPath");
|
|
220
|
+
@source inline("text-2xl");
|
|
221
|
+
@source inline("text-3xl");
|
|
222
|
+
@source inline("text-fd-card-foreground");
|
|
223
|
+
@source inline("text-fd-muted-foreground");
|
|
224
|
+
@source inline("text-fd-primary");
|
|
225
|
+
@source inline("text-fd-primary-foreground");
|
|
226
|
+
@source inline("text-sm");
|
|
227
|
+
@source inline("text-xs");
|
|
92
228
|
@source inline("the");
|
|
93
229
|
@source inline("this");
|
|
94
|
-
@source inline("
|
|
230
|
+
@source inline("title");
|
|
231
|
+
@source inline("to");
|
|
95
232
|
@source inline("toc");
|
|
233
|
+
@source inline("transition-all");
|
|
234
|
+
@source inline("transition-colors");
|
|
235
|
+
@source inline("transition-transform");
|
|
96
236
|
@source inline("translations");
|
|
97
237
|
@source inline("tree");
|
|
238
|
+
@source inline("truncate");
|
|
98
239
|
@source inline("type");
|
|
99
240
|
@source inline("undefined");
|
|
100
241
|
@source inline("unstable_notFound");
|
|
242
|
+
@source inline("url");
|
|
101
243
|
@source inline("use");
|
|
244
|
+
@source inline("useCopyButton");
|
|
102
245
|
@source inline("useDocsSearch");
|
|
103
|
-
@source inline("useI18n");
|
|
246
|
+
@source inline("useI18n");
|
|
247
|
+
@source inline("useState");
|
|
248
|
+
@source inline("useTOCItems");
|
|
249
|
+
@source inline("variant");
|
|
250
|
+
@source inline("w-full");
|
|
251
|
+
@source inline("waku");
|
|
252
|
+
@source inline("xl:grid-cols-4");
|
|
253
|
+
@source inline("xl:grid-cols-6");
|
|
254
|
+
@source inline("z-2");
|
|
255
|
+
@source inline("z-20");
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
export { __commonJSMin, __toESM };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as base from "fumadocs-core/source/schema";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/mdx/schema.d.ts
|
|
5
|
+
declare const pageSchema: z.ZodObject<{
|
|
6
|
+
title: z.ZodString;
|
|
7
|
+
description: z.ZodOptional<z.ZodString>;
|
|
8
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
9
|
+
full: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
_openapi: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<base._JSONType, base._JSONType>>>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
declare const metaSchema: z.ZodObject<{
|
|
13
|
+
title: z.ZodOptional<z.ZodString>;
|
|
14
|
+
pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
15
|
+
description: z.ZodOptional<z.ZodString>;
|
|
16
|
+
root: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
defaultOpen: z.ZodOptional<z.ZodBoolean>;
|
|
18
|
+
collapsible: z.ZodOptional<z.ZodBoolean>;
|
|
19
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
declare const blogPageSchema: z.ZodObject<{
|
|
22
|
+
title: z.ZodString;
|
|
23
|
+
description: z.ZodOptional<z.ZodString>;
|
|
24
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
25
|
+
full: z.ZodOptional<z.ZodBoolean>;
|
|
26
|
+
_openapi: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<base._JSONType, base._JSONType>>>;
|
|
27
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
declare const blogMetaSchema: z.ZodObject<{
|
|
30
|
+
title: z.ZodOptional<z.ZodString>;
|
|
31
|
+
pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
description: z.ZodOptional<z.ZodString>;
|
|
33
|
+
root: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
defaultOpen: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
collapsible: z.ZodOptional<z.ZodBoolean>;
|
|
36
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { blogMetaSchema, blogPageSchema, metaSchema, pageSchema };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as base from "fumadocs-core/source/schema";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
//#region src/adapters/mdx/schema.ts
|
|
4
|
+
const pageSchema = base.pageSchema;
|
|
5
|
+
const metaSchema = base.metaSchema;
|
|
6
|
+
const blogPageSchema = base.pageSchema.extend({ tags: z.array(z.string()).optional() });
|
|
7
|
+
const blogMetaSchema = base.metaSchema;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { blogMetaSchema, blogPageSchema, metaSchema, pageSchema };
|
package/dist/adapters/mdx.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
2
|
import defaultMdxComponents, { createRelativeLink } from "fumadocs-ui/mdx";
|
|
3
|
+
import { z } from "zod/mini";
|
|
3
4
|
//#region src/adapters/mdx.ts
|
|
4
5
|
function fumadocsMdx(options) {
|
|
5
6
|
const getMdxComponents = options?.getMdxComponents;
|
|
@@ -24,9 +25,26 @@ function fumadocsMdx(options) {
|
|
|
24
25
|
async "core:render-toc"(page) {
|
|
25
26
|
if (isSyncEntry(page.data)) return page.data.toc;
|
|
26
27
|
if (isAsyncEntry(page.data)) return (await page.data.load()).toc;
|
|
28
|
+
},
|
|
29
|
+
"core:get-creation-date"(page) {
|
|
30
|
+
if (isSyncEntry(page.data) || isAsyncEntry(page.data)) return "date" in page.data && page.data.date instanceof Date ? page.data.date : void 0;
|
|
31
|
+
},
|
|
32
|
+
async "core:get-modified-date"(page) {
|
|
33
|
+
let data;
|
|
34
|
+
if (isSyncEntry(page.data)) data = page.data;
|
|
35
|
+
else if (isAsyncEntry(page.data)) data = await page.data.load();
|
|
36
|
+
else return;
|
|
37
|
+
return "lastModified" in data && data.lastModified instanceof Date ? data.lastModified : void 0;
|
|
38
|
+
},
|
|
39
|
+
"blog:get-tags"(page) {
|
|
40
|
+
if (isSyncEntry(page.data) || isAsyncEntry(page.data)) {
|
|
41
|
+
const parsed = tagsSchema.safeParse(page.data);
|
|
42
|
+
return parsed.success ? parsed.data.tags : void 0;
|
|
43
|
+
}
|
|
27
44
|
}
|
|
28
45
|
};
|
|
29
46
|
}
|
|
47
|
+
const tagsSchema = z.looseObject({ tags: z.optional(z.array(z.string())) });
|
|
30
48
|
function isSyncEntry(v) {
|
|
31
49
|
return "info" in v && typeof v.info === "object" && "_exports" in v && typeof v._exports === "object";
|
|
32
50
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { ChevronDown, ShareIcon } from "lucide-react";
|
|
6
|
+
import { TOCProvider, TOCScrollArea, useTOCItems } from "fumadocs-ui/components/toc";
|
|
7
|
+
import { TOCItem, TOCItems } from "fumadocs-ui/components/toc/clerk";
|
|
8
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "fumadocs-ui/components/ui/collapsible";
|
|
9
|
+
import { cva } from "class-variance-authority";
|
|
10
|
+
import { useCopyButton } from "fumadocs-ui/utils/use-copy-button";
|
|
11
|
+
//#region src/components/blog-panel.tsx
|
|
12
|
+
const panelButtonVariants = cva("inline-flex items-center font-medium gap-2 px-3 py-2 transition-all duration-150 rounded-lg hover:text-fd-accent-foreground hover:bg-fd-accent active:scale-95");
|
|
13
|
+
function BlogPanel() {
|
|
14
|
+
const items = useTOCItems();
|
|
15
|
+
const [open, setOpen] = useState(false);
|
|
16
|
+
const [isSuccessful, onCopy] = useCopyButton(() => {
|
|
17
|
+
if (navigator.share) return navigator.share({
|
|
18
|
+
title: document.title,
|
|
19
|
+
url: location.href
|
|
20
|
+
});
|
|
21
|
+
else return navigator.clipboard.writeText(location.href);
|
|
22
|
+
});
|
|
23
|
+
return /* @__PURE__ */ jsxs(Collapsible, {
|
|
24
|
+
open,
|
|
25
|
+
onOpenChange: setOpen,
|
|
26
|
+
className: "fixed w-full max-w-[calc(100%---spacing(4))] left-1/2 -translate-x-1/2 bottom-2 border shadow-md text-sm bg-fd-secondary/80 backdrop-blur-sm z-20 p-1 rounded-xl sm:max-w-[400px] sm:bottom-4",
|
|
27
|
+
children: [/* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(TOCScrollArea, {
|
|
28
|
+
className: "max-h-[min(600px,calc(100vh---spacing(30)))]",
|
|
29
|
+
children: /* @__PURE__ */ jsx(TOCItems, { children: items.map((item) => /* @__PURE__ */ jsx(TOCItem, {
|
|
30
|
+
item,
|
|
31
|
+
onClick: () => setOpen(false)
|
|
32
|
+
}, item.url)) })
|
|
33
|
+
}) }), /* @__PURE__ */ jsxs("div", {
|
|
34
|
+
className: "flex flex-row gap-2",
|
|
35
|
+
children: [/* @__PURE__ */ jsxs(CollapsibleTrigger, {
|
|
36
|
+
className: cn(panelButtonVariants(), "min-w-0"),
|
|
37
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
38
|
+
className: "truncate",
|
|
39
|
+
children: "Table of Contents"
|
|
40
|
+
}), /* @__PURE__ */ jsx(ChevronDown, { className: cn("size-3.5 shrink-0 text-fd-muted-foreground transition-transform", open && "rotate-180") })]
|
|
41
|
+
}), /* @__PURE__ */ jsxs("button", {
|
|
42
|
+
className: cn(panelButtonVariants(), "ms-auto text-fd-muted-foreground"),
|
|
43
|
+
onClick: onCopy,
|
|
44
|
+
children: [/* @__PURE__ */ jsx(ShareIcon, { className: "size-3.5 shrink-0" }), isSuccessful ? "Copied" : "Share"]
|
|
45
|
+
})]
|
|
46
|
+
})]
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function BlogProvider({ toc, children }) {
|
|
50
|
+
return /* @__PURE__ */ jsx(TOCProvider, {
|
|
51
|
+
toc,
|
|
52
|
+
children
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { BlogPanel, BlogProvider };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getCreationDate } from "../lib/shared.js";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { joinPathname } from "../lib/join-pathname.js";
|
|
4
|
+
import { Link } from "waku";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { buttonVariants } from "fumadocs-ui/components/ui/button";
|
|
7
|
+
import { CornerLeftUpIcon } from "lucide-react";
|
|
8
|
+
//#region src/components/blog.tsx
|
|
9
|
+
function BlogItem({ page, date }) {
|
|
10
|
+
return /* @__PURE__ */ jsxs(Link, {
|
|
11
|
+
to: page.url,
|
|
12
|
+
className: "flex flex-col bg-fd-card rounded-2xl border shadow-sm p-4 transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx("p", {
|
|
15
|
+
className: "font-medium",
|
|
16
|
+
children: page.data.title
|
|
17
|
+
}),
|
|
18
|
+
/* @__PURE__ */ jsx("p", {
|
|
19
|
+
className: "text-sm text-fd-muted-foreground",
|
|
20
|
+
children: page.data.description
|
|
21
|
+
}),
|
|
22
|
+
/* @__PURE__ */ jsx("p", {
|
|
23
|
+
className: "mt-auto pt-4 text-xs text-fd-primary",
|
|
24
|
+
children: date.toDateString()
|
|
25
|
+
})
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function OrderedBlogGrid({ posts, ctx }) {
|
|
30
|
+
const currentDate = new Date(Date.now());
|
|
31
|
+
const orderedPosts = [];
|
|
32
|
+
for (const page of posts) {
|
|
33
|
+
const date = await getCreationDate(ctx, page);
|
|
34
|
+
orderedPosts.push({
|
|
35
|
+
page,
|
|
36
|
+
date: date ?? currentDate
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
orderedPosts.sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
40
|
+
return /* @__PURE__ */ jsx("div", {
|
|
41
|
+
className: "grid grid-cols-1 gap-2 mt-4 md:grid-cols-3 xl:grid-cols-4",
|
|
42
|
+
children: orderedPosts.map(({ page, date }) => /* @__PURE__ */ jsx(BlogItem, {
|
|
43
|
+
page,
|
|
44
|
+
date
|
|
45
|
+
}, page.url))
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function LinkToHome({ lang, blog }) {
|
|
49
|
+
if (!blog.indexPath) return;
|
|
50
|
+
return /* @__PURE__ */ jsxs(Link, {
|
|
51
|
+
to: lang ? joinPathname(lang, blog.indexPath) : blog.indexPath,
|
|
52
|
+
className: cn(buttonVariants({
|
|
53
|
+
variant: "ghost",
|
|
54
|
+
className: "text-fd-muted-foreground gap-2"
|
|
55
|
+
})),
|
|
56
|
+
children: [/* @__PURE__ */ jsx(CornerLeftUpIcon, { className: "size-3.5" }), "Back to Home"]
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { LinkToHome, OrderedBlogGrid };
|
package/dist/config.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { ComponentType, ReactNode } from "react";
|
|
|
4
4
|
import { TranslationsOption } from "fumadocs-ui/contexts/i18n";
|
|
5
5
|
import { LoaderConfig, LoaderOutput } from "fumadocs-core/source";
|
|
6
6
|
import { I18nConfig } from "fumadocs-core/i18n";
|
|
7
|
+
import { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
|
7
8
|
|
|
8
9
|
//#region src/config.d.ts
|
|
9
10
|
interface ConfigContext {
|
|
@@ -26,31 +27,42 @@ interface Config<C extends ConfigContext = ConfigContext> {
|
|
|
26
27
|
/** adapter for content sources, use `fumadocs-mdx` if not specified */
|
|
27
28
|
adapters?: Adapter[];
|
|
28
29
|
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
|
-
};
|
|
30
|
+
meta?: MetaConfig<C>;
|
|
33
31
|
}
|
|
34
32
|
interface Layouts<C extends ConfigContext = ConfigContext> {
|
|
35
|
-
root: ComponentType<
|
|
33
|
+
root: ComponentType<{
|
|
36
34
|
lang?: string;
|
|
35
|
+
ctx: AppContext<C>;
|
|
37
36
|
children: ReactNode;
|
|
38
37
|
}>;
|
|
39
|
-
page: ComponentType<
|
|
38
|
+
page: ComponentType<{
|
|
40
39
|
lang?: string;
|
|
40
|
+
ctx: AppContext<C>;
|
|
41
41
|
slugs: string[];
|
|
42
42
|
}>;
|
|
43
|
-
notFound: ComponentType<
|
|
43
|
+
notFound: ComponentType<{
|
|
44
44
|
lang?: string;
|
|
45
|
+
ctx: AppContext<C>;
|
|
45
46
|
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Define default props for page layouts, will be merged with current props.
|
|
49
|
+
*/
|
|
50
|
+
defaultProps?: (this: AppContext<C>, env: {
|
|
51
|
+
lang: string | undefined;
|
|
52
|
+
}) => Awaitable<Omit<BaseLayoutProps, "children">>;
|
|
46
53
|
}
|
|
47
|
-
interface I18nConfig$1<Lang extends string = string> extends Pick<I18nConfig<NoInfer<Lang>>, "fallbackLanguage" | "parser"> {
|
|
54
|
+
interface I18nConfig$1<Lang extends string = string> extends Pick<I18nConfig<NoInfer<Lang>>, "defaultLanguage" | "fallbackLanguage" | "parser"> {
|
|
48
55
|
/** locale code -> language info */
|
|
49
56
|
languages: { [K in Lang]: {
|
|
50
57
|
displayName: string;
|
|
51
58
|
translations?: TranslationsOption;
|
|
52
59
|
} };
|
|
53
|
-
|
|
60
|
+
}
|
|
61
|
+
interface MetaConfig<C extends ConfigContext = ConfigContext> {
|
|
62
|
+
/** render meta tags for any pages */
|
|
63
|
+
root?: (this: AppContext<C>) => ReactNode;
|
|
64
|
+
/** render meta tags for page */
|
|
65
|
+
page?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => ReactNode;
|
|
54
66
|
}
|
|
55
67
|
interface SiteConfig {
|
|
56
68
|
/** full URL of app, used for metadata generation*/
|
|
@@ -81,4 +93,4 @@ declare function defineConfig<C extends LoaderConfig, L extends string = string>
|
|
|
81
93
|
}>;
|
|
82
94
|
declare function defineI18nConfig<Lang extends string>(config: I18nConfig$1<Lang>): I18nConfigBuilder<Lang>;
|
|
83
95
|
//#endregion
|
|
84
|
-
export { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig$1 as I18nConfig, I18nConfigBuilder, Layouts, SiteConfig, defineConfig, defineI18nConfig };
|
|
96
|
+
export { BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig$1 as I18nConfig, I18nConfigBuilder, Layouts, MetaConfig, SiteConfig, defineConfig, defineI18nConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
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, ServerPlugin } from "./lib/types.js";
|
|
4
|
-
export { type Adapter, type AppContext, type AppContextData, BuildMode, Config, ConfigBuilder, ConfigContext, I18nConfig, I18nConfigBuilder, Layouts, type ServerPlugin, SiteConfig, defineConfig, defineI18nConfig };
|
|
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 };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HomeLayoutOptions } from "./home.js";
|
|
2
|
+
import { AppContext } from "../lib/shared.js";
|
|
3
|
+
import { ConfigContext } from "../config.js";
|
|
4
|
+
import { Awaitable } from "../lib/types.js";
|
|
5
|
+
import { BlogLayout, BlogLayoutPage } from "../plugins/blog.js";
|
|
6
|
+
import { ReactNode } from "react";
|
|
7
|
+
import { TOCItemType } from "fumadocs-core/toc";
|
|
8
|
+
|
|
9
|
+
//#region src/layouts/blog.d.ts
|
|
10
|
+
declare function createBlogLayout<C extends ConfigContext = ConfigContext>(options?: HomeLayoutOptions<C>): BlogLayout<C>;
|
|
11
|
+
interface BlogLayoutPageRenderData {
|
|
12
|
+
creationDate?: Date;
|
|
13
|
+
toc: TOCItemType[];
|
|
14
|
+
body: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
interface BlogLayoutPageOptions<C extends ConfigContext = ConfigContext> {
|
|
17
|
+
render?: (this: AppContext<C>, page: C["loaderConfig"]["page"]) => Awaitable<Partial<BlogLayoutPageRenderData>>;
|
|
18
|
+
}
|
|
19
|
+
declare function createBlogLayoutPage<C extends ConfigContext = ConfigContext>(options?: BlogLayoutPageOptions<C>): BlogLayoutPage<C>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { BlogLayoutPageOptions, BlogLayoutPageRenderData, createBlogLayout, createBlogLayoutPage };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ConfigContext } from "../config.js";
|
|
2
|
+
import { BlogIndexPage } from "../plugins/blog.js";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/layouts/blog.index.d.ts
|
|
6
|
+
interface BlogIndexPageOptions {
|
|
7
|
+
heading?: ReactNode;
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
declare function createBlogIndexPage<C extends ConfigContext = ConfigContext>({
|
|
11
|
+
heading,
|
|
12
|
+
description
|
|
13
|
+
}?: BlogIndexPageOptions): BlogIndexPage<C>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { BlogIndexPageOptions, createBlogIndexPage };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { joinPathname } from "../lib/join-pathname.js";
|
|
3
|
+
import { OrderedBlogGrid } from "../components/blog.js";
|
|
4
|
+
import { Link } from "waku";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { buttonVariants } from "fumadocs-ui/components/ui/button";
|
|
7
|
+
import { ListIcon } from "lucide-react";
|
|
8
|
+
//#region src/layouts/blog.index.tsx
|
|
9
|
+
function createBlogIndexPage({ heading, description } = {}) {
|
|
10
|
+
return async function BlogIndexPage({ lang, blog, ctx }) {
|
|
11
|
+
const source = await ctx.getLoader();
|
|
12
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
13
|
+
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
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ jsx("h1", {
|
|
16
|
+
className: "text-3xl font-semibold",
|
|
17
|
+
children: heading ?? "Blog"
|
|
18
|
+
}),
|
|
19
|
+
/* @__PURE__ */ jsx("p", {
|
|
20
|
+
className: "text-fd-primary overline decoration-fd-primary empty:hidden",
|
|
21
|
+
children: description
|
|
22
|
+
}),
|
|
23
|
+
blog.tagsPath !== false && /* @__PURE__ */ jsxs(Link, {
|
|
24
|
+
to: lang ? joinPathname(lang, blog.tagsPath) : blog.tagsPath,
|
|
25
|
+
className: cn(buttonVariants({ variant: "primary" }), "gap-2"),
|
|
26
|
+
children: [/* @__PURE__ */ jsx(ListIcon, { className: "size-4" }), "All Tags"]
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
}), /* @__PURE__ */ jsx(OrderedBlogGrid, {
|
|
30
|
+
posts: source.getPages(lang).filter((page) => blog.isBlog.call(ctx, page)),
|
|
31
|
+
ctx
|
|
32
|
+
})] });
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { createBlogIndexPage };
|