fumadocs-core 12.0.1 → 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.
@@ -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
- containerRef: RefObject<HTMLElement>;
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 as useEffect2,
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
- (props, ref) => {
96
- const { containerRef } = useContext(ActiveAnchorContext);
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
- useEffect2(() => {
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.1",
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
  ],