fumadocs-core 12.5.5 → 13.0.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/dist/mdx-plugins/index.d.ts +16 -8
- package/dist/mdx-plugins/index.js +65 -3
- package/dist/toc.d.ts +15 -15
- package/dist/toc.js +76 -36
- package/package.json +5 -12
- package/dist/chunk-V6DBK6TW.js +0 -50
- package/dist/toc-internal.d.ts +0 -28
- package/dist/toc-internal.js +0 -65
|
@@ -26,13 +26,6 @@ type RehypeCodeOptions = RehypeShikiOptions & {
|
|
|
26
26
|
* Filter meta string before processing
|
|
27
27
|
*/
|
|
28
28
|
filterMetaString?: (metaString: string) => string;
|
|
29
|
-
/**
|
|
30
|
-
* Default language
|
|
31
|
-
*
|
|
32
|
-
* @defaultValue plaintext
|
|
33
|
-
* @deprecated Use `defaultLanguage` instead
|
|
34
|
-
*/
|
|
35
|
-
defaultLang?: string;
|
|
36
29
|
/**
|
|
37
30
|
* Add icon to code blocks
|
|
38
31
|
*/
|
|
@@ -85,4 +78,19 @@ interface RemarkHeadingOptions {
|
|
|
85
78
|
*/
|
|
86
79
|
declare function remarkHeading({ slug: defaultSlug, customId, }?: RemarkHeadingOptions): Transformer<Root$1, Root$1>;
|
|
87
80
|
|
|
88
|
-
|
|
81
|
+
interface RemarkAdmonitionOptions {
|
|
82
|
+
tag?: string;
|
|
83
|
+
types?: string[];
|
|
84
|
+
/**
|
|
85
|
+
* Map type to another type
|
|
86
|
+
*/
|
|
87
|
+
typeMap?: Record<string, string>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Remark Plugin to support Admonition syntax
|
|
91
|
+
*
|
|
92
|
+
* Useful when Migrating from Docusaurus
|
|
93
|
+
*/
|
|
94
|
+
declare function remarkAdmonition(options?: RemarkAdmonitionOptions): Transformer<Root$1, Root$1>;
|
|
95
|
+
|
|
96
|
+
export { type CodeBlockIcon, type RehypeCodeOptions, type RemarkAdmonitionOptions, type RemarkHeadingOptions, type RemarkImageOptions, rehypeCode, rehypeCodeDefaultOptions, remarkAdmonition, remarkHeading, remarkImage, transformerIcon };
|
|
@@ -241,9 +241,6 @@ function rehypeCode(options = {}) {
|
|
|
241
241
|
if (codeOptions.tab !== false) {
|
|
242
242
|
codeOptions.transformers = [...codeOptions.transformers, transformerTab()];
|
|
243
243
|
}
|
|
244
|
-
if (codeOptions.defaultLang) {
|
|
245
|
-
codeOptions.defaultLanguage = codeOptions.defaultLang;
|
|
246
|
-
}
|
|
247
244
|
return rehypeShiki.call(this, codeOptions);
|
|
248
245
|
}
|
|
249
246
|
function transformerTab() {
|
|
@@ -406,9 +403,74 @@ function structure(content, remarkPlugins = [], options = {}) {
|
|
|
406
403
|
const result = remark().use(remarkGfm).use(remarkMdx).use(remarkPlugins).use(remarkStructure, options).processSync(content);
|
|
407
404
|
return result.data.structuredData;
|
|
408
405
|
}
|
|
406
|
+
|
|
407
|
+
// src/mdx-plugins/remark-admonition.ts
|
|
408
|
+
import { visit as visit3 } from "unist-util-visit";
|
|
409
|
+
function remarkAdmonition(options = {}) {
|
|
410
|
+
const types = options.types ?? ["warn", "info", "error"];
|
|
411
|
+
const tag = options.tag ?? ":::";
|
|
412
|
+
const typeMap = options.typeMap ?? {
|
|
413
|
+
note: "info",
|
|
414
|
+
tip: "info",
|
|
415
|
+
warning: "warn",
|
|
416
|
+
danger: "error"
|
|
417
|
+
};
|
|
418
|
+
function replaceNodes(nodes) {
|
|
419
|
+
if (nodes.length === 0) return nodes;
|
|
420
|
+
let open = -1, end = -1;
|
|
421
|
+
const attributes = [];
|
|
422
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
423
|
+
if (nodes[i].type !== "paragraph") continue;
|
|
424
|
+
const text = flattenNode(nodes[i]);
|
|
425
|
+
const start = types.find((type) => text.startsWith(`${tag}${type}`));
|
|
426
|
+
if (start) {
|
|
427
|
+
if (open !== -1) throw new Error("Nested callout is not supported");
|
|
428
|
+
open = i;
|
|
429
|
+
attributes.push({
|
|
430
|
+
type: "mdxJsxAttribute",
|
|
431
|
+
name: "type",
|
|
432
|
+
value: start in typeMap ? typeMap[start] : start
|
|
433
|
+
});
|
|
434
|
+
const rest = text.slice(`${tag}${start}`.length);
|
|
435
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
436
|
+
attributes.push({
|
|
437
|
+
type: "mdxJsxAttribute",
|
|
438
|
+
name: "title",
|
|
439
|
+
value: rest.slice(1, -1)
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (open !== -1 && text === tag) {
|
|
444
|
+
end = i;
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (open === -1 || end === -1) return nodes;
|
|
449
|
+
return [
|
|
450
|
+
...nodes.slice(0, open),
|
|
451
|
+
{
|
|
452
|
+
type: "mdxJsxFlowElement",
|
|
453
|
+
name: "Callout",
|
|
454
|
+
attributes,
|
|
455
|
+
children: nodes.slice(open + 1, end)
|
|
456
|
+
},
|
|
457
|
+
...replaceNodes(nodes.slice(end + 1))
|
|
458
|
+
];
|
|
459
|
+
}
|
|
460
|
+
return (tree) => {
|
|
461
|
+
visit3(tree, (node) => {
|
|
462
|
+
if (!("children" in node)) return "skip";
|
|
463
|
+
const result = replaceNodes(node.children);
|
|
464
|
+
if (result === node.children) return;
|
|
465
|
+
node.children = result;
|
|
466
|
+
return "skip";
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
}
|
|
409
470
|
export {
|
|
410
471
|
rehypeCode,
|
|
411
472
|
rehypeCodeDefaultOptions,
|
|
473
|
+
remarkAdmonition,
|
|
412
474
|
default2 as remarkGfm,
|
|
413
475
|
remarkHeading,
|
|
414
476
|
remarkImage,
|
package/dist/toc.d.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ReactNode, RefObject, AnchorHTMLAttributes } from 'react';
|
|
3
3
|
import { T as TableOfContents } from './get-toc-CM4X3hbw.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The id of active anchor (doesn't include hash)
|
|
7
|
+
*/
|
|
8
|
+
declare function useActiveAnchor(): string | undefined;
|
|
9
|
+
interface AnchorProviderProps {
|
|
7
10
|
toc: TableOfContents;
|
|
11
|
+
children?: ReactNode;
|
|
8
12
|
}
|
|
9
|
-
|
|
10
|
-
interface TOCScrollProvider {
|
|
13
|
+
interface ScrollProviderProps {
|
|
11
14
|
/**
|
|
12
15
|
* Scroll into the view of container when active
|
|
13
16
|
*/
|
|
14
|
-
containerRef
|
|
15
|
-
|
|
16
|
-
children: ReactNode;
|
|
17
|
+
containerRef: RefObject<HTMLElement>;
|
|
18
|
+
children?: ReactNode;
|
|
17
19
|
}
|
|
18
|
-
declare function
|
|
19
|
-
|
|
20
|
+
declare function ScrollProvider({ containerRef, children, }: ScrollProviderProps): React.ReactElement;
|
|
21
|
+
declare function AnchorProvider({ toc, children, }: AnchorProviderProps): React.ReactElement;
|
|
22
|
+
interface TOCItemProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
|
|
20
23
|
href: string;
|
|
21
|
-
|
|
22
|
-
* Scroll into the view of container when active
|
|
23
|
-
*/
|
|
24
|
-
containerRef?: RefObject<HTMLElement>;
|
|
24
|
+
onActiveChange?: (v: boolean) => void;
|
|
25
25
|
}
|
|
26
26
|
declare const TOCItem: react.ForwardRefExoticComponent<TOCItemProps & react.RefAttributes<HTMLAnchorElement>>;
|
|
27
27
|
|
|
28
|
-
export {
|
|
28
|
+
export { AnchorProvider, type AnchorProviderProps, ScrollProvider, type ScrollProviderProps, TOCItem, type TOCItemProps, useActiveAnchor };
|
package/dist/toc.js
CHANGED
|
@@ -1,53 +1,92 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "./chunk-V6DBK6TW.js";
|
|
2
|
+
useOnChange
|
|
3
|
+
} from "./chunk-KGMG4N3Y.js";
|
|
5
4
|
import "./chunk-MLKGABMK.js";
|
|
6
5
|
|
|
7
6
|
// src/toc.tsx
|
|
8
|
-
import {
|
|
9
|
-
createContext,
|
|
10
|
-
forwardRef,
|
|
11
|
-
useContext,
|
|
12
|
-
useEffect,
|
|
13
|
-
useMemo,
|
|
14
|
-
useRef
|
|
15
|
-
} from "react";
|
|
7
|
+
import { createContext, forwardRef, useContext, useMemo, useRef } from "react";
|
|
16
8
|
import scrollIntoView from "scroll-into-view-if-needed";
|
|
9
|
+
|
|
10
|
+
// src/utils/merge-refs.ts
|
|
11
|
+
function mergeRefs(...refs) {
|
|
12
|
+
return (value) => {
|
|
13
|
+
refs.forEach((ref) => {
|
|
14
|
+
if (typeof ref === "function") {
|
|
15
|
+
ref(value);
|
|
16
|
+
} else if (ref !== null) {
|
|
17
|
+
ref.current = value;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/utils/use-anchor-observer.ts
|
|
24
|
+
import { useEffect, useState } from "react";
|
|
25
|
+
function useAnchorObserver(watch) {
|
|
26
|
+
const [activeAnchor, setActiveAnchor] = useState();
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const observer = new IntersectionObserver(
|
|
29
|
+
(entries) => {
|
|
30
|
+
setActiveAnchor((f) => {
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
const aboveHalf = window.innerHeight / 2 > entry.boundingClientRect.y;
|
|
33
|
+
const active = aboveHalf && entry.isIntersecting;
|
|
34
|
+
if (active) {
|
|
35
|
+
return entry.target.id;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return f ?? watch[0];
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
{ rootMargin: `0% 0% -80% 0%` }
|
|
42
|
+
);
|
|
43
|
+
for (const heading of watch) {
|
|
44
|
+
const element = document.getElementById(heading);
|
|
45
|
+
if (element !== null) {
|
|
46
|
+
observer.observe(element);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return () => {
|
|
50
|
+
observer.disconnect();
|
|
51
|
+
};
|
|
52
|
+
}, [watch]);
|
|
53
|
+
return activeAnchor;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/toc.tsx
|
|
17
57
|
import { jsx } from "react/jsx-runtime";
|
|
18
|
-
var ActiveAnchorContext = createContext(
|
|
19
|
-
var
|
|
20
|
-
|
|
21
|
-
return
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
({ toc, ...props }, ref) => {
|
|
25
|
-
const containerRef = useRef(null);
|
|
26
|
-
const mergedRef = mergeRefs(containerRef, ref);
|
|
27
|
-
return /* @__PURE__ */ jsx("div", { ref: mergedRef, ...props, children: /* @__PURE__ */ jsx(TOCScrollProvider, { toc, containerRef, children: props.children }) });
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
TOCProvider.displayName = "TOCProvider";
|
|
31
|
-
function TOCScrollProvider({
|
|
32
|
-
toc,
|
|
58
|
+
var ActiveAnchorContext = createContext(void 0);
|
|
59
|
+
var ScrollContext = createContext({ current: null });
|
|
60
|
+
function useActiveAnchor() {
|
|
61
|
+
return useContext(ActiveAnchorContext);
|
|
62
|
+
}
|
|
63
|
+
function ScrollProvider({
|
|
33
64
|
containerRef,
|
|
34
65
|
children
|
|
66
|
+
}) {
|
|
67
|
+
return /* @__PURE__ */ jsx(ScrollContext.Provider, { value: containerRef, children });
|
|
68
|
+
}
|
|
69
|
+
function AnchorProvider({
|
|
70
|
+
toc,
|
|
71
|
+
children
|
|
35
72
|
}) {
|
|
36
73
|
const headings = useMemo(() => {
|
|
37
74
|
return toc.map((item) => item.url.split("#")[1]);
|
|
38
75
|
}, [toc]);
|
|
39
76
|
const activeAnchor = useAnchorObserver(headings);
|
|
40
|
-
return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, { value:
|
|
77
|
+
return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, { value: activeAnchor, children });
|
|
41
78
|
}
|
|
42
79
|
var TOCItem = forwardRef(
|
|
43
|
-
({
|
|
44
|
-
const
|
|
45
|
-
const
|
|
80
|
+
({ onActiveChange, ...props }, ref) => {
|
|
81
|
+
const containerRef = useContext(ScrollContext);
|
|
82
|
+
const activeAnchor = useActiveAnchor();
|
|
46
83
|
const anchorRef = useRef(null);
|
|
47
84
|
const mergedRef = mergeRefs(anchorRef, ref);
|
|
48
|
-
|
|
85
|
+
const isActive = activeAnchor === props.href.split("#")[1];
|
|
86
|
+
useOnChange(isActive, (v) => {
|
|
49
87
|
const element = anchorRef.current;
|
|
50
|
-
if (
|
|
88
|
+
if (!element) return;
|
|
89
|
+
if (v && containerRef.current) {
|
|
51
90
|
scrollIntoView(element, {
|
|
52
91
|
behavior: "smooth",
|
|
53
92
|
block: "center",
|
|
@@ -56,14 +95,15 @@ var TOCItem = forwardRef(
|
|
|
56
95
|
boundary: containerRef.current
|
|
57
96
|
});
|
|
58
97
|
}
|
|
59
|
-
|
|
60
|
-
|
|
98
|
+
onActiveChange?.(v);
|
|
99
|
+
});
|
|
100
|
+
return /* @__PURE__ */ jsx("a", { ref: mergedRef, "data-active": isActive, ...props, children: props.children });
|
|
61
101
|
}
|
|
62
102
|
);
|
|
63
103
|
TOCItem.displayName = "TOCItem";
|
|
64
104
|
export {
|
|
105
|
+
AnchorProvider,
|
|
106
|
+
ScrollProvider,
|
|
65
107
|
TOCItem,
|
|
66
|
-
TOCProvider,
|
|
67
|
-
TOCScrollProvider,
|
|
68
108
|
useActiveAnchor
|
|
69
109
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "The library for building a documentation website in Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -24,10 +24,6 @@
|
|
|
24
24
|
"import": "./dist/toc.js",
|
|
25
25
|
"types": "./dist/toc.d.ts"
|
|
26
26
|
},
|
|
27
|
-
"./toc-internal": {
|
|
28
|
-
"import": "./dist/toc-internal.js",
|
|
29
|
-
"types": "./dist/toc-internal.d.ts"
|
|
30
|
-
},
|
|
31
27
|
"./search/client": {
|
|
32
28
|
"import": "./dist/search/client.js",
|
|
33
29
|
"types": "./dist/search/client.d.ts"
|
|
@@ -84,9 +80,6 @@
|
|
|
84
80
|
"toc": [
|
|
85
81
|
"./dist/toc.d.ts"
|
|
86
82
|
],
|
|
87
|
-
"toc-internal": [
|
|
88
|
-
"./dist/toc-internal.d.ts"
|
|
89
|
-
],
|
|
90
83
|
"search/client": [
|
|
91
84
|
"./dist/search/client.d.ts"
|
|
92
85
|
],
|
|
@@ -127,8 +120,8 @@
|
|
|
127
120
|
],
|
|
128
121
|
"dependencies": {
|
|
129
122
|
"@formatjs/intl-localematcher": "^0.5.4",
|
|
130
|
-
"@shikijs/rehype": "^1.11.
|
|
131
|
-
"@shikijs/transformers": "^1.11.
|
|
123
|
+
"@shikijs/rehype": "^1.11.1",
|
|
124
|
+
"@shikijs/transformers": "^1.11.1",
|
|
132
125
|
"flexsearch": "0.7.21",
|
|
133
126
|
"github-slugger": "^2.0.0",
|
|
134
127
|
"negotiator": "^0.6.3",
|
|
@@ -138,7 +131,7 @@
|
|
|
138
131
|
"remark-gfm": "^4.0.0",
|
|
139
132
|
"remark-mdx": "^3.0.1",
|
|
140
133
|
"scroll-into-view-if-needed": "^3.1.0",
|
|
141
|
-
"shiki": "^1.11.
|
|
134
|
+
"shiki": "^1.11.1",
|
|
142
135
|
"swr": "^2.2.5",
|
|
143
136
|
"unist-util-visit": "^5.0.0"
|
|
144
137
|
},
|
|
@@ -150,7 +143,7 @@
|
|
|
150
143
|
"@types/hast": "^3.0.4",
|
|
151
144
|
"@types/mdast": "^4.0.3",
|
|
152
145
|
"@types/negotiator": "^0.6.3",
|
|
153
|
-
"@types/node": "20.14.
|
|
146
|
+
"@types/node": "20.14.12",
|
|
154
147
|
"@types/react": "^18.3.3",
|
|
155
148
|
"@types/react-dom": "^18.3.0",
|
|
156
149
|
"algoliasearch": "^4.24.0",
|
package/dist/chunk-V6DBK6TW.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// src/utils/merge-refs.ts
|
|
2
|
-
function mergeRefs(...refs) {
|
|
3
|
-
return (value) => {
|
|
4
|
-
refs.forEach((ref) => {
|
|
5
|
-
if (typeof ref === "function") {
|
|
6
|
-
ref(value);
|
|
7
|
-
} else if (ref !== null) {
|
|
8
|
-
ref.current = value;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// src/utils/use-anchor-observer.ts
|
|
15
|
-
import { useEffect, useState } from "react";
|
|
16
|
-
function useAnchorObserver(watch) {
|
|
17
|
-
const [activeAnchor, setActiveAnchor] = useState();
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
const observer = new IntersectionObserver(
|
|
20
|
-
(entries) => {
|
|
21
|
-
setActiveAnchor((f) => {
|
|
22
|
-
for (const entry of entries) {
|
|
23
|
-
const aboveHalf = window.innerHeight / 2 > entry.boundingClientRect.y;
|
|
24
|
-
const active = aboveHalf && entry.isIntersecting;
|
|
25
|
-
if (active) {
|
|
26
|
-
return entry.target.id;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return f ?? watch[0];
|
|
30
|
-
});
|
|
31
|
-
},
|
|
32
|
-
{ rootMargin: `0% 0% -80% 0%` }
|
|
33
|
-
);
|
|
34
|
-
for (const heading of watch) {
|
|
35
|
-
const element = document.getElementById(heading);
|
|
36
|
-
if (element !== null) {
|
|
37
|
-
observer.observe(element);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return () => {
|
|
41
|
-
observer.disconnect();
|
|
42
|
-
};
|
|
43
|
-
}, [watch]);
|
|
44
|
-
return activeAnchor;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export {
|
|
48
|
-
mergeRefs,
|
|
49
|
-
useAnchorObserver
|
|
50
|
-
};
|
package/dist/toc-internal.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ReactNode, RefObject, AnchorHTMLAttributes } from 'react';
|
|
3
|
-
import { T as TableOfContents } from './get-toc-CM4X3hbw.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The id of active anchor (doesn't include hash)
|
|
7
|
-
*/
|
|
8
|
-
declare function useActiveAnchor(): string | undefined;
|
|
9
|
-
interface AnchorProviderProps {
|
|
10
|
-
toc: TableOfContents;
|
|
11
|
-
children?: ReactNode;
|
|
12
|
-
}
|
|
13
|
-
interface ScrollProviderProps {
|
|
14
|
-
/**
|
|
15
|
-
* Scroll into the view of container when active
|
|
16
|
-
*/
|
|
17
|
-
containerRef: RefObject<HTMLElement>;
|
|
18
|
-
children?: ReactNode;
|
|
19
|
-
}
|
|
20
|
-
declare function ScrollProvider({ containerRef, children, }: ScrollProviderProps): React.ReactElement;
|
|
21
|
-
declare function AnchorProvider({ toc, children, }: AnchorProviderProps): React.ReactElement;
|
|
22
|
-
interface TOCItemProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
|
|
23
|
-
href: string;
|
|
24
|
-
onActiveChange?: (v: boolean) => void;
|
|
25
|
-
}
|
|
26
|
-
declare const TOCItem: react.ForwardRefExoticComponent<TOCItemProps & react.RefAttributes<HTMLAnchorElement>>;
|
|
27
|
-
|
|
28
|
-
export { AnchorProvider, type AnchorProviderProps, ScrollProvider, type ScrollProviderProps, TOCItem, type TOCItemProps, useActiveAnchor };
|
package/dist/toc-internal.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useOnChange
|
|
3
|
-
} from "./chunk-KGMG4N3Y.js";
|
|
4
|
-
import {
|
|
5
|
-
mergeRefs,
|
|
6
|
-
useAnchorObserver
|
|
7
|
-
} from "./chunk-V6DBK6TW.js";
|
|
8
|
-
import "./chunk-MLKGABMK.js";
|
|
9
|
-
|
|
10
|
-
// src/toc-internal.tsx
|
|
11
|
-
import { createContext, forwardRef, useContext, useMemo, useRef } from "react";
|
|
12
|
-
import scrollIntoView from "scroll-into-view-if-needed";
|
|
13
|
-
import { jsx } from "react/jsx-runtime";
|
|
14
|
-
var ActiveAnchorContext = createContext(void 0);
|
|
15
|
-
var ScrollContext = createContext({ current: null });
|
|
16
|
-
function useActiveAnchor() {
|
|
17
|
-
return useContext(ActiveAnchorContext);
|
|
18
|
-
}
|
|
19
|
-
function ScrollProvider({
|
|
20
|
-
containerRef,
|
|
21
|
-
children
|
|
22
|
-
}) {
|
|
23
|
-
return /* @__PURE__ */ jsx(ScrollContext.Provider, { value: containerRef, children });
|
|
24
|
-
}
|
|
25
|
-
function AnchorProvider({
|
|
26
|
-
toc,
|
|
27
|
-
children
|
|
28
|
-
}) {
|
|
29
|
-
const headings = useMemo(() => {
|
|
30
|
-
return toc.map((item) => item.url.split("#")[1]);
|
|
31
|
-
}, [toc]);
|
|
32
|
-
const activeAnchor = useAnchorObserver(headings);
|
|
33
|
-
return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, { value: activeAnchor, children });
|
|
34
|
-
}
|
|
35
|
-
var TOCItem = forwardRef(
|
|
36
|
-
({ onActiveChange, ...props }, ref) => {
|
|
37
|
-
const containerRef = useContext(ScrollContext);
|
|
38
|
-
const activeAnchor = useActiveAnchor();
|
|
39
|
-
const anchorRef = useRef(null);
|
|
40
|
-
const mergedRef = mergeRefs(anchorRef, ref);
|
|
41
|
-
const isActive = activeAnchor === props.href.split("#")[1];
|
|
42
|
-
useOnChange(isActive, (v) => {
|
|
43
|
-
const element = anchorRef.current;
|
|
44
|
-
if (!element) return;
|
|
45
|
-
if (v && containerRef.current) {
|
|
46
|
-
scrollIntoView(element, {
|
|
47
|
-
behavior: "smooth",
|
|
48
|
-
block: "center",
|
|
49
|
-
inline: "center",
|
|
50
|
-
scrollMode: "always",
|
|
51
|
-
boundary: containerRef.current
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
onActiveChange?.(v);
|
|
55
|
-
});
|
|
56
|
-
return /* @__PURE__ */ jsx("a", { ref: mergedRef, "data-active": isActive, ...props, children: props.children });
|
|
57
|
-
}
|
|
58
|
-
);
|
|
59
|
-
TOCItem.displayName = "TOCItem";
|
|
60
|
-
export {
|
|
61
|
-
AnchorProvider,
|
|
62
|
-
ScrollProvider,
|
|
63
|
-
TOCItem,
|
|
64
|
-
useActiveAnchor
|
|
65
|
-
};
|