@farming-labs/theme 0.1.141 → 0.1.143
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/docs-page-client.d.mts +1 -1
- package/dist/docs-page-client.mjs +143 -75
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/locale-theme-control.mjs +4 -0
- package/dist/page-actions.d.mts +2 -0
- package/dist/page-actions.mjs +109 -17
- package/dist/threadline/index.d.mts +149 -0
- package/dist/threadline/index.mjs +154 -0
- package/package.json +9 -3
- package/styles/threadline.css +1270 -0
|
@@ -28,7 +28,7 @@ interface DocsPageClientProps {
|
|
|
28
28
|
openDocsTarget?: "markdown" | "page" | "source" | "github";
|
|
29
29
|
openDocsPrompt?: string;
|
|
30
30
|
/** Where to render page actions relative to the title */
|
|
31
|
-
pageActionsPosition?: "above-title" | "below-title";
|
|
31
|
+
pageActionsPosition?: "above-title" | "below-title" | "toc";
|
|
32
32
|
/** Horizontal alignment of page action buttons */
|
|
33
33
|
pageActionsAlignment?: "left" | "right";
|
|
34
34
|
/** GitHub repository URL (e.g. "https://github.com/user/repo") */
|
|
@@ -6,7 +6,7 @@ import { useWindowSearchParams } from "./client-location.mjs";
|
|
|
6
6
|
import { DocsFeedback } from "./docs-feedback.mjs";
|
|
7
7
|
import { resolveClientLocale, withLangInUrl } from "./i18n.mjs";
|
|
8
8
|
import { escapeJsonLdForScript } from "./json-ld.mjs";
|
|
9
|
-
import { Children, Fragment,
|
|
9
|
+
import { Children, Fragment, useEffect, useState } from "react";
|
|
10
10
|
import { DocsBody, DocsPage, EditOnGitHub } from "fumadocs-ui/layouts/docs/page";
|
|
11
11
|
import { createPortal } from "react-dom";
|
|
12
12
|
import { usePathname, useRouter } from "fumadocs-core/framework";
|
|
@@ -53,7 +53,7 @@ function PathBreadcrumb({ pathname, publicPath, locale }) {
|
|
|
53
53
|
},
|
|
54
54
|
children: parentLabel
|
|
55
55
|
})
|
|
56
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
56
|
+
}, "parent"), /* @__PURE__ */ jsxs("span", {
|
|
57
57
|
className: "fd-breadcrumb-item",
|
|
58
58
|
children: [/* @__PURE__ */ jsx("span", {
|
|
59
59
|
className: "fd-breadcrumb-sep",
|
|
@@ -62,7 +62,7 @@ function PathBreadcrumb({ pathname, publicPath, locale }) {
|
|
|
62
62
|
className: "fd-breadcrumb-current",
|
|
63
63
|
children: currentLabel
|
|
64
64
|
})]
|
|
65
|
-
})]
|
|
65
|
+
}, "current")]
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
@@ -214,59 +214,52 @@ function scrollToHashTarget(hash) {
|
|
|
214
214
|
target.scrollIntoView({ block: "start" });
|
|
215
215
|
return true;
|
|
216
216
|
}
|
|
217
|
-
function injectTitleDecorations(node, { description, belowTitle }) {
|
|
218
|
-
if (!description && !belowTitle) return {
|
|
219
|
-
node,
|
|
220
|
-
inserted: false
|
|
221
|
-
};
|
|
222
|
-
let inserted = false;
|
|
223
|
-
const extras = Children.toArray([description, belowTitle].filter(Boolean));
|
|
224
|
-
if (extras.length === 0) return {
|
|
225
|
-
node,
|
|
226
|
-
inserted: false
|
|
227
|
-
};
|
|
228
|
-
const insertedExtras = extras.map((extra, index) => /* @__PURE__ */ jsx(Fragment, { children: extra }, `fd-title-decoration-${index}`));
|
|
229
|
-
function visit(current) {
|
|
230
|
-
if (current == null || typeof current === "boolean") return current;
|
|
231
|
-
if (inserted) return current;
|
|
232
|
-
if (Array.isArray(current)) return current.flatMap((child) => {
|
|
233
|
-
const next = visit(child);
|
|
234
|
-
return Array.isArray(next) ? next : [next];
|
|
235
|
-
});
|
|
236
|
-
if (!isValidElement(current)) return current;
|
|
237
|
-
if (typeof current.type === "string" && current.type === "h1") {
|
|
238
|
-
inserted = true;
|
|
239
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [current, insertedExtras] }, "fd-title-decoration-block");
|
|
240
|
-
}
|
|
241
|
-
const childProps = current.props ?? null;
|
|
242
|
-
if (childProps?.children === void 0) return current;
|
|
243
|
-
const nextChildren = Children.toArray(childProps.children).flatMap((child) => {
|
|
244
|
-
const next = visit(child);
|
|
245
|
-
return Array.isArray(next) ? next : [next];
|
|
246
|
-
});
|
|
247
|
-
if (!inserted) return current;
|
|
248
|
-
return cloneElement(current, void 0, nextChildren);
|
|
249
|
-
}
|
|
250
|
-
if (Array.isArray(node)) return {
|
|
251
|
-
node: node.flatMap((child) => {
|
|
252
|
-
const next = visit(child);
|
|
253
|
-
return Array.isArray(next) ? next : [next];
|
|
254
|
-
}),
|
|
255
|
-
inserted
|
|
256
|
-
};
|
|
257
|
-
return {
|
|
258
|
-
node: visit(node),
|
|
259
|
-
inserted
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
217
|
function TitleDecorations({ description, belowTitle }) {
|
|
263
218
|
if (!description && !belowTitle) return null;
|
|
264
|
-
return /* @__PURE__ */
|
|
219
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [description && /* @__PURE__ */ jsx(Fragment, { children: description }, "description"), belowTitle && /* @__PURE__ */ jsx(Fragment, { children: belowTitle }, "below-title")] });
|
|
220
|
+
}
|
|
221
|
+
function ThreadlinePageControls() {
|
|
222
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
223
|
+
className: "fd-threadline-doc-controls not-prose",
|
|
224
|
+
"aria-label": "Page controls",
|
|
225
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
226
|
+
type: "button",
|
|
227
|
+
"aria-label": "Go back",
|
|
228
|
+
onClick: () => window.history.back(),
|
|
229
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
230
|
+
"aria-hidden": "true",
|
|
231
|
+
children: "<"
|
|
232
|
+
})
|
|
233
|
+
}, "back"), /* @__PURE__ */ jsx("button", {
|
|
234
|
+
type: "button",
|
|
235
|
+
"aria-label": "Go forward",
|
|
236
|
+
onClick: () => window.history.forward(),
|
|
237
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
238
|
+
"aria-hidden": "true",
|
|
239
|
+
children: ">"
|
|
240
|
+
})
|
|
241
|
+
}, "forward")]
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function findThreadlineTocActionsContainer() {
|
|
245
|
+
const toc = document.getElementById("nd-toc") ?? document.querySelector(".fd-toc, [data-toc]");
|
|
246
|
+
if (!toc) return null;
|
|
247
|
+
const stickyChild = toc.querySelector(":scope > .sticky, :scope > [class*='sticky']");
|
|
248
|
+
if (stickyChild) return stickyChild;
|
|
249
|
+
if ((typeof toc.className === "string" ? toc.className : "").includes("grid-area:toc")) return toc;
|
|
250
|
+
let node = toc.parentElement;
|
|
251
|
+
while (node && node.id !== "nd-docs-layout") {
|
|
252
|
+
if ((typeof node.className === "string" ? node.className : "").includes("grid-area:toc") || window.getComputedStyle(node).position === "sticky") return node;
|
|
253
|
+
node = node.parentElement;
|
|
254
|
+
}
|
|
255
|
+
return toc.parentElement ?? toc;
|
|
265
256
|
}
|
|
266
257
|
function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled = true, changelogBasePath, entry = "docs", publicPath, locale, copyMarkdown = false, openDocs = false, openDocsProviders, openDocsTarget, openDocsPrompt, pageActionsPosition = "below-title", pageActionsAlignment = "left", githubUrl, contentDir, githubBranch = "main", githubDirectory, editOnGithubUrl, lastModifiedMap, lastModified: lastModifiedProp, readingTimeMap, readingTime: readingTimeProp, structuredDataMap, structuredData: structuredDataProp, readingTimeEnabled = false, lastUpdatedEnabled = true, lastUpdatedPosition = "footer", llmsTxtEnabled = false, descriptionMap, description, feedbackEnabled = false, feedbackQuestion, feedbackPlaceholder, feedbackPositiveLabel, feedbackNegativeLabel, feedbackSubmitLabel, feedbackOnFeedback, analytics = false, children }) {
|
|
267
258
|
const fdTocStyle = tocStyle === "directional" ? "clerk" : void 0;
|
|
268
259
|
const [toc, setToc] = useState([]);
|
|
269
260
|
const [titlePortalHost, setTitlePortalHost] = useState(null);
|
|
261
|
+
const [titleControlsPortalHost, setTitleControlsPortalHost] = useState(null);
|
|
262
|
+
const [tocActionsPortalHost, setTocActionsPortalHost] = useState(null);
|
|
270
263
|
const [browserPath, setBrowserPath] = useState(null);
|
|
271
264
|
const pathname = usePathname();
|
|
272
265
|
const activeLocale = resolveClientLocale(useWindowSearchParams(), locale);
|
|
@@ -374,10 +367,69 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
374
367
|
clearTimeout(timeout);
|
|
375
368
|
};
|
|
376
369
|
}, [pathname, children]);
|
|
377
|
-
const showActions = !isChangelogRoute && (copyMarkdown || openDocs);
|
|
370
|
+
const showActions = !isChangelogRoute && (copyMarkdown || openDocs || pageActionsPosition === "toc");
|
|
378
371
|
const showActionsBelowTitle = showActions && pageActionsPosition === "below-title";
|
|
379
372
|
const showActionsAboveTitle = showActions && pageActionsPosition === "above-title";
|
|
373
|
+
const showActionsInToc = showActions && pageActionsPosition === "toc";
|
|
380
374
|
const githubFileUrl = editOnGithubUrl ?? (githubUrl ? buildGithubFileUrl(githubUrl, githubBranch, pathname, entry, activeLocale, githubDirectory, contentDir) : void 0);
|
|
375
|
+
useEffect(() => {
|
|
376
|
+
if (!showActionsInToc) {
|
|
377
|
+
setTocActionsPortalHost(null);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
let frame = 0;
|
|
381
|
+
let attempts = 0;
|
|
382
|
+
let host = null;
|
|
383
|
+
let cancelled = false;
|
|
384
|
+
const mountActions = () => {
|
|
385
|
+
if (cancelled) return;
|
|
386
|
+
const container = findThreadlineTocActionsContainer();
|
|
387
|
+
if (!container) {
|
|
388
|
+
if (attempts < 12) {
|
|
389
|
+
attempts += 1;
|
|
390
|
+
frame = requestAnimationFrame(mountActions);
|
|
391
|
+
} else setTocActionsPortalHost(null);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
host = container.querySelector(":scope > .fd-actions-toc-host");
|
|
395
|
+
if (!host) {
|
|
396
|
+
host = document.createElement("div");
|
|
397
|
+
host.className = "fd-actions-toc-host";
|
|
398
|
+
container.append(host);
|
|
399
|
+
}
|
|
400
|
+
setTocActionsPortalHost(host);
|
|
401
|
+
};
|
|
402
|
+
frame = requestAnimationFrame(mountActions);
|
|
403
|
+
return () => {
|
|
404
|
+
cancelled = true;
|
|
405
|
+
cancelAnimationFrame(frame);
|
|
406
|
+
if (host?.isConnected) host.remove();
|
|
407
|
+
setTocActionsPortalHost(null);
|
|
408
|
+
};
|
|
409
|
+
}, [
|
|
410
|
+
pathname,
|
|
411
|
+
showActionsInToc,
|
|
412
|
+
toc.length
|
|
413
|
+
]);
|
|
414
|
+
useEffect(() => {
|
|
415
|
+
if (!showActionsInToc) {
|
|
416
|
+
setTitleControlsPortalHost(null);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const title = document.getElementById("nd-page")?.querySelector("h1");
|
|
420
|
+
if (!title) {
|
|
421
|
+
setTitleControlsPortalHost(null);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const host = document.createElement("div");
|
|
425
|
+
host.className = "fd-threadline-title-controls-host";
|
|
426
|
+
title.insertAdjacentElement("afterend", host);
|
|
427
|
+
setTitleControlsPortalHost(host);
|
|
428
|
+
return () => {
|
|
429
|
+
host.remove();
|
|
430
|
+
setTitleControlsPortalHost(null);
|
|
431
|
+
};
|
|
432
|
+
}, [pathname, showActionsInToc]);
|
|
381
433
|
const lastModified = !isChangelogRoute && lastUpdatedEnabled ? lastModifiedProp ?? lastModifiedMap?.[normalizedPath] : void 0;
|
|
382
434
|
const showLastUpdatedBelowTitle = !!lastModified && lastUpdatedPosition === "below-title";
|
|
383
435
|
const showLastUpdatedInFooter = !!lastModified && lastUpdatedPosition === "footer";
|
|
@@ -392,7 +444,7 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
392
444
|
className: "fd-page-meta-item",
|
|
393
445
|
children: formatReadingTimeLabel(resolvedReadingTime)
|
|
394
446
|
})]
|
|
395
|
-
}) : void 0;
|
|
447
|
+
}, "reading-time") : void 0;
|
|
396
448
|
const titleDescription = pageDescription ? /* @__PURE__ */ jsx("p", {
|
|
397
449
|
className: "fd-page-description",
|
|
398
450
|
children: pageDescription
|
|
@@ -405,8 +457,8 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
405
457
|
showLastUpdatedBelowTitle && /* @__PURE__ */ jsxs("p", {
|
|
406
458
|
className: "fd-last-updated-inline",
|
|
407
459
|
children: ["Last updated ", lastModified]
|
|
408
|
-
}),
|
|
409
|
-
/* @__PURE__ */ jsx("hr", { className: "fd-title-separator" }),
|
|
460
|
+
}, "last-updated"),
|
|
461
|
+
/* @__PURE__ */ jsx("hr", { className: "fd-title-separator" }, "separator"),
|
|
410
462
|
showActionsBelowTitle && /* @__PURE__ */ jsx("div", {
|
|
411
463
|
className: "fd-actions-portal",
|
|
412
464
|
"data-actions-alignment": pageActionsAlignment,
|
|
@@ -417,18 +469,16 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
417
469
|
openDocsTarget,
|
|
418
470
|
openDocsPrompt,
|
|
419
471
|
alignment: pageActionsAlignment,
|
|
472
|
+
variant: "default",
|
|
420
473
|
githubFileUrl,
|
|
421
474
|
analytics
|
|
422
475
|
})
|
|
423
|
-
}),
|
|
476
|
+
}, "actions"),
|
|
424
477
|
showReadingTimeBelowTitle && readingTimeBlock
|
|
425
478
|
]
|
|
426
|
-
}) : void 0;
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
belowTitle: belowTitleBlock
|
|
430
|
-
});
|
|
431
|
-
const needsTitleDecorationsPortal = !titleDecorationsInserted && (!!titleDescription || !!belowTitleBlock);
|
|
479
|
+
}, "below-title") : void 0;
|
|
480
|
+
const decoratedChildren = children;
|
|
481
|
+
const needsTitleDecorationsPortal = !!titleDescription || !!belowTitleBlock;
|
|
432
482
|
useEffect(() => {
|
|
433
483
|
if (!needsTitleDecorationsPortal) {
|
|
434
484
|
setTitlePortalHost(null);
|
|
@@ -451,13 +501,28 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
451
501
|
const titleDecorationsPortal = needsTitleDecorationsPortal && titlePortalHost ? createPortal(/* @__PURE__ */ jsx(TitleDecorations, {
|
|
452
502
|
description: titleDescription,
|
|
453
503
|
belowTitle: belowTitleBlock
|
|
454
|
-
}), titlePortalHost) : null;
|
|
455
|
-
const
|
|
504
|
+
}), titlePortalHost, "title-decorations") : null;
|
|
505
|
+
const titleControlsPortal = showActionsInToc && titleControlsPortalHost ? createPortal(/* @__PURE__ */ jsx(ThreadlinePageControls, {}), titleControlsPortalHost, "title-controls") : null;
|
|
506
|
+
const tocActionsPortal = showActionsInToc && tocActionsPortalHost ? createPortal(/* @__PURE__ */ jsx("div", {
|
|
507
|
+
className: "fd-actions-toc-portal not-prose",
|
|
508
|
+
children: /* @__PURE__ */ jsx(PageActions, {
|
|
509
|
+
copyMarkdown,
|
|
510
|
+
openDocs,
|
|
511
|
+
providers: openDocsProviders,
|
|
512
|
+
openDocsTarget,
|
|
513
|
+
openDocsPrompt,
|
|
514
|
+
alignment: "left",
|
|
515
|
+
variant: "rail",
|
|
516
|
+
githubFileUrl,
|
|
517
|
+
analytics
|
|
518
|
+
})
|
|
519
|
+
}), tocActionsPortalHost, "toc-actions") : null;
|
|
520
|
+
const renderedChildren = Children.toArray(decoratedChildren).map((child, index) => /* @__PURE__ */ jsx(Fragment, { children: child }, `fd-rendered-child-${index}`));
|
|
456
521
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
457
522
|
structuredDataJson && /* @__PURE__ */ jsx("script", {
|
|
458
523
|
type: "application/ld+json",
|
|
459
524
|
dangerouslySetInnerHTML: { __html: escapeJsonLdForScript(structuredDataJson) }
|
|
460
|
-
}),
|
|
525
|
+
}, "structured-data"),
|
|
461
526
|
llmsTxtEnabled && /* @__PURE__ */ jsx("a", {
|
|
462
527
|
href: `/llms.txt${llmsLangQuery}`,
|
|
463
528
|
className: "fd-agent-llms-directive",
|
|
@@ -465,7 +530,9 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
465
530
|
tabIndex: -1,
|
|
466
531
|
"aria-hidden": "true",
|
|
467
532
|
children: "llms.txt"
|
|
468
|
-
}),
|
|
533
|
+
}, "llms-txt"),
|
|
534
|
+
titleControlsPortal,
|
|
535
|
+
tocActionsPortal,
|
|
469
536
|
/* @__PURE__ */ jsxs(DocsPage, {
|
|
470
537
|
full: false,
|
|
471
538
|
toc,
|
|
@@ -484,7 +551,7 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
484
551
|
pathname,
|
|
485
552
|
publicPath: resolvedPublicPath,
|
|
486
553
|
locale: activeLocale
|
|
487
|
-
}),
|
|
554
|
+
}, "breadcrumb"),
|
|
488
555
|
showActionsAboveTitle && /* @__PURE__ */ jsxs("div", {
|
|
489
556
|
className: "fd-below-title-block not-prose",
|
|
490
557
|
children: [/* @__PURE__ */ jsx("div", {
|
|
@@ -497,11 +564,12 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
497
564
|
openDocsTarget,
|
|
498
565
|
openDocsPrompt,
|
|
499
566
|
alignment: pageActionsAlignment,
|
|
567
|
+
variant: "default",
|
|
500
568
|
githubFileUrl,
|
|
501
569
|
analytics
|
|
502
570
|
})
|
|
503
|
-
}), readingTimeBlock]
|
|
504
|
-
}),
|
|
571
|
+
}, "actions"), readingTimeBlock]
|
|
572
|
+
}, "actions-above-title"),
|
|
505
573
|
!showReadingTimeAboveTitle && !showReadingTimeBelowTitle ? readingTimeBlock : null,
|
|
506
574
|
/* @__PURE__ */ jsxs(DocsBody, {
|
|
507
575
|
style: {
|
|
@@ -512,7 +580,7 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
512
580
|
/* @__PURE__ */ jsx("div", {
|
|
513
581
|
style: { flex: 1 },
|
|
514
582
|
children: renderedChildren
|
|
515
|
-
}),
|
|
583
|
+
}, "content"),
|
|
516
584
|
titleDecorationsPortal,
|
|
517
585
|
!isChangelogRoute && feedbackEnabled && /* @__PURE__ */ jsx(DocsFeedback, {
|
|
518
586
|
pathname: normalizedPath,
|
|
@@ -525,11 +593,11 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
525
593
|
submitLabel: feedbackSubmitLabel,
|
|
526
594
|
onFeedback: feedbackOnFeedback,
|
|
527
595
|
analytics
|
|
528
|
-
}),
|
|
596
|
+
}, "feedback"),
|
|
529
597
|
showFooter && /* @__PURE__ */ jsxs("div", {
|
|
530
598
|
className: "not-prose fd-page-footer",
|
|
531
599
|
children: [
|
|
532
|
-
githubFileUrl && /* @__PURE__ */ jsx(EditOnGitHub, { href: githubFileUrl }),
|
|
600
|
+
githubFileUrl && /* @__PURE__ */ jsx(EditOnGitHub, { href: githubFileUrl }, "github"),
|
|
533
601
|
llmsTxtEnabled && /* @__PURE__ */ jsxs("span", {
|
|
534
602
|
className: "fd-llms-txt-links",
|
|
535
603
|
children: [/* @__PURE__ */ jsx("a", {
|
|
@@ -545,17 +613,17 @@ function DocsPageClient({ tocEnabled, tocStyle = "default", breadcrumbEnabled =
|
|
|
545
613
|
className: "fd-llms-txt-link",
|
|
546
614
|
children: "llms-full.txt"
|
|
547
615
|
})]
|
|
548
|
-
}),
|
|
616
|
+
}, "llms-links"),
|
|
549
617
|
showLastUpdatedInFooter && lastModified && /* @__PURE__ */ jsxs("span", {
|
|
550
618
|
className: "fd-last-updated-footer",
|
|
551
619
|
children: ["Last updated ", lastModified]
|
|
552
|
-
})
|
|
620
|
+
}, "last-updated")
|
|
553
621
|
]
|
|
554
|
-
})
|
|
622
|
+
}, "footer")
|
|
555
623
|
]
|
|
556
|
-
})
|
|
624
|
+
}, "body")
|
|
557
625
|
]
|
|
558
|
-
})
|
|
626
|
+
}, "docs-page")
|
|
559
627
|
] });
|
|
560
628
|
}
|
|
561
629
|
|
package/dist/index.d.mts
CHANGED
|
@@ -8,6 +8,7 @@ import { DocsPageClient } from "./docs-page-client.mjs";
|
|
|
8
8
|
import { HardlineUIDefaults, hardline } from "./hardline/index.mjs";
|
|
9
9
|
import { RootProvider } from "./provider.mjs";
|
|
10
10
|
import { LedgerUIDefaults, ledger } from "./ledger/index.mjs";
|
|
11
|
+
import { ThreadlineUIDefaults, threadline, threadlinePageActions } from "./threadline/index.mjs";
|
|
11
12
|
import { DocsFeedback, DocsFeedbackProps } from "./docs-feedback.mjs";
|
|
12
13
|
import { PageActions } from "./page-actions.mjs";
|
|
13
14
|
import { withLangInUrl } from "./i18n.mjs";
|
|
@@ -19,4 +20,4 @@ import { AIConfig, BreadcrumbConfig, ChangelogConfig, ChangelogFrontmatter, Copy
|
|
|
19
20
|
import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
|
|
20
21
|
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
|
21
22
|
import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
|
|
22
|
-
export { type AIConfig, Agent, type BreadcrumbConfig, type ChangelogConfig, type ChangelogFrontmatter, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CodeGroup, CommandGridUIDefaults, ConcreteUIDefaults, type CopyMarkdownConfig, DocsBody, DocsClientHooks, DocsCommandSearch, type DocsConfig, DocsFeedback, type DocsFeedbackData, type DocsFeedbackProps, type DocsFeedbackValue, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FeedbackConfig, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, type HoverLinkProps, LedgerUIDefaults, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageFrontmatter, Pre, Prompt, type PromptProps, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, type TypographyConfig, type UIConfig, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, ledger, withLangInUrl };
|
|
23
|
+
export { type AIConfig, Agent, type BreadcrumbConfig, type ChangelogConfig, type ChangelogFrontmatter, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CodeGroup, CommandGridUIDefaults, ConcreteUIDefaults, type CopyMarkdownConfig, DocsBody, DocsClientHooks, DocsCommandSearch, type DocsConfig, DocsFeedback, type DocsFeedbackData, type DocsFeedbackProps, type DocsFeedbackValue, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FeedbackConfig, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, type HoverLinkProps, LedgerUIDefaults, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageFrontmatter, Pre, Prompt, type PromptProps, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, ThreadlineUIDefaults, type TypographyConfig, type UIConfig, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, ledger, threadline, threadlinePageActions, withLangInUrl };
|
package/dist/index.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { CommandGridUIDefaults, commandGrid } from "./command-grid/index.mjs";
|
|
|
10
10
|
import { ConcreteUIDefaults, concrete } from "./concrete/index.mjs";
|
|
11
11
|
import { HardlineUIDefaults, hardline } from "./hardline/index.mjs";
|
|
12
12
|
import { LedgerUIDefaults, ledger } from "./ledger/index.mjs";
|
|
13
|
+
import { ThreadlineUIDefaults, threadline, threadlinePageActions } from "./threadline/index.mjs";
|
|
13
14
|
import { DocsClientHooks } from "./docs-client-hooks.mjs";
|
|
14
15
|
import { HoverLink } from "./hover-link.mjs";
|
|
15
16
|
import { Prompt } from "./prompt.mjs";
|
|
@@ -20,4 +21,4 @@ import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
|
|
|
20
21
|
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
|
21
22
|
import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
|
|
22
23
|
|
|
23
|
-
export { Agent, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CodeGroup, CommandGridUIDefaults, ConcreteUIDefaults, DocsBody, DocsClientHooks, DocsCommandSearch, DocsFeedback, DocsLayout, DocsPage, DocsPageClient, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, LedgerUIDefaults, PageActions, Pre, Prompt, RootProvider, Tab, Tabs, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, ledger, withLangInUrl };
|
|
24
|
+
export { Agent, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CodeGroup, CommandGridUIDefaults, ConcreteUIDefaults, DocsBody, DocsClientHooks, DocsCommandSearch, DocsFeedback, DocsLayout, DocsPage, DocsPageClient, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, LedgerUIDefaults, PageActions, Pre, Prompt, RootProvider, Tab, Tabs, ThreadlineUIDefaults, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, ledger, threadline, threadlinePageActions, withLangInUrl };
|
|
@@ -236,6 +236,7 @@ function LocaleThemeControl({ locales, defaultLocale, locale, showThemeToggle =
|
|
|
236
236
|
}), showThemeToggle && (themeMode === "light-dark" ? /* @__PURE__ */ jsxs("button", {
|
|
237
237
|
type: "button",
|
|
238
238
|
"aria-label": "Toggle theme",
|
|
239
|
+
"data-theme-toggle": true,
|
|
239
240
|
onClick: () => applyTheme(resolvedTheme === "light" ? "dark" : "light"),
|
|
240
241
|
style: toggleContainerStyle,
|
|
241
242
|
children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -251,6 +252,7 @@ function LocaleThemeControl({ locales, defaultLocale, locale, showThemeToggle =
|
|
|
251
252
|
/* @__PURE__ */ jsx("button", {
|
|
252
253
|
type: "button",
|
|
253
254
|
"aria-label": "light",
|
|
255
|
+
"data-theme-toggle": true,
|
|
254
256
|
style: getToggleItemStyle(themeValue === "light"),
|
|
255
257
|
onClick: () => applyTheme("light"),
|
|
256
258
|
children: /* @__PURE__ */ jsx(SunIcon, {})
|
|
@@ -258,6 +260,7 @@ function LocaleThemeControl({ locales, defaultLocale, locale, showThemeToggle =
|
|
|
258
260
|
/* @__PURE__ */ jsx("button", {
|
|
259
261
|
type: "button",
|
|
260
262
|
"aria-label": "dark",
|
|
263
|
+
"data-theme-toggle": true,
|
|
261
264
|
style: getToggleItemStyle(themeValue === "dark"),
|
|
262
265
|
onClick: () => applyTheme("dark"),
|
|
263
266
|
children: /* @__PURE__ */ jsx(MoonIcon, {})
|
|
@@ -265,6 +268,7 @@ function LocaleThemeControl({ locales, defaultLocale, locale, showThemeToggle =
|
|
|
265
268
|
/* @__PURE__ */ jsx("button", {
|
|
266
269
|
type: "button",
|
|
267
270
|
"aria-label": "system",
|
|
271
|
+
"data-theme-toggle": true,
|
|
268
272
|
style: getToggleItemStyle(themeValue === "system"),
|
|
269
273
|
onClick: () => applyTheme("system"),
|
|
270
274
|
children: /* @__PURE__ */ jsx("span", {
|
package/dist/page-actions.d.mts
CHANGED
|
@@ -16,6 +16,7 @@ interface PageActionsProps {
|
|
|
16
16
|
openDocsTarget?: "markdown" | "page" | "source" | "github";
|
|
17
17
|
openDocsPrompt?: string;
|
|
18
18
|
alignment?: "left" | "right";
|
|
19
|
+
variant?: "default" | "rail";
|
|
19
20
|
/** GitHub file URL (edit view) for the current page. Used when urlTemplate contains {githubUrl}. */
|
|
20
21
|
githubFileUrl?: string | null;
|
|
21
22
|
analytics?: boolean;
|
|
@@ -27,6 +28,7 @@ declare function PageActions({
|
|
|
27
28
|
openDocsTarget,
|
|
28
29
|
openDocsPrompt,
|
|
29
30
|
alignment,
|
|
31
|
+
variant,
|
|
30
32
|
githubFileUrl,
|
|
31
33
|
analytics
|
|
32
34
|
}: PageActionsProps): react_jsx_runtime0.JSX.Element | null;
|
package/dist/page-actions.mjs
CHANGED
|
@@ -67,6 +67,46 @@ const ExternalLinkIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
|
67
67
|
})
|
|
68
68
|
]
|
|
69
69
|
});
|
|
70
|
+
const FileTextIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
71
|
+
width: "14",
|
|
72
|
+
height: "14",
|
|
73
|
+
viewBox: "0 0 24 24",
|
|
74
|
+
fill: "none",
|
|
75
|
+
stroke: "currentColor",
|
|
76
|
+
strokeWidth: "2",
|
|
77
|
+
strokeLinecap: "round",
|
|
78
|
+
strokeLinejoin: "round",
|
|
79
|
+
children: [
|
|
80
|
+
/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
81
|
+
/* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
|
|
82
|
+
/* @__PURE__ */ jsx("path", { d: "M10 9H8" }),
|
|
83
|
+
/* @__PURE__ */ jsx("path", { d: "M16 13H8" }),
|
|
84
|
+
/* @__PURE__ */ jsx("path", { d: "M16 17H8" })
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
const GitHubIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
88
|
+
width: "14",
|
|
89
|
+
height: "14",
|
|
90
|
+
viewBox: "0 0 24 24",
|
|
91
|
+
fill: "currentColor",
|
|
92
|
+
"aria-hidden": "true",
|
|
93
|
+
children: /* @__PURE__ */ jsx("path", { d: "M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.92.58.11.79-.25.79-.56v-2.02c-3.2.7-3.88-1.37-3.88-1.37-.53-1.33-1.29-1.69-1.29-1.69-1.05-.72.08-.71.08-.71 1.16.08 1.77 1.2 1.77 1.2 1.03 1.76 2.71 1.25 3.37.96.1-.75.4-1.25.73-1.54-2.56-.29-5.26-1.28-5.26-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.47.11-3.05 0 0 .97-.31 3.18 1.18a10.9 10.9 0 0 1 5.8 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.58.23 2.76.11 3.05.74.81 1.19 1.84 1.19 3.1 0 4.43-2.7 5.41-5.27 5.7.41.36.78 1.06.78 2.14v3.03c0 .31.21.67.8.56A11.5 11.5 0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5Z" })
|
|
94
|
+
});
|
|
95
|
+
const SparklesIcon = () => /* @__PURE__ */ jsxs("svg", {
|
|
96
|
+
width: "14",
|
|
97
|
+
height: "14",
|
|
98
|
+
viewBox: "0 0 24 24",
|
|
99
|
+
fill: "none",
|
|
100
|
+
stroke: "currentColor",
|
|
101
|
+
strokeWidth: "2",
|
|
102
|
+
strokeLinecap: "round",
|
|
103
|
+
strokeLinejoin: "round",
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ jsx("path", { d: "M9.94 15.5 8.5 21l-1.44-5.5L1.5 14l5.56-1.5L8.5 7l1.44 5.5L15.5 14Z" }),
|
|
106
|
+
/* @__PURE__ */ jsx("path", { d: "M17.5 3 18 5l2 .5-2 .5-.5 2-.5-2-2-.5 2-.5Z" }),
|
|
107
|
+
/* @__PURE__ */ jsx("path", { d: "M19 11.5 20 15l3.5 1-3.5 1-1 3.5-1-3.5-3.5-1 3.5-1Z" })
|
|
108
|
+
]
|
|
109
|
+
});
|
|
70
110
|
const DEFAULT_PROVIDERS = [{
|
|
71
111
|
name: "ChatGPT",
|
|
72
112
|
urlTemplate: "https://chatgpt.com/?q={prompt}"
|
|
@@ -92,30 +132,39 @@ function pageUrlToMarkdownUrl(pageUrl) {
|
|
|
92
132
|
function fillPromptTemplate(template, values) {
|
|
93
133
|
return template.replace(/\{pageUrl\}/g, values.pageUrl).replace(/\{markdownUrl\}/g, values.markdownUrl).replace(/\{sourceUrl\}/g, values.sourceUrl).replace(/\{mdxUrl\}/g, values.sourceUrl).replace(/\{githubUrl\}/g, values.githubUrl).replace(/\{url\}/g, values.url);
|
|
94
134
|
}
|
|
95
|
-
function PageActions({ copyMarkdown, openDocs, providers, openDocsTarget = DEFAULT_OPEN_DOCS_TARGET, openDocsPrompt = DEFAULT_OPEN_DOCS_PROMPT, alignment = "left", githubFileUrl, analytics = false }) {
|
|
135
|
+
function PageActions({ copyMarkdown, openDocs, providers, openDocsTarget = DEFAULT_OPEN_DOCS_TARGET, openDocsPrompt = DEFAULT_OPEN_DOCS_PROMPT, alignment = "left", variant = "default", githubFileUrl, analytics = false }) {
|
|
96
136
|
const [copied, setCopied] = useState(false);
|
|
97
137
|
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
98
138
|
const dropdownRef = useRef(null);
|
|
99
139
|
const pathname = usePathname();
|
|
100
140
|
const resolvedProviders = providers ?? DEFAULT_PROVIDERS;
|
|
141
|
+
const cleanedPathname = pathname.replace(/\/+$/, "") || "/";
|
|
142
|
+
const markdownHref = cleanedPathname === "/" ? "/index.md" : `${cleanedPathname.replace(/\.md$/, "")}.md`;
|
|
101
143
|
const handleCopyMarkdown = useCallback(async () => {
|
|
102
144
|
try {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
await
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
let content = "";
|
|
146
|
+
try {
|
|
147
|
+
const response = await fetch(markdownHref, { headers: { Accept: "text/markdown" } });
|
|
148
|
+
if (response.ok) content = await response.text();
|
|
149
|
+
} catch {}
|
|
150
|
+
if (!content) content = document.querySelector("article")?.innerText || "";
|
|
151
|
+
if (!content) return;
|
|
152
|
+
await navigator.clipboard.writeText(content);
|
|
153
|
+
if (analytics) emitClientAnalyticsEvent({
|
|
154
|
+
type: "page_action_copy_markdown",
|
|
155
|
+
properties: {
|
|
156
|
+
contentLength: content.length,
|
|
157
|
+
pathname
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
setCopied(true);
|
|
161
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
117
162
|
} catch {}
|
|
118
|
-
}, [
|
|
163
|
+
}, [
|
|
164
|
+
analytics,
|
|
165
|
+
markdownHref,
|
|
166
|
+
pathname
|
|
167
|
+
]);
|
|
119
168
|
const handleOpen = useCallback((provider) => {
|
|
120
169
|
const template = provider.urlTemplate;
|
|
121
170
|
const githubUrl = githubFileUrl ?? "";
|
|
@@ -157,6 +206,15 @@ function PageActions({ copyMarkdown, openDocs, providers, openDocsTarget = DEFAU
|
|
|
157
206
|
openDocsPrompt,
|
|
158
207
|
openDocsTarget
|
|
159
208
|
]);
|
|
209
|
+
const handleAskAI = useCallback(() => {
|
|
210
|
+
const trigger = document.querySelector(".fd-ai-fm-trigger-btn, [data-ai-trigger], button[aria-label='Ask AI']");
|
|
211
|
+
if (!trigger) return;
|
|
212
|
+
trigger.click();
|
|
213
|
+
if (analytics) emitClientAnalyticsEvent({
|
|
214
|
+
type: "page_action_ask_ai",
|
|
215
|
+
properties: { pathname }
|
|
216
|
+
});
|
|
217
|
+
}, [analytics, pathname]);
|
|
160
218
|
useEffect(() => {
|
|
161
219
|
if (!dropdownOpen) return;
|
|
162
220
|
function handleClick(e) {
|
|
@@ -169,7 +227,41 @@ function PageActions({ copyMarkdown, openDocs, providers, openDocsTarget = DEFAU
|
|
|
169
227
|
setDropdownOpen(false);
|
|
170
228
|
setCopied(false);
|
|
171
229
|
}, [pathname]);
|
|
172
|
-
if (!copyMarkdown && !openDocs) return null;
|
|
230
|
+
if (variant !== "rail" && !copyMarkdown && !openDocs) return null;
|
|
231
|
+
if (variant === "rail") return /* @__PURE__ */ jsxs("div", {
|
|
232
|
+
className: "fd-page-actions fd-page-actions-rail",
|
|
233
|
+
"data-page-actions": true,
|
|
234
|
+
"data-page-actions-variant": "rail",
|
|
235
|
+
children: [
|
|
236
|
+
copyMarkdown && /* @__PURE__ */ jsxs("button", {
|
|
237
|
+
type: "button",
|
|
238
|
+
onClick: handleCopyMarkdown,
|
|
239
|
+
className: "fd-page-action-btn",
|
|
240
|
+
"data-copied": copied,
|
|
241
|
+
children: [copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {}), /* @__PURE__ */ jsx("span", { children: copied ? "Copied!" : "Copy page" })]
|
|
242
|
+
}),
|
|
243
|
+
openDocs && /* @__PURE__ */ jsxs("a", {
|
|
244
|
+
className: "fd-page-action-btn",
|
|
245
|
+
href: markdownHref,
|
|
246
|
+
target: "_blank",
|
|
247
|
+
rel: "noreferrer",
|
|
248
|
+
children: [/* @__PURE__ */ jsx(FileTextIcon, {}), /* @__PURE__ */ jsx("span", { children: "View as Markdown" })]
|
|
249
|
+
}),
|
|
250
|
+
githubFileUrl && /* @__PURE__ */ jsxs("a", {
|
|
251
|
+
className: "fd-page-action-btn",
|
|
252
|
+
href: githubFileUrl,
|
|
253
|
+
target: "_blank",
|
|
254
|
+
rel: "noreferrer",
|
|
255
|
+
children: [/* @__PURE__ */ jsx(GitHubIcon, {}), /* @__PURE__ */ jsx("span", { children: "Edit on GitHub" })]
|
|
256
|
+
}),
|
|
257
|
+
/* @__PURE__ */ jsxs("button", {
|
|
258
|
+
type: "button",
|
|
259
|
+
onClick: handleAskAI,
|
|
260
|
+
className: "fd-page-action-btn",
|
|
261
|
+
children: [/* @__PURE__ */ jsx(SparklesIcon, {}), /* @__PURE__ */ jsx("span", { children: "Ask AI" })]
|
|
262
|
+
})
|
|
263
|
+
]
|
|
264
|
+
});
|
|
173
265
|
return /* @__PURE__ */ jsxs("div", {
|
|
174
266
|
className: "fd-page-actions",
|
|
175
267
|
"data-page-actions": true,
|