fumadocs-ui 16.7.15 → 16.7.16

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.
@@ -14,7 +14,6 @@
14
14
  @source inline("*:has-[+:last-child[data-empty=true]]:border-b-0");
15
15
  @source inline("*:last:border-b-0");
16
16
  @source inline("*:rounded-full");
17
- @source inline("--b");
18
17
  @source inline("--callout-color");
19
18
  @source inline("--color-fd-");
20
19
  @source inline("--color-fd-muted");
@@ -30,7 +29,6 @@
30
29
  @source inline("--shiki-dark-bg");
31
30
  @source inline("--shiki-light-bg");
32
31
  @source inline("--spacing");
33
- @source inline("--t");
34
32
  @source inline("--track-bottom");
35
33
  @source inline("--track-top");
36
34
  @source inline("-circle");
@@ -165,8 +163,6 @@
165
163
  @source inline("bottom-0");
166
164
  @source inline("bottom-1.5");
167
165
  @source inline("boundary");
168
- @source inline("box");
169
- @source inline("boxRef");
170
166
  @source inline("breaking");
171
167
  @source inline("button");
172
168
  @source inline("buttonVariants");
@@ -322,6 +318,7 @@
322
318
  @source inline("display");
323
319
  @source inline("displayName");
324
320
  @source inline("displayed");
321
+ @source inline("distance");
325
322
  @source inline("div");
326
323
  @source inline("divide-fd-border");
327
324
  @source inline("divide-x");
@@ -440,8 +437,6 @@
440
437
  @source inline("group-data-[state=active]:bg-fd-primary");
441
438
  @source inline("group-data-[state=open]:rotate-180");
442
439
  @source inline("group-data-[state=open]:rotate-90");
443
- @source inline("group-first:[--t:--spacing(0.75)]");
444
- @source inline("group-last:[--b:--spacing(0.75)]");
445
440
  @source inline("groupListeners");
446
441
  @source inline("guides");
447
442
  @source inline("h");
@@ -520,6 +515,8 @@
520
515
  @source inline("invisible");
521
516
  @source inline("is");
522
517
  @source inline("isActive");
518
+ @source inline("isFirst");
519
+ @source inline("isLast");
523
520
  @source inline("isLoading");
524
521
  @source inline("isOpen");
525
522
  @source inline("isTabActive");
@@ -645,6 +642,7 @@
645
642
  @source inline("my-4");
646
643
  @source inline("my-6");
647
644
  @source inline("my-auto");
645
+ @source inline("n");
648
646
  @source inline("name");
649
647
  @source inline("namespace");
650
648
  @source inline("nav");
@@ -711,7 +709,6 @@
711
709
  @source inline("onSelectCallback");
712
710
  @source inline("onTagChange");
713
711
  @source inline("onTagChangeCallback");
714
- @source inline("onUpdate");
715
712
  @source inline("onValueChange");
716
713
  @source inline("only");
717
714
  @source inline("opacity-(--opacity,0)");
@@ -729,6 +726,7 @@
729
726
  @source inline("origin-[top_center]");
730
727
  @source inline("original");
731
728
  @source inline("other");
729
+ @source inline("out");
732
730
  @source inline("outer");
733
731
  @source inline("outline");
734
732
  @source inline("outline-none");
@@ -761,6 +759,7 @@
761
759
  @source inline("path");
762
760
  @source inline("pathname");
763
761
  @source inline("paths");
762
+ @source inline("pb-0");
764
763
  @source inline("pb-2");
765
764
  @source inline("pe-2");
766
765
  @source inline("peer");
@@ -986,7 +985,6 @@
986
985
  @source inline("supposed");
987
986
  @source inline("sure");
988
987
  @source inline("svg");
989
- @source inline("svgRef");
990
988
  @source inline("switch");
991
989
  @source inline("system");
992
990
  @source inline("t");
@@ -1052,8 +1050,6 @@
1052
1050
  @source inline("top-2.5");
1053
1051
  @source inline("top-3");
1054
1052
  @source inline("top-4");
1055
- @source inline("top-[calc(50%-var(--t,0px)+var(--b,0px))]");
1056
- @source inline("topL");
1057
1053
  @source inline("touch");
1058
1054
  @source inline("transform");
1059
1055
  @source inline("transition-[clip-path]");
package/css/lib/shiki.css CHANGED
@@ -95,3 +95,14 @@
95
95
  font-style: var(--shiki-dark-font-style);
96
96
  }
97
97
  }
98
+
99
+ /* inline code */
100
+ code.shiki span {
101
+ color: var(--shiki-light);
102
+ font-style: var(--shiki-light-font-style);
103
+ }
104
+
105
+ .dark code.shiki span {
106
+ color: var(--shiki-dark);
107
+ font-style: var(--shiki-dark-font-style);
108
+ }
@@ -10,6 +10,7 @@ declare function TOCItems({
10
10
  ref,
11
11
  className,
12
12
  thumbBox,
13
+ children,
13
14
  ...props
14
15
  }: TOCItemsProps): _$react_jsx_runtime0.JSX.Element;
15
16
  declare function TOCEmpty(): _$react_jsx_runtime0.JSX.Element;
@@ -5,7 +5,7 @@ import { cn } from "../../utils/cn.js";
5
5
  import { mergeRefs } from "../../utils/merge-refs.js";
6
6
  import { useTOCItems } from "./index.js";
7
7
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import * as Primitive from "fumadocs-core/toc";
10
10
  //#region src/components/toc/clerk.tsx
11
11
  var clerk_exports = /* @__PURE__ */ __exportAll({
@@ -13,7 +13,7 @@ var clerk_exports = /* @__PURE__ */ __exportAll({
13
13
  TOCItem: () => TOCItem,
14
14
  TOCItems: () => TOCItems
15
15
  });
16
- function TOCItems({ ref, className, thumbBox = true, ...props }) {
16
+ function TOCItems({ ref, className, thumbBox = true, children, ...props }) {
17
17
  const containerRef = useRef(null);
18
18
  const items = useTOCItems();
19
19
  const [svg, setSvg] = useState(null);
@@ -78,12 +78,12 @@ function TOCItems({ ref, className, thumbBox = true, ...props }) {
78
78
  if (thumbBox) {
79
79
  const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
80
80
  path.setAttribute("d", d);
81
- let l = 0;
82
- for (const [top, bottom] of positions) {
83
- while (path.getPointAtLength(l).y < top) l++;
84
- const topL = l;
85
- while (path.getPointAtLength(l).y < bottom) l++;
86
- itemLineLengths.push([topL, l]);
81
+ const n = path.getTotalLength();
82
+ for (let i = 0; i < positions.length; i++) {
83
+ const [top, bottom] = positions[i];
84
+ let l = i > 0 ? itemLineLengths[i - 1][1] + (top - positions[i - 1][1]) : top;
85
+ while (l < n && path.getPointAtLength(l).y < top) l++;
86
+ itemLineLengths.push([l, l + bottom - top]);
87
87
  }
88
88
  }
89
89
  setSvg({
@@ -105,14 +105,15 @@ function TOCItems({ ref, className, thumbBox = true, ...props }) {
105
105
  observer.unobserve(container);
106
106
  };
107
107
  }, [onPrint]);
108
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [svg && /* @__PURE__ */ jsx(ThumbTrack, {
109
- computed: svg,
110
- thumbBox
111
- }), /* @__PURE__ */ jsx("div", {
108
+ return /* @__PURE__ */ jsxs("div", {
112
109
  ref: mergeRefs(containerRef, ref),
113
- className: cn("flex flex-col", className),
114
- ...props
115
- })] });
110
+ className: cn("relative flex flex-col", className),
111
+ ...props,
112
+ children: [svg && /* @__PURE__ */ jsx(ThumbTrack, {
113
+ computed: svg,
114
+ thumbBox
115
+ }), children]
116
+ });
116
117
  }
117
118
  function TOCEmpty() {
118
119
  const { text } = useI18n();
@@ -122,20 +123,17 @@ function TOCEmpty() {
122
123
  });
123
124
  }
124
125
  function ThumbTrack({ computed, thumbBox }) {
125
- const svgRef = useRef(null);
126
- const boxRef = useRef(null);
126
+ const ref = useRef(null);
127
127
  const previousRef = useRef(null);
128
128
  const tocInfo = Primitive.useTOC();
129
- const onUpdate = useCallback((items) => {
130
- const svg = svgRef.current;
131
- if (!svg) return;
129
+ function calculate(items) {
130
+ const out = {};
132
131
  const startIdx = items.findIndex((item) => item.active);
133
- if (startIdx === -1) return;
132
+ if (startIdx === -1) return out;
134
133
  const endIdx = items.findLastIndex((item) => item.active);
135
- svg.style.setProperty("--track-top", `${computed.positions[startIdx][0]}px`);
136
- svg.style.setProperty("--track-bottom", `${computed.positions[endIdx][1]}px`);
137
- const box = boxRef.current;
138
- if (box) {
134
+ out["--track-top"] = `${computed.positions[startIdx][0]}px`;
135
+ out["--track-bottom"] = `${computed.positions[endIdx][1]}px`;
136
+ if (thumbBox) {
139
137
  let isUp = false;
140
138
  if (previousRef.current) {
141
139
  const prev = previousRef.current;
@@ -146,22 +144,25 @@ function ThumbTrack({ computed, thumbBox }) {
146
144
  endIdx,
147
145
  isUp
148
146
  };
149
- box.style.setProperty("--offset-distance", isUp ? `${computed.itemLineLengths[startIdx][0]}px` : `${computed.itemLineLengths[endIdx][1]}px`);
150
- box.style.setProperty("--opacity", items[isUp ? startIdx : endIdx].original._step !== void 0 ? "0" : "1");
147
+ out["--offset-distance"] = isUp ? `${computed.itemLineLengths[startIdx][0]}px` : `${computed.itemLineLengths[endIdx][1]}px`;
148
+ out["--opacity"] = items[isUp ? startIdx : endIdx].original._step !== void 0 ? "0" : "1";
151
149
  }
152
- }, [computed]);
153
- Primitive.useTOCListener(onUpdate);
154
- useEffect(() => {
155
- onUpdate(tocInfo.get());
156
- }, [onUpdate, tocInfo]);
150
+ return out;
151
+ }
152
+ Primitive.useTOCListener((items) => {
153
+ const element = ref.current;
154
+ if (!element) return;
155
+ for (const [k, v] of Object.entries(calculate(items))) element.style.setProperty(k, v);
156
+ });
157
157
  return /* @__PURE__ */ jsxs("div", {
158
+ ref,
158
159
  className: "absolute top-0 inset-s-0",
159
160
  style: {
160
161
  width: computed.width,
161
- height: computed.height
162
+ height: computed.height,
163
+ ...calculate(tocInfo.get())
162
164
  },
163
165
  children: [/* @__PURE__ */ jsx("svg", {
164
- ref: svgRef,
165
166
  xmlns: "http://www.w3.org/2000/svg",
166
167
  viewBox: `0 0 ${computed.width} ${computed.height}`,
167
168
  className: "absolute transition-[clip-path]",
@@ -172,7 +173,6 @@ function ThumbTrack({ computed, thumbBox }) {
172
173
  },
173
174
  children: computed.content
174
175
  }), thumbBox && /* @__PURE__ */ jsx("div", {
175
- ref: boxRef,
176
176
  className: "absolute size-1 bg-fd-primary rounded-full [offset-distance:var(--offset-distance,0)] opacity-(--opacity,0) transition-[opacity,offset-distance]",
177
177
  style: { offsetPath: `path("${computed.d}")` }
178
178
  })]
@@ -191,11 +191,13 @@ function getLineOffset(depth) {
191
191
  }
192
192
  function TOCItem({ item, ...props }) {
193
193
  const items = useTOCItems();
194
- const { lowerOffset, offset, upperOffset } = useMemo(() => {
194
+ const { lowerOffset, offset, upperOffset, isFirst, isLast } = useMemo(() => {
195
195
  const index = items.indexOf(item);
196
196
  const offset = getLineOffset(item.depth);
197
197
  return {
198
198
  offset,
199
+ isFirst: index === 0,
200
+ isLast: index === items.length - 1,
199
201
  upperOffset: index > 0 ? getLineOffset(items[index - 1].depth) : offset,
200
202
  lowerOffset: index + 1 < items.length ? getLineOffset(items[index + 1].depth) : offset
201
203
  };
@@ -203,7 +205,7 @@ function TOCItem({ item, ...props }) {
203
205
  return /* @__PURE__ */ jsxs(Primitive.TOCItem, {
204
206
  href: item.url,
205
207
  ...props,
206
- className: cn("group prose relative py-1.5 text-sm scroll-m-4 text-fd-muted-foreground hover:text-fd-accent-foreground transition-colors wrap-anywhere first:pt-0 last:pb-0 data-[active=true]:text-fd-primary", props.className),
208
+ className: cn("prose relative py-1.5 text-sm scroll-m-4 text-fd-muted-foreground hover:text-fd-accent-foreground transition-colors wrap-anywhere data-[active=true]:text-fd-primary", isFirst && "pt-0", isLast && "pb-0", props.className),
207
209
  style: {
208
210
  paddingInlineStart: getItemOffset(item.depth),
209
211
  ...props.style
@@ -231,8 +233,11 @@ function TOCItem({ item, ...props }) {
231
233
  style: { insetInlineStart: offset }
232
234
  }),
233
235
  item._step !== void 0 && /* @__PURE__ */ jsx("div", {
234
- className: "absolute flex items-center justify-center -translate-1/2 -z-1 top-[calc(50%-var(--t,0px)+var(--b,0px))] size-4 font-mono font-medium text-xs bg-fd-muted text-fd-muted-foreground rounded-full leading-none group-first:[--t:--spacing(0.75)] group-last:[--b:--spacing(0.75)]",
235
- style: { insetInlineStart: offset },
236
+ className: "absolute flex items-center justify-center -translate-1/2 -z-1 size-4 font-mono font-medium text-xs bg-fd-muted text-fd-muted-foreground rounded-full leading-none",
237
+ style: {
238
+ top: `calc(50% + ${(isFirst ? -.75 : 0) + (isLast ? .75 : 0)} * var(--spacing))`,
239
+ insetInlineStart: offset
240
+ },
236
241
  children: item._step
237
242
  }),
238
243
  item.title
@@ -55,23 +55,27 @@ function TOCItems({ ref, className, ...props }) {
55
55
  function TocThumb({ computed }) {
56
56
  const ref = useRef(null);
57
57
  const tocInfo = Primitive.useTOC();
58
- const onUpdate = useCallback((items) => {
59
- const element = ref.current;
60
- if (!element) return;
58
+ function calculate(items) {
59
+ const out = {};
61
60
  const startIdx = items.findIndex((item) => item.active);
62
- if (startIdx === -1) return;
61
+ if (startIdx === -1) return out;
63
62
  const endIdx = items.findLastIndex((item) => item.active);
64
- element.style.setProperty("--track-top", `${computed.positions[startIdx][0]}px`);
65
- element.style.setProperty("--track-bottom", `${computed.positions[endIdx][1]}px`);
66
- }, [computed]);
67
- Primitive.useTOCListener(onUpdate);
68
- useEffect(() => {
69
- onUpdate(tocInfo.get());
70
- }, [onUpdate, tocInfo]);
63
+ out["--track-top"] = `${computed.positions[startIdx][0]}px`;
64
+ out["--track-bottom"] = `${computed.positions[endIdx][1]}px`;
65
+ return out;
66
+ }
67
+ Primitive.useTOCListener((items) => {
68
+ const element = ref.current;
69
+ if (!element) return;
70
+ for (const [k, v] of Object.entries(calculate(items))) element.style.setProperty(k, v);
71
+ });
71
72
  return /* @__PURE__ */ jsx("div", {
72
73
  ref,
73
74
  className: "absolute inset-y-0 inset-s-0 bg-fd-primary w-px transition-[clip-path]",
74
- style: { clipPath: `polygon(0 var(--track-top,0), 100% var(--track-top,0), 100% var(--track-bottom,0), 0 var(--track-bottom,0))` }
75
+ style: {
76
+ clipPath: `polygon(0 var(--track-top,0), 100% var(--track-top,0), 100% var(--track-bottom,0), 0 var(--track-bottom,0))`,
77
+ ...calculate(tocInfo.get())
78
+ }
75
79
  });
76
80
  }
77
81
  function TOCEmpty() {
package/dist/style.css CHANGED
@@ -374,9 +374,6 @@
374
374
  .top-\[calc\(--spacing\(4\)\+var\(--fd-docs-row-3\)\)\] {
375
375
  top: calc(calc(var(--spacing) * 4) + var(--fd-docs-row-3));
376
376
  }
377
- .top-\[calc\(50\%-var\(--t\,0px\)\+var\(--b\,0px\)\)\] {
378
- top: calc(50% - var(--t,0px) + var(--b,0px));
379
- }
380
377
  .right-2 {
381
378
  right: calc(var(--spacing) * 2);
382
379
  }
@@ -1688,6 +1685,9 @@
1688
1685
  .pr-\(--removed-body-scroll-bar-size\,0\) {
1689
1686
  padding-right: var(--removed-body-scroll-bar-size,0);
1690
1687
  }
1688
+ .pb-0 {
1689
+ padding-bottom: calc(var(--spacing) * 0);
1690
+ }
1691
1691
  .pb-1\.5 {
1692
1692
  padding-bottom: calc(var(--spacing) * 1.5);
1693
1693
  }
@@ -2110,16 +2110,6 @@
2110
2110
  margin-bottom: calc(var(--spacing) * 2);
2111
2111
  }
2112
2112
  }
2113
- .group-first\:\[--t\:--spacing\(0\.75\)\] {
2114
- &:is(:where(.group):first-child *) {
2115
- --t: calc(var(--spacing) * 0.75);
2116
- }
2117
- }
2118
- .group-last\:\[--b\:--spacing\(0\.75\)\] {
2119
- &:is(:where(.group):last-child *) {
2120
- --b: calc(var(--spacing) * 0.75);
2121
- }
2122
- }
2123
2113
  .group-data-\[state\=active\]\:bg-fd-primary {
2124
2114
  &:is(:where(.group)[data-state="active"] *) {
2125
2115
  background-color: var(--color-fd-primary);
@@ -3106,6 +3096,14 @@
3106
3096
  font-style: var(--shiki-dark-font-style);
3107
3097
  }
3108
3098
  }
3099
+ code.shiki span {
3100
+ color: var(--shiki-light);
3101
+ font-style: var(--shiki-light-font-style);
3102
+ }
3103
+ .dark code.shiki span {
3104
+ color: var(--shiki-dark);
3105
+ font-style: var(--shiki-dark-font-style);
3106
+ }
3109
3107
  @property --radix-collapsible-content-height {
3110
3108
  syntax: '<length>';
3111
3109
  inherits: false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-ui",
3
- "version": "16.7.15",
3
+ "version": "16.7.16",
4
4
  "description": "The Radix UI version of Fumadocs UI",
5
5
  "keywords": [
6
6
  "Docs",
@@ -148,7 +148,7 @@
148
148
  },
149
149
  "devDependencies": {
150
150
  "@tailwindcss/cli": "^4.2.2",
151
- "@tsdown/css": "^0.21.6",
151
+ "@tsdown/css": "^0.21.8",
152
152
  "@types/hast": "^3.0.4",
153
153
  "@types/mdx": "^2.0.13",
154
154
  "@types/node": "^25.6.0",
@@ -157,10 +157,10 @@
157
157
  "fuma-cli": "^0.0.5",
158
158
  "react-medium-image-zoom": "^5.4.3",
159
159
  "tailwindcss": "^4.2.2",
160
- "tsdown": "0.21.7",
160
+ "tsdown": "0.21.8",
161
161
  "unified": "^11.0.5",
162
162
  "@fumadocs/cli": "1.3.7",
163
- "fumadocs-core": "16.7.15",
163
+ "fumadocs-core": "16.7.16",
164
164
  "tsconfig": "0.0.0"
165
165
  },
166
166
  "peerDependencies": {
@@ -170,7 +170,7 @@
170
170
  "next": "16.x.x",
171
171
  "react": "^19.2.0",
172
172
  "react-dom": "^19.2.0",
173
- "fumadocs-core": "16.7.15"
173
+ "fumadocs-core": "16.7.16"
174
174
  },
175
175
  "peerDependenciesMeta": {
176
176
  "next": {