@vezham/docs-core 1.0.1
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/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/advanced-Ct13khZr.js +79 -0
- package/dist/algolia-C0E5qQhM.d.ts +66 -0
- package/dist/breadcrumb.d.ts +46 -0
- package/dist/breadcrumb.js +59 -0
- package/dist/build-doc-4OvfjVN2.js +85 -0
- package/dist/client-kQ39Ub0-.d.ts +247 -0
- package/dist/codeblock-utils-CyP8qsYv.d.ts +29 -0
- package/dist/content/github.d.ts +41 -0
- package/dist/content/github.js +28 -0
- package/dist/content/md/frontmatter.d.ts +15 -0
- package/dist/content/md/frontmatter.js +24 -0
- package/dist/content/md.d.ts +24 -0
- package/dist/content/md.js +43 -0
- package/dist/content/mdx/preset-bundler.d.ts +29 -0
- package/dist/content/mdx/preset-bundler.js +39 -0
- package/dist/content/mdx/preset-runtime.d.ts +26 -0
- package/dist/content/mdx/preset-runtime.js +36 -0
- package/dist/content/toc.d.ts +19 -0
- package/dist/content/toc.js +14 -0
- package/dist/definitions-CFOhwE1k.d.ts +72 -0
- package/dist/dynamic-CTsodhTH.js +905 -0
- package/dist/dynamic-link.d.ts +12 -0
- package/dist/dynamic-link.js +31 -0
- package/dist/endpoint-MyoBU5IC.js +28 -0
- package/dist/framework/astro.d.ts +21 -0
- package/dist/framework/astro.js +52 -0
- package/dist/framework/index.d.ts +40 -0
- package/dist/framework/index.js +66 -0
- package/dist/framework/next.d.ts +10 -0
- package/dist/framework/next.js +19 -0
- package/dist/framework/react-router.d.ts +10 -0
- package/dist/framework/react-router.js +43 -0
- package/dist/framework/tanstack.d.ts +13 -0
- package/dist/framework/tanstack.js +54 -0
- package/dist/framework/waku.d.ts +10 -0
- package/dist/framework/waku.js +46 -0
- package/dist/highlight/client.d.ts +11 -0
- package/dist/highlight/client.js +15 -0
- package/dist/highlight/index.d.ts +31 -0
- package/dist/highlight/index.js +30 -0
- package/dist/highlight/shiki/full.d.ts +7 -0
- package/dist/highlight/shiki/full.js +23 -0
- package/dist/highlight/shiki/index.d.ts +2 -0
- package/dist/highlight/shiki/index.js +27 -0
- package/dist/highlight/shiki/react.d.ts +23 -0
- package/dist/highlight/shiki/react.js +50 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/index.js +63 -0
- package/dist/i18n/middleware.d.ts +34 -0
- package/dist/i18n/middleware.js +3855 -0
- package/dist/icon-BILaoXeg.js +17 -0
- package/dist/index-B-0R0VbS.d.ts +18 -0
- package/dist/index-BM36H-xw.d.ts +36 -0
- package/dist/index-BMEUQz-F.d.ts +21 -0
- package/dist/index-DAYtLGbx.d.ts +16 -0
- package/dist/index-DIwKCYOz.d.ts +513 -0
- package/dist/index-DydiXvgS.d.ts +90 -0
- package/dist/index-E8Qh_yQs.d.ts +49 -0
- package/dist/is-equal-LdLqRs0o.js +8 -0
- package/dist/link.d.ts +17 -0
- package/dist/link.js +23 -0
- package/dist/mdx-plugins/codeblock-utils.d.ts +2 -0
- package/dist/mdx-plugins/codeblock-utils.js +68 -0
- package/dist/mdx-plugins/index.d.ts +20 -0
- package/dist/mdx-plugins/index.js +18 -0
- package/dist/mdx-plugins/rehype-code.core.d.ts +3 -0
- package/dist/mdx-plugins/rehype-code.core.js +3 -0
- package/dist/mdx-plugins/rehype-code.d.ts +4 -0
- package/dist/mdx-plugins/rehype-code.js +24 -0
- package/dist/mdx-plugins/rehype-toc.d.ts +2 -0
- package/dist/mdx-plugins/rehype-toc.js +139 -0
- package/dist/mdx-plugins/remark-admonition.d.ts +2 -0
- package/dist/mdx-plugins/remark-admonition.js +71 -0
- package/dist/mdx-plugins/remark-block-id.d.ts +37 -0
- package/dist/mdx-plugins/remark-block-id.js +41 -0
- package/dist/mdx-plugins/remark-code-tab.d.ts +2 -0
- package/dist/mdx-plugins/remark-code-tab.js +190 -0
- package/dist/mdx-plugins/remark-directive-admonition.d.ts +2 -0
- package/dist/mdx-plugins/remark-directive-admonition.js +57 -0
- package/dist/mdx-plugins/remark-feedback-block.d.ts +2 -0
- package/dist/mdx-plugins/remark-feedback-block.js +54 -0
- package/dist/mdx-plugins/remark-gfm.d.ts +2 -0
- package/dist/mdx-plugins/remark-gfm.js +2 -0
- package/dist/mdx-plugins/remark-heading.d.ts +2 -0
- package/dist/mdx-plugins/remark-heading.js +46 -0
- package/dist/mdx-plugins/remark-image.d.ts +2 -0
- package/dist/mdx-plugins/remark-image.js +167 -0
- package/dist/mdx-plugins/remark-llms.d.ts +2 -0
- package/dist/mdx-plugins/remark-llms.js +338 -0
- package/dist/mdx-plugins/remark-llms.runtime.d.ts +10 -0
- package/dist/mdx-plugins/remark-llms.runtime.js +24 -0
- package/dist/mdx-plugins/remark-mdx-files.d.ts +2 -0
- package/dist/mdx-plugins/remark-mdx-files.js +182 -0
- package/dist/mdx-plugins/remark-mdx-mermaid.d.ts +2 -0
- package/dist/mdx-plugins/remark-mdx-mermaid.js +28 -0
- package/dist/mdx-plugins/remark-npm.d.ts +2 -0
- package/dist/mdx-plugins/remark-npm.js +76 -0
- package/dist/mdx-plugins/remark-steps.d.ts +2 -0
- package/dist/mdx-plugins/remark-steps.js +93 -0
- package/dist/mdx-plugins/remark-structure.d.ts +2 -0
- package/dist/mdx-plugins/remark-structure.js +118 -0
- package/dist/mdx-plugins/stringifier.d.ts +2 -0
- package/dist/mdx-plugins/stringifier.js +91 -0
- package/dist/mdx-plugins/transformer-icon.d.ts +2 -0
- package/dist/mdx-plugins/transformer-icon.js +145 -0
- package/dist/negotiation/index.d.ts +17 -0
- package/dist/negotiation/index.js +378 -0
- package/dist/page-tree/index.d.ts +3 -0
- package/dist/page-tree/index.js +2 -0
- package/dist/path-1H5VzYiT.js +75 -0
- package/dist/rehype-code-D-RFJb9W.d.ts +14 -0
- package/dist/rehype-code.core-BUwNuchP.js +548 -0
- package/dist/rehype-code.core-BjH1uHWj.d.ts +115 -0
- package/dist/rehype-toc-K51AGb5U.d.ts +43 -0
- package/dist/remark-admonition-BwTcmI_S.d.ts +20 -0
- package/dist/remark-code-tab-DE_4bdnu.d.ts +34 -0
- package/dist/remark-directive-admonition-BLiJ5l43.d.ts +27 -0
- package/dist/remark-feedback-block-BxtINXN-.d.ts +45 -0
- package/dist/remark-gfm-DpVfAX1x.d.ts +2 -0
- package/dist/remark-heading-DEIzTkU5.d.ts +33 -0
- package/dist/remark-image-BI2S9LOb.d.ts +57 -0
- package/dist/remark-llms-bD3WvU2V.d.ts +73 -0
- package/dist/remark-mdx-files-Buvxc-sa.d.ts +54 -0
- package/dist/remark-mdx-mermaid-C1bCHHc6.d.ts +15 -0
- package/dist/remark-npm-BbpvkJaT.d.ts +31 -0
- package/dist/remark-steps-DqVEo0iq.d.ts +23 -0
- package/dist/remark-structure-CnHwvNZr.d.ts +87 -0
- package/dist/remove-markdown-DfKNMl9w.js +40 -0
- package/dist/remove-undefined-CzMSKybq.js +24 -0
- package/dist/rolldown-runtime-DC62tzP2.js +33 -0
- package/dist/search/algolia.d.ts +2 -0
- package/dist/search/algolia.js +75 -0
- package/dist/search/client/algolia.d.ts +2 -0
- package/dist/search/client/algolia.js +53 -0
- package/dist/search/client/fetch.d.ts +2 -0
- package/dist/search/client/fetch.js +28 -0
- package/dist/search/client/flexsearch-static.d.ts +2 -0
- package/dist/search/client/flexsearch-static.js +42 -0
- package/dist/search/client/mixedbread.d.ts +2 -0
- package/dist/search/client/mixedbread.js +65 -0
- package/dist/search/client/orama-cloud-legacy.d.ts +2 -0
- package/dist/search/client/orama-cloud-legacy.js +84 -0
- package/dist/search/client/orama-cloud.d.ts +2 -0
- package/dist/search/client/orama-cloud.js +86 -0
- package/dist/search/client/orama-static.d.ts +2 -0
- package/dist/search/client/orama-static.js +75 -0
- package/dist/search/client.d.ts +2 -0
- package/dist/search/client.js +97 -0
- package/dist/search/flexsearch.d.ts +56 -0
- package/dist/search/flexsearch.js +128 -0
- package/dist/search/index.d.ts +2 -0
- package/dist/search/index.js +74 -0
- package/dist/search/mixedbread.d.ts +49 -0
- package/dist/search/mixedbread.js +77 -0
- package/dist/search/orama-cloud-legacy.d.ts +75 -0
- package/dist/search/orama-cloud-legacy.js +48 -0
- package/dist/search/orama-cloud.d.ts +75 -0
- package/dist/search/orama-cloud.js +50 -0
- package/dist/search/server.d.ts +2 -0
- package/dist/search/server.js +237 -0
- package/dist/server-CCqACwlF.d.ts +165 -0
- package/dist/server.browser.d.ts +13 -0
- package/dist/server.browser.js +22 -0
- package/dist/server.d.ts +42 -0
- package/dist/server.js +398 -0
- package/dist/source/client/index.d.ts +2 -0
- package/dist/source/client/index.js +37 -0
- package/dist/source/dynamic.d.ts +2 -0
- package/dist/source/dynamic.js +2 -0
- package/dist/source/index.d.ts +2 -0
- package/dist/source/index.js +5 -0
- package/dist/source/llms.d.ts +2 -0
- package/dist/source/llms.js +74 -0
- package/dist/source/plugins/lucide-icons.d.ts +11 -0
- package/dist/source/plugins/lucide-icons.js +21 -0
- package/dist/source/plugins/slugs.d.ts +2 -0
- package/dist/source/plugins/slugs.js +75 -0
- package/dist/source/plugins/status-badges.d.ts +50 -0
- package/dist/source/plugins/status-badges.js +52 -0
- package/dist/source/schema.d.ts +30 -0
- package/dist/source/schema.js +28 -0
- package/dist/stringifier-B_QUcUyo.d.ts +63 -0
- package/dist/toc-CtW5lwA1.d.ts +64 -0
- package/dist/toc.d.ts +2 -0
- package/dist/toc.js +245 -0
- package/dist/transformer-icon-DlrneIS3.d.ts +17 -0
- package/dist/types-D89QoQR-.d.ts +4 -0
- package/dist/url-BVHvi3_K.js +29 -0
- package/dist/util-BDsqOxh3.d.ts +6 -0
- package/dist/util-DjBr9b3w.js +8 -0
- package/dist/utils/use-media-query.d.ts +4 -0
- package/dist/utils/use-media-query.js +20 -0
- package/dist/utils/use-on-change.d.ts +9 -0
- package/dist/utils/use-on-change.js +17 -0
- package/dist/utils-Bvy3V-fv.js +59 -0
- package/dist/utils-Cgs-6U-z.js +39 -0
- package/dist/utils-DEVq3cEC.js +151 -0
- package/dist/utils-Yx0IL9eW.js +48 -0
- package/package.json +251 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { a as Separator$1, n as Item$1, t as Folder$1 } from "../../definitions-CFOhwE1k.js";
|
|
2
|
+
import { x as LoaderPlugin } from "../../index-DIwKCYOz.js";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
//#region src/source/plugins/status-badges.d.ts
|
|
5
|
+
interface Item extends Item$1 {
|
|
6
|
+
/**
|
|
7
|
+
* Status badge to display in the sidebar (e.g., "new", "beta", "deprecated", "experimental").
|
|
8
|
+
*/
|
|
9
|
+
status?: string;
|
|
10
|
+
}
|
|
11
|
+
interface Folder extends Omit<Folder$1, 'children' | 'index'> {
|
|
12
|
+
index?: Item;
|
|
13
|
+
children: Node[];
|
|
14
|
+
}
|
|
15
|
+
type Separator = Separator$1;
|
|
16
|
+
type Node = Item | Folder | Separator;
|
|
17
|
+
/**
|
|
18
|
+
* Plugin to add status badges to pages in the sidebar.
|
|
19
|
+
*
|
|
20
|
+
* This reads the `status` field from page frontmatter and adds it to the page tree item.
|
|
21
|
+
* Define the `renderBadge` option to render it.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* import { loader } from '@vezham/docs-core/source';
|
|
26
|
+
* import { statusBadgesPlugin } from '@vezham/docs-core/source/status-badges';
|
|
27
|
+
*
|
|
28
|
+
* export const source = loader({
|
|
29
|
+
* plugins: [
|
|
30
|
+
* statusBadgesPlugin({
|
|
31
|
+
* renderBadge: (status) => <span>{status}</span>,
|
|
32
|
+
* }),
|
|
33
|
+
* ],
|
|
34
|
+
* // ...
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* Then in your frontmatter:
|
|
39
|
+
* ```yaml
|
|
40
|
+
* ---
|
|
41
|
+
* title: My Page
|
|
42
|
+
* status: new
|
|
43
|
+
* ---
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
declare function statusBadgesPlugin(options?: {
|
|
47
|
+
renderBadge?: (status: string) => ReactNode;
|
|
48
|
+
}): LoaderPlugin;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { Folder, Item, Node, Separator, statusBadgesPlugin };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
//#region src/source/plugins/status-badges.tsx
|
|
3
|
+
/**
|
|
4
|
+
* Plugin to add status badges to pages in the sidebar.
|
|
5
|
+
*
|
|
6
|
+
* This reads the `status` field from page frontmatter and adds it to the page tree item.
|
|
7
|
+
* Define the `renderBadge` option to render it.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { loader } from '@vezham/docs-core/source';
|
|
12
|
+
* import { statusBadgesPlugin } from '@vezham/docs-core/source/status-badges';
|
|
13
|
+
*
|
|
14
|
+
* export const source = loader({
|
|
15
|
+
* plugins: [
|
|
16
|
+
* statusBadgesPlugin({
|
|
17
|
+
* renderBadge: (status) => <span>{status}</span>,
|
|
18
|
+
* }),
|
|
19
|
+
* ],
|
|
20
|
+
* // ...
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Then in your frontmatter:
|
|
25
|
+
* ```yaml
|
|
26
|
+
* ---
|
|
27
|
+
* title: My Page
|
|
28
|
+
* status: new
|
|
29
|
+
* ---
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function statusBadgesPlugin(options = {}) {
|
|
33
|
+
const { renderBadge = (status) => /* @__PURE__ */ jsx("span", {
|
|
34
|
+
"data-status": status,
|
|
35
|
+
children: status
|
|
36
|
+
}) } = options;
|
|
37
|
+
return {
|
|
38
|
+
name: "fumadocs:status-badges",
|
|
39
|
+
transformPageTree: { file(node, filePath) {
|
|
40
|
+
if (!filePath) return node;
|
|
41
|
+
const file = this.storage.read(filePath);
|
|
42
|
+
if (file?.format === "page" && "status" in file.data && typeof file.data.status === "string") {
|
|
43
|
+
const status = file.data.status;
|
|
44
|
+
node.name = /* @__PURE__ */ jsxs(Fragment, { children: [node.name, renderBadge(status)] });
|
|
45
|
+
node.status = status;
|
|
46
|
+
}
|
|
47
|
+
return node;
|
|
48
|
+
} }
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { statusBadgesPlugin };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/source/schema.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Zod 4 schema
|
|
5
|
+
*/
|
|
6
|
+
declare const metaSchema: z.ZodObject<{
|
|
7
|
+
title: z.ZodOptional<z.ZodString>;
|
|
8
|
+
pages: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
9
|
+
pagesIndex: z.ZodOptional<z.ZodString>;
|
|
10
|
+
description: z.ZodOptional<z.ZodString>;
|
|
11
|
+
root: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
12
|
+
defaultOpen: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
collapsible: z.ZodOptional<z.ZodBoolean>;
|
|
14
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
type _JSONType = number | boolean | string | null | _JSONType[] | {
|
|
17
|
+
[key: string]: _JSONType;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Zod 4 schema
|
|
21
|
+
*/
|
|
22
|
+
declare const pageSchema: z.ZodObject<{
|
|
23
|
+
title: z.ZodString;
|
|
24
|
+
description: z.ZodOptional<z.ZodString>;
|
|
25
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
26
|
+
full: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
+
_openapi: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<_JSONType, _JSONType>>>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { _JSONType, metaSchema, pageSchema };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/source/schema.ts
|
|
3
|
+
/**
|
|
4
|
+
* Zod 4 schema
|
|
5
|
+
*/
|
|
6
|
+
const metaSchema = z.object({
|
|
7
|
+
title: z.string().optional(),
|
|
8
|
+
pages: z.array(z.string()).optional(),
|
|
9
|
+
/** specify a index page for folder */
|
|
10
|
+
pagesIndex: z.string().optional(),
|
|
11
|
+
description: z.string().optional(),
|
|
12
|
+
root: z.union([z.boolean(), z.string()]).optional(),
|
|
13
|
+
defaultOpen: z.boolean().optional(),
|
|
14
|
+
collapsible: z.boolean().optional(),
|
|
15
|
+
icon: z.string().optional()
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Zod 4 schema
|
|
19
|
+
*/
|
|
20
|
+
const pageSchema = z.object({
|
|
21
|
+
title: z.string(),
|
|
22
|
+
description: z.string().optional(),
|
|
23
|
+
icon: z.string().optional(),
|
|
24
|
+
full: z.boolean().optional(),
|
|
25
|
+
_openapi: z.record(z.string(), z.custom()).optional()
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
export { metaSchema, pageSchema };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { MdxJsxAttribute, MdxJsxExpressionAttribute, MdxJsxFlowElement, MdxJsxTextElement } from "mdast-util-mdx";
|
|
2
|
+
import { Info, Options, State } from "mdast-util-to-markdown";
|
|
3
|
+
import { Processor } from "unified";
|
|
4
|
+
import { Nodes, Parents } from "mdast";
|
|
5
|
+
//#region src/mdx-plugins/stringifier.d.ts
|
|
6
|
+
declare module 'mdast' {
|
|
7
|
+
interface Data {
|
|
8
|
+
/**
|
|
9
|
+
* [Fumadocs: stringify] Extra info for stringifying the node:
|
|
10
|
+
* - `children-only`: only stringify its children.
|
|
11
|
+
* - `{ node }`: stringify as another node.
|
|
12
|
+
* - `{ text }`: the stringified form of node.
|
|
13
|
+
*/
|
|
14
|
+
_stringify?: 'children-only' | {
|
|
15
|
+
node: Nodes;
|
|
16
|
+
} | {
|
|
17
|
+
text: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
type Stringifier<Context> = ((this: Processor, node: Nodes, ctx: Context) => string) | ((node: Nodes, ctx: Context) => string);
|
|
22
|
+
interface StringifyOptions<Context = undefined> extends Options {
|
|
23
|
+
/**
|
|
24
|
+
* Filter the elements to be included in the output:
|
|
25
|
+
*
|
|
26
|
+
* - `true`: include element & its children.
|
|
27
|
+
* - `children-only`: exclude element but keep its children.
|
|
28
|
+
* - `false`: exclude element & its children.
|
|
29
|
+
*
|
|
30
|
+
* Default:
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* filterElement = (node) => {
|
|
34
|
+
* switch (node.type) {
|
|
35
|
+
* case 'mdxJsxFlowElement':
|
|
36
|
+
* case 'mdxJsxTextElement':
|
|
37
|
+
* switch (node.name) {
|
|
38
|
+
* case 'File':
|
|
39
|
+
* case 'TypeTable':
|
|
40
|
+
* case 'Callout':
|
|
41
|
+
* case 'Card':
|
|
42
|
+
* return true;
|
|
43
|
+
* }
|
|
44
|
+
* return 'children-only';
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* return true;
|
|
48
|
+
* },
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
filterElement?: (node: Nodes) => boolean | 'children-only';
|
|
52
|
+
/**
|
|
53
|
+
* Filter the attributes to stringify.
|
|
54
|
+
*/
|
|
55
|
+
filterMdxAttributes?: (node: MdxJsxFlowElement | MdxJsxTextElement, attribute: MdxJsxAttribute | MdxJsxExpressionAttribute) => boolean;
|
|
56
|
+
/**
|
|
57
|
+
* override default stringifier
|
|
58
|
+
*/
|
|
59
|
+
stringify?: (node: Nodes, parent: Parents | undefined, state: State, info: Info, ctx: Context) => string | undefined;
|
|
60
|
+
}
|
|
61
|
+
declare function defaultStringifier<Context = undefined>(config?: StringifyOptions<Context>): Stringifier<Context>;
|
|
62
|
+
//#endregion
|
|
63
|
+
export { StringifyOptions as n, defaultStringifier as r, Stringifier as t };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ComponentProps, ReactNode, RefObject } from "react";
|
|
2
|
+
//#region src/toc.d.ts
|
|
3
|
+
interface TOCItemType {
|
|
4
|
+
title: ReactNode;
|
|
5
|
+
url: string;
|
|
6
|
+
depth: number;
|
|
7
|
+
/** [remark-steps] the step number */
|
|
8
|
+
_step?: number;
|
|
9
|
+
}
|
|
10
|
+
type TableOfContents = TOCItemType[];
|
|
11
|
+
interface TOCItemInfo {
|
|
12
|
+
id: string;
|
|
13
|
+
active: boolean;
|
|
14
|
+
/** last time the item is updated */
|
|
15
|
+
t: number;
|
|
16
|
+
/** currently active but not intersecting in viewport */
|
|
17
|
+
fallback: boolean;
|
|
18
|
+
original: TOCItemType;
|
|
19
|
+
}
|
|
20
|
+
interface AnchorProviderProps {
|
|
21
|
+
toc: TOCItemType[];
|
|
22
|
+
/**
|
|
23
|
+
* Only accept one active item at most
|
|
24
|
+
*
|
|
25
|
+
* @defaultValue false
|
|
26
|
+
*/
|
|
27
|
+
single?: boolean;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}
|
|
30
|
+
interface ScrollProviderProps {
|
|
31
|
+
/**
|
|
32
|
+
* Scroll into the view of container when active
|
|
33
|
+
*/
|
|
34
|
+
containerRef: RefObject<HTMLElement | null>;
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
}
|
|
37
|
+
/** Optional: add auto-scroll to TOC items. */
|
|
38
|
+
declare function ScrollProvider({ containerRef, children }: ScrollProviderProps): import("react").JSX.Element;
|
|
39
|
+
declare function AnchorProvider({ toc, single, children }: AnchorProviderProps): import("react").JSX.Element;
|
|
40
|
+
interface TOCItemProps extends ComponentProps<'a'> {
|
|
41
|
+
autoScroll?: boolean;
|
|
42
|
+
onActiveChange?: (v: boolean) => void;
|
|
43
|
+
}
|
|
44
|
+
declare function TOCItem({ ref, onActiveChange, autoScroll, ...props }: TOCItemProps): import("react").JSX.Element;
|
|
45
|
+
/** @returns static info object, useful for custom rendering logic */
|
|
46
|
+
declare function useTOC(): {
|
|
47
|
+
get(): TOCItemInfo[];
|
|
48
|
+
listen: (listener: ChangeListener) => void;
|
|
49
|
+
unlisten: (listener: ChangeListener) => void;
|
|
50
|
+
};
|
|
51
|
+
declare function useTOCListener(listener: ChangeListener): void;
|
|
52
|
+
declare function useTOCSelector<T>(select: (items: TOCItemInfo[]) => T, isEqual?: (a: T, b: T) => boolean): T;
|
|
53
|
+
/**
|
|
54
|
+
* The estimated active heading ID
|
|
55
|
+
*/
|
|
56
|
+
declare function useActiveAnchor(): string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* The id of visible anchors
|
|
59
|
+
*/
|
|
60
|
+
declare function useActiveAnchors(): string[];
|
|
61
|
+
declare function useItems(): TOCItemInfo[];
|
|
62
|
+
type ChangeListener = (items: TOCItemInfo[]) => void;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { TOCItem as a, TOCItemType as c, useActiveAnchors as d, useItems as f, useTOCSelector as h, ScrollProviderProps as i, TableOfContents as l, useTOCListener as m, AnchorProviderProps as n, TOCItemInfo as o, useTOC as p, ScrollProvider as r, TOCItemProps as s, AnchorProvider as t, useActiveAnchor as u };
|
package/dist/toc.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as TOCItem, c as TOCItemType, d as useActiveAnchors, f as useItems, h as useTOCSelector, i as ScrollProviderProps, l as TableOfContents, m as useTOCListener, n as AnchorProviderProps, o as TOCItemInfo, p as useTOC, r as ScrollProvider, s as TOCItemProps, t as AnchorProvider, u as useActiveAnchor } from "./toc-CtW5lwA1.js";
|
|
2
|
+
export { AnchorProvider, AnchorProviderProps, ScrollProvider, ScrollProviderProps, TOCItem, TOCItemInfo, TOCItemProps, TOCItemType, TableOfContents, useActiveAnchor, useActiveAnchors, useItems, useTOC, useTOCListener, useTOCSelector };
|
package/dist/toc.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as isEqualShallow } from "./is-equal-LdLqRs0o.js";
|
|
3
|
+
import { createContext, use, useEffect, useEffectEvent, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import scrollIntoView from "scroll-into-view-if-needed";
|
|
6
|
+
//#region src/utils/merge-refs.ts
|
|
7
|
+
function mergeRefs(...refs) {
|
|
8
|
+
return (value) => {
|
|
9
|
+
refs.forEach((ref) => {
|
|
10
|
+
if (typeof ref === "function") ref(value);
|
|
11
|
+
else if (ref != null) ref.current = value;
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/toc.tsx
|
|
17
|
+
const ObserverContext = createContext(null);
|
|
18
|
+
const ScrollContext = createContext(null);
|
|
19
|
+
/** Optional: add auto-scroll to TOC items. */
|
|
20
|
+
function ScrollProvider({ containerRef, children }) {
|
|
21
|
+
return /* @__PURE__ */ jsx(ScrollContext, {
|
|
22
|
+
value: containerRef,
|
|
23
|
+
children
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function AnchorProvider({ toc, single = false, children }) {
|
|
27
|
+
const observer = useMemo(() => new Observer(), []);
|
|
28
|
+
observer.single = single;
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
observer.setItems(toc);
|
|
31
|
+
}, [observer, toc]);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
observer.watch({ threshold: .9 });
|
|
34
|
+
return () => observer.unwatch();
|
|
35
|
+
}, [observer]);
|
|
36
|
+
return /* @__PURE__ */ jsx(ObserverContext, {
|
|
37
|
+
value: observer,
|
|
38
|
+
children
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function TOCItem({ ref, onActiveChange = () => null, autoScroll = true, ...props }) {
|
|
42
|
+
const id = props.href ? getItemId(props.href) : null;
|
|
43
|
+
const containerRef = use(ScrollContext);
|
|
44
|
+
const anchorRef = useRef(null);
|
|
45
|
+
const isInitialRef = useRef(true);
|
|
46
|
+
const observer = useObserver();
|
|
47
|
+
const [active, setActive] = useState(() => observer.items.some((item) => item.id === id && item.active));
|
|
48
|
+
const onUpdate = useEffectEvent((items, initial) => {
|
|
49
|
+
const itemData = id ? items.find((item) => item.id === id) : null;
|
|
50
|
+
if (!itemData) return;
|
|
51
|
+
if (itemData.active !== active) {
|
|
52
|
+
setActive(itemData.active);
|
|
53
|
+
onActiveChange(itemData.active);
|
|
54
|
+
}
|
|
55
|
+
const anchor = anchorRef.current;
|
|
56
|
+
const container = containerRef?.current;
|
|
57
|
+
if (!autoScroll || !anchor || !container) return;
|
|
58
|
+
let lastActive;
|
|
59
|
+
for (const item of items) {
|
|
60
|
+
if (!item.active) continue;
|
|
61
|
+
if (!lastActive || lastActive.t < item.t) lastActive = item;
|
|
62
|
+
}
|
|
63
|
+
if (lastActive?.id === id) scrollIntoView(anchor, {
|
|
64
|
+
behavior: initial ? "instant" : "smooth",
|
|
65
|
+
block: "center",
|
|
66
|
+
inline: "center",
|
|
67
|
+
scrollMode: "always",
|
|
68
|
+
boundary: container
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (autoScroll) onUpdate(observer.items, isInitialRef.current);
|
|
73
|
+
isInitialRef.current = false;
|
|
74
|
+
}, [observer, autoScroll]);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const listener = (items) => onUpdate(items, false);
|
|
77
|
+
observer.listen(listener);
|
|
78
|
+
return () => observer.unlisten(listener);
|
|
79
|
+
}, [observer]);
|
|
80
|
+
return /* @__PURE__ */ jsx("a", {
|
|
81
|
+
ref: mergeRefs(anchorRef, ref),
|
|
82
|
+
"data-active": active,
|
|
83
|
+
...props
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function useObserver() {
|
|
87
|
+
const observer = use(ObserverContext);
|
|
88
|
+
if (!observer) throw new Error(`Component must be used under the <AnchorProvider /> component.`);
|
|
89
|
+
return observer;
|
|
90
|
+
}
|
|
91
|
+
/** @returns static info object, useful for custom rendering logic */
|
|
92
|
+
function useTOC() {
|
|
93
|
+
const observer = useObserver();
|
|
94
|
+
return useMemo(() => ({
|
|
95
|
+
get() {
|
|
96
|
+
return observer.items;
|
|
97
|
+
},
|
|
98
|
+
listen: observer.listen.bind(observer),
|
|
99
|
+
unlisten: observer.unlisten.bind(observer)
|
|
100
|
+
}), [observer]);
|
|
101
|
+
}
|
|
102
|
+
function useTOCListener(listener) {
|
|
103
|
+
const observer = useObserver();
|
|
104
|
+
const callback = useEffectEvent(listener);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
observer.listen(callback);
|
|
107
|
+
return () => observer.unlisten(callback);
|
|
108
|
+
}, [observer]);
|
|
109
|
+
}
|
|
110
|
+
function useTOCSelector(select, isEqual = isEqualShallow) {
|
|
111
|
+
const observer = useObserver();
|
|
112
|
+
const [value, setValue] = useState(() => select(observer.items));
|
|
113
|
+
useTOCListener((items) => {
|
|
114
|
+
const next = select(items);
|
|
115
|
+
if (!isEqual(value, next)) setValue(next);
|
|
116
|
+
});
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The estimated active heading ID
|
|
121
|
+
*/
|
|
122
|
+
function useActiveAnchor() {
|
|
123
|
+
return useTOCSelector((items) => {
|
|
124
|
+
let out;
|
|
125
|
+
for (const item of items) {
|
|
126
|
+
if (!item.active) continue;
|
|
127
|
+
if (!out || item.t > out.t) out = item;
|
|
128
|
+
}
|
|
129
|
+
return out?.id;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The id of visible anchors
|
|
134
|
+
*/
|
|
135
|
+
function useActiveAnchors() {
|
|
136
|
+
return useTOCSelector((items) => {
|
|
137
|
+
const out = [];
|
|
138
|
+
for (const item of items) if (item.active) out.push(item.id);
|
|
139
|
+
return out;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function useItems() {
|
|
143
|
+
return useTOCSelector((items) => items);
|
|
144
|
+
}
|
|
145
|
+
function getItemId(url) {
|
|
146
|
+
if (url.startsWith("#")) return url.slice(1);
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
var Observer = class {
|
|
150
|
+
constructor() {
|
|
151
|
+
this.items = [];
|
|
152
|
+
this.single = false;
|
|
153
|
+
this.observer = null;
|
|
154
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
155
|
+
}
|
|
156
|
+
listen(listener) {
|
|
157
|
+
this.listeners.add(listener);
|
|
158
|
+
}
|
|
159
|
+
unlisten(listener) {
|
|
160
|
+
this.listeners.delete(listener);
|
|
161
|
+
}
|
|
162
|
+
setItems(newItems) {
|
|
163
|
+
const observer = this.observer;
|
|
164
|
+
if (observer) for (const item of this.items) {
|
|
165
|
+
const element = document.getElementById(item.id);
|
|
166
|
+
if (!element) continue;
|
|
167
|
+
observer.unobserve(element);
|
|
168
|
+
}
|
|
169
|
+
const next = [];
|
|
170
|
+
for (const item of newItems) {
|
|
171
|
+
const id = getItemId(item.url);
|
|
172
|
+
if (!id) continue;
|
|
173
|
+
next.push({
|
|
174
|
+
id,
|
|
175
|
+
active: false,
|
|
176
|
+
fallback: false,
|
|
177
|
+
t: 0,
|
|
178
|
+
original: item
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
this.update(next);
|
|
182
|
+
this.observeItems();
|
|
183
|
+
}
|
|
184
|
+
watch(options) {
|
|
185
|
+
if (this.observer) return;
|
|
186
|
+
this.observer = new IntersectionObserver(this.callback.bind(this), options);
|
|
187
|
+
this.observeItems();
|
|
188
|
+
}
|
|
189
|
+
unwatch() {
|
|
190
|
+
this.observer?.disconnect();
|
|
191
|
+
this.observer = null;
|
|
192
|
+
}
|
|
193
|
+
callback(entries) {
|
|
194
|
+
if (entries.length === 0) return;
|
|
195
|
+
let hasActive = false;
|
|
196
|
+
const updated = this.items.map((item) => {
|
|
197
|
+
const entry = entries.find((entry) => entry.target.id === item.id);
|
|
198
|
+
let active = entry ? entry.isIntersecting : item.active && !item.fallback;
|
|
199
|
+
if (this.single && hasActive) active = false;
|
|
200
|
+
if (item.active !== active) item = {
|
|
201
|
+
...item,
|
|
202
|
+
t: Date.now(),
|
|
203
|
+
active,
|
|
204
|
+
fallback: false
|
|
205
|
+
};
|
|
206
|
+
if (active) hasActive = true;
|
|
207
|
+
return item;
|
|
208
|
+
});
|
|
209
|
+
if (!hasActive && entries[0].rootBounds) {
|
|
210
|
+
const viewTop = entries[0].rootBounds.top;
|
|
211
|
+
let min = Number.MAX_VALUE;
|
|
212
|
+
let fallbackIdx = -1;
|
|
213
|
+
for (let i = 0; i < updated.length; i++) {
|
|
214
|
+
const element = document.getElementById(updated[i].id);
|
|
215
|
+
if (!element) continue;
|
|
216
|
+
const d = Math.abs(viewTop - element.getBoundingClientRect().top);
|
|
217
|
+
if (d < min) {
|
|
218
|
+
fallbackIdx = i;
|
|
219
|
+
min = d;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (fallbackIdx !== -1) updated[fallbackIdx] = {
|
|
223
|
+
...updated[fallbackIdx],
|
|
224
|
+
active: true,
|
|
225
|
+
fallback: true,
|
|
226
|
+
t: Date.now()
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
this.update(updated);
|
|
230
|
+
}
|
|
231
|
+
observeItems() {
|
|
232
|
+
if (!this.observer) return;
|
|
233
|
+
for (const item of this.items) {
|
|
234
|
+
const element = document.getElementById(item.id);
|
|
235
|
+
if (!element) continue;
|
|
236
|
+
this.observer.observe(element);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
update(next) {
|
|
240
|
+
this.items = next;
|
|
241
|
+
for (const listener of this.listeners) listener(next);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
//#endregion
|
|
245
|
+
export { AnchorProvider, ScrollProvider, TOCItem, useActiveAnchor, useActiveAnchors, useItems, useTOC, useTOCListener, useTOCSelector };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ShikiTransformer } from "shiki";
|
|
2
|
+
//#region src/mdx-plugins/transformer-icon.d.ts
|
|
3
|
+
type CodeBlockIcon = {
|
|
4
|
+
viewBox: string;
|
|
5
|
+
fill: string;
|
|
6
|
+
d: string;
|
|
7
|
+
} | string;
|
|
8
|
+
interface IconOptions {
|
|
9
|
+
shortcuts?: Record<string, string>;
|
|
10
|
+
extend?: Record<string, CodeBlockIcon>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Inject icons to `icon` property (as HTML)
|
|
14
|
+
*/
|
|
15
|
+
declare function transformerIcon(options?: IconOptions): ShikiTransformer;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { IconOptions as n, transformerIcon as r, CodeBlockIcon as t };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/utils/url.tsx
|
|
2
|
+
/**
|
|
3
|
+
* The base path (Vite)
|
|
4
|
+
*/
|
|
5
|
+
const BASE_PATH = typeof import.meta.env !== "undefined" && typeof import.meta.env.BASE_URL === "string" ? import.meta.env.BASE_URL : "/";
|
|
6
|
+
function join(...paths) {
|
|
7
|
+
let out = "";
|
|
8
|
+
for (let p of paths) {
|
|
9
|
+
if (out.length > 0) {
|
|
10
|
+
if (p.startsWith("/")) p = p.slice(1);
|
|
11
|
+
if (!out.endsWith("/")) out += "/";
|
|
12
|
+
}
|
|
13
|
+
out += p;
|
|
14
|
+
}
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* normalize URL into the Fumadocs standard form (`/slug-1/slug-2`).
|
|
19
|
+
*
|
|
20
|
+
* This includes URLs with trailing slashes.
|
|
21
|
+
*/
|
|
22
|
+
function normalizeUrl(url) {
|
|
23
|
+
if (url.startsWith("http://") || url.startsWith("https://")) return url;
|
|
24
|
+
if (!url.startsWith("/")) url = "/" + url;
|
|
25
|
+
if (url.length > 1 && url.endsWith("/")) url = url.slice(0, -1);
|
|
26
|
+
return url;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { join as n, normalizeUrl as r, BASE_PATH as t };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/content/mdx/util.ts
|
|
2
|
+
async function resolvePlugins(def, options = []) {
|
|
3
|
+
const list = (await Promise.all(def(Array.isArray(options) ? options : []))).filter((v) => v !== false);
|
|
4
|
+
if (typeof options === "function") return Promise.all(options(list));
|
|
5
|
+
return list;
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { resolvePlugins as t };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
//#region src/utils/use-media-query.ts
|
|
3
|
+
function useMediaQuery(query, disabled = false) {
|
|
4
|
+
const [isMatch, setMatch] = useState(null);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (disabled) return;
|
|
7
|
+
const mediaQueryList = window.matchMedia(query);
|
|
8
|
+
const handleChange = () => {
|
|
9
|
+
setMatch(mediaQueryList.matches);
|
|
10
|
+
};
|
|
11
|
+
handleChange();
|
|
12
|
+
mediaQueryList.addEventListener("change", handleChange);
|
|
13
|
+
return () => {
|
|
14
|
+
mediaQueryList.removeEventListener("change", handleChange);
|
|
15
|
+
};
|
|
16
|
+
}, [disabled, query]);
|
|
17
|
+
return isMatch;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { useMediaQuery };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/utils/use-on-change.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* @param value - state to watch
|
|
4
|
+
* @param onChange - when the state changed
|
|
5
|
+
* @param isUpdated - a function that determines if the state is updated
|
|
6
|
+
*/
|
|
7
|
+
declare function useOnChange<T>(value: T, onChange: (current: T, previous: T) => void, isUpdated?: (prev: T, current: T) => boolean): void;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { useOnChange };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { t as isEqualShallow } from "../is-equal-LdLqRs0o.js";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
//#region src/utils/use-on-change.ts
|
|
4
|
+
/**
|
|
5
|
+
* @param value - state to watch
|
|
6
|
+
* @param onChange - when the state changed
|
|
7
|
+
* @param isUpdated - a function that determines if the state is updated
|
|
8
|
+
*/
|
|
9
|
+
function useOnChange(value, onChange, isUpdated = (a, b) => !isEqualShallow(a, b)) {
|
|
10
|
+
const [prev, setPrev] = useState(value);
|
|
11
|
+
if (isUpdated(prev, value)) {
|
|
12
|
+
onChange(value, prev);
|
|
13
|
+
setPrev(value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { useOnChange };
|