fumadocs-core 12.0.0 → 12.0.2
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/chunk-EP2HYVJS.js +50 -0
- package/dist/toc-internal.d.ts +28 -0
- package/dist/toc-internal.js +79 -0
- package/dist/toc.d.ts +8 -1
- package/dist/toc.js +11 -57
- package/package.json +8 -1
|
@@ -0,0 +1,50 @@
|
|
|
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 != null ? 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
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, RefObject, AnchorHTMLAttributes } from 'react';
|
|
3
|
+
import { T as TableOfContents } from './get-toc-B-AMfFKT.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 };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergeRefs,
|
|
3
|
+
useAnchorObserver
|
|
4
|
+
} from "./chunk-EP2HYVJS.js";
|
|
5
|
+
import {
|
|
6
|
+
__objRest,
|
|
7
|
+
__spreadProps,
|
|
8
|
+
__spreadValues
|
|
9
|
+
} from "./chunk-UWTMEZUM.js";
|
|
10
|
+
|
|
11
|
+
// src/toc-internal.tsx
|
|
12
|
+
import {
|
|
13
|
+
createContext,
|
|
14
|
+
forwardRef,
|
|
15
|
+
useContext,
|
|
16
|
+
useEffect,
|
|
17
|
+
useMemo,
|
|
18
|
+
useRef
|
|
19
|
+
} from "react";
|
|
20
|
+
import scrollIntoView from "scroll-into-view-if-needed";
|
|
21
|
+
import { jsx } from "react/jsx-runtime";
|
|
22
|
+
var ActiveAnchorContext = createContext(void 0);
|
|
23
|
+
var ScrollContext = createContext({ current: null });
|
|
24
|
+
function useActiveAnchor() {
|
|
25
|
+
return useContext(ActiveAnchorContext);
|
|
26
|
+
}
|
|
27
|
+
function ScrollProvider({
|
|
28
|
+
containerRef,
|
|
29
|
+
children
|
|
30
|
+
}) {
|
|
31
|
+
return /* @__PURE__ */ jsx(ScrollContext.Provider, { value: containerRef, children });
|
|
32
|
+
}
|
|
33
|
+
function AnchorProvider({
|
|
34
|
+
toc,
|
|
35
|
+
children
|
|
36
|
+
}) {
|
|
37
|
+
const headings = useMemo(() => {
|
|
38
|
+
return toc.map((item) => item.url.split("#")[1]);
|
|
39
|
+
}, [toc]);
|
|
40
|
+
const activeAnchor = useAnchorObserver(headings);
|
|
41
|
+
return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, { value: activeAnchor, children });
|
|
42
|
+
}
|
|
43
|
+
var TOCItem = forwardRef(
|
|
44
|
+
(_a, ref) => {
|
|
45
|
+
var _b = _a, { onActiveChange } = _b, props = __objRest(_b, ["onActiveChange"]);
|
|
46
|
+
const containerRef = useContext(ScrollContext);
|
|
47
|
+
const activeAnchor = useActiveAnchor();
|
|
48
|
+
const anchorRef = useRef(null);
|
|
49
|
+
const mergedRef = mergeRefs(anchorRef, ref);
|
|
50
|
+
const isActive = activeAnchor === props.href.split("#")[1];
|
|
51
|
+
const onActiveRef = useRef();
|
|
52
|
+
onActiveRef.current = (active) => {
|
|
53
|
+
const element = anchorRef.current;
|
|
54
|
+
if (!element) return;
|
|
55
|
+
if (active && containerRef.current) {
|
|
56
|
+
scrollIntoView(element, {
|
|
57
|
+
behavior: "smooth",
|
|
58
|
+
block: "center",
|
|
59
|
+
inline: "center",
|
|
60
|
+
scrollMode: "always",
|
|
61
|
+
boundary: containerRef.current
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
onActiveChange == null ? void 0 : onActiveChange(active);
|
|
65
|
+
};
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
var _a2;
|
|
68
|
+
(_a2 = onActiveRef.current) == null ? void 0 : _a2.call(onActiveRef, isActive);
|
|
69
|
+
}, [isActive]);
|
|
70
|
+
return /* @__PURE__ */ jsx("a", __spreadProps(__spreadValues({ ref: mergedRef, "data-active": isActive }, props), { children: props.children }));
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
TOCItem.displayName = "TOCItem";
|
|
74
|
+
export {
|
|
75
|
+
AnchorProvider,
|
|
76
|
+
ScrollProvider,
|
|
77
|
+
TOCItem,
|
|
78
|
+
useActiveAnchor
|
|
79
|
+
};
|
package/dist/toc.d.ts
CHANGED
|
@@ -8,13 +8,20 @@ interface TOCProviderProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
8
8
|
}
|
|
9
9
|
declare const TOCProvider: react.ForwardRefExoticComponent<TOCProviderProps & react.RefAttributes<HTMLDivElement>>;
|
|
10
10
|
interface TOCScrollProvider {
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Scroll into the view of container when active
|
|
13
|
+
*/
|
|
14
|
+
containerRef?: RefObject<HTMLElement>;
|
|
12
15
|
toc: TableOfContents;
|
|
13
16
|
children: ReactNode;
|
|
14
17
|
}
|
|
15
18
|
declare function TOCScrollProvider({ toc, containerRef, children, }: TOCScrollProvider): React.ReactElement;
|
|
16
19
|
interface TOCItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
17
20
|
href: string;
|
|
21
|
+
/**
|
|
22
|
+
* Scroll into the view of container when active
|
|
23
|
+
*/
|
|
24
|
+
containerRef?: RefObject<HTMLElement>;
|
|
18
25
|
}
|
|
19
26
|
declare const TOCItem: react.ForwardRefExoticComponent<TOCItemProps & react.RefAttributes<HTMLAnchorElement>>;
|
|
20
27
|
|
package/dist/toc.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergeRefs,
|
|
3
|
+
useAnchorObserver
|
|
4
|
+
} from "./chunk-EP2HYVJS.js";
|
|
1
5
|
import {
|
|
2
6
|
__objRest,
|
|
3
7
|
__spreadProps,
|
|
@@ -9,64 +13,13 @@ import {
|
|
|
9
13
|
createContext,
|
|
10
14
|
forwardRef,
|
|
11
15
|
useContext,
|
|
12
|
-
useEffect
|
|
16
|
+
useEffect,
|
|
13
17
|
useMemo,
|
|
14
18
|
useRef
|
|
15
19
|
} from "react";
|
|
16
20
|
import scrollIntoView from "scroll-into-view-if-needed";
|
|
17
|
-
|
|
18
|
-
// src/utils/merge-refs.ts
|
|
19
|
-
function mergeRefs(...refs) {
|
|
20
|
-
return (value) => {
|
|
21
|
-
refs.forEach((ref) => {
|
|
22
|
-
if (typeof ref === "function") {
|
|
23
|
-
ref(value);
|
|
24
|
-
} else if (ref !== null) {
|
|
25
|
-
ref.current = value;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// src/utils/use-anchor-observer.ts
|
|
32
|
-
import { useEffect, useState } from "react";
|
|
33
|
-
function useAnchorObserver(watch) {
|
|
34
|
-
const [activeAnchor, setActiveAnchor] = useState();
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
const observer = new IntersectionObserver(
|
|
37
|
-
(entries) => {
|
|
38
|
-
setActiveAnchor((f) => {
|
|
39
|
-
for (const entry of entries) {
|
|
40
|
-
const aboveHalf = window.innerHeight / 2 > entry.boundingClientRect.y;
|
|
41
|
-
const active = aboveHalf && entry.isIntersecting;
|
|
42
|
-
if (active) {
|
|
43
|
-
return entry.target.id;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return f != null ? f : watch[0];
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
{ rootMargin: `0% 0% -80% 0%` }
|
|
50
|
-
);
|
|
51
|
-
for (const heading of watch) {
|
|
52
|
-
const element = document.getElementById(heading);
|
|
53
|
-
if (element !== null) {
|
|
54
|
-
observer.observe(element);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return () => {
|
|
58
|
-
observer.disconnect();
|
|
59
|
-
};
|
|
60
|
-
}, [watch]);
|
|
61
|
-
return activeAnchor;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// src/toc.tsx
|
|
65
21
|
import { jsx } from "react/jsx-runtime";
|
|
66
|
-
var ActiveAnchorContext = createContext({
|
|
67
|
-
activeAnchor: void 0,
|
|
68
|
-
containerRef: { current: null }
|
|
69
|
-
});
|
|
22
|
+
var ActiveAnchorContext = createContext({});
|
|
70
23
|
var useActiveAnchor = (url) => {
|
|
71
24
|
const { activeAnchor } = useContext(ActiveAnchorContext);
|
|
72
25
|
return activeAnchor === url.split("#")[1];
|
|
@@ -92,14 +45,15 @@ function TOCScrollProvider({
|
|
|
92
45
|
return /* @__PURE__ */ jsx(ActiveAnchorContext.Provider, { value: { containerRef, activeAnchor }, children });
|
|
93
46
|
}
|
|
94
47
|
var TOCItem = forwardRef(
|
|
95
|
-
(
|
|
96
|
-
|
|
48
|
+
(_a, ref) => {
|
|
49
|
+
var _b = _a, { containerRef: container } = _b, props = __objRest(_b, ["containerRef"]);
|
|
50
|
+
const { containerRef = container } = useContext(ActiveAnchorContext);
|
|
97
51
|
const active = useActiveAnchor(props.href);
|
|
98
52
|
const anchorRef = useRef(null);
|
|
99
53
|
const mergedRef = mergeRefs(anchorRef, ref);
|
|
100
|
-
|
|
54
|
+
useEffect(() => {
|
|
101
55
|
const element = anchorRef.current;
|
|
102
|
-
if (active && element) {
|
|
56
|
+
if (active && element && containerRef) {
|
|
103
57
|
scrollIntoView(element, {
|
|
104
58
|
behavior: "smooth",
|
|
105
59
|
block: "center",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-core",
|
|
3
|
-
"version": "12.0.
|
|
3
|
+
"version": "12.0.2",
|
|
4
4
|
"description": "The library for building a documentation website in Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -24,6 +24,10 @@
|
|
|
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
|
+
},
|
|
27
31
|
"./search/client": {
|
|
28
32
|
"import": "./dist/search/client.js",
|
|
29
33
|
"types": "./dist/search/client.d.ts"
|
|
@@ -76,6 +80,9 @@
|
|
|
76
80
|
"toc": [
|
|
77
81
|
"./dist/toc.d.ts"
|
|
78
82
|
],
|
|
83
|
+
"toc-internal": [
|
|
84
|
+
"./dist/toc-internal.d.ts"
|
|
85
|
+
],
|
|
79
86
|
"search/client": [
|
|
80
87
|
"./dist/search/client.d.ts"
|
|
81
88
|
],
|