docstra 1.6.3 → 1.7.1
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/README.md +120 -60
- package/dist/client/index.d.mts +12 -6
- package/dist/client/index.d.ts +12 -6
- package/dist/client/index.js +269 -285
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +266 -283
- package/dist/client/index.mjs.map +1 -1
- package/dist/server/docstra-loader.d.mts +5 -0
- package/dist/server/docstra-loader.d.ts +5 -0
- package/dist/server/docstra-loader.js +30894 -0
- package/dist/server/docstra-loader.js.map +1 -0
- package/dist/server/docstra-loader.mjs +30885 -0
- package/dist/server/docstra-loader.mjs.map +1 -0
- package/dist/server/index.d.mts +20 -5
- package/dist/server/index.d.ts +20 -5
- package/dist/server/index.js +104 -88
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +102 -86
- package/dist/server/index.mjs.map +1 -1
- package/dist/{types-BCr1htTq.d.mts → types-QzxGYJU4.d.mts} +22 -12
- package/dist/{types-BCr1htTq.d.ts → types-QzxGYJU4.d.ts} +22 -12
- package/package.json +2 -1
package/dist/client/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(client_exports, {
|
|
|
36
36
|
DocstraHeader: () => DocstraHeader,
|
|
37
37
|
DocstraPage: () => DocstraPage,
|
|
38
38
|
DocstraProvider: () => DocstraProvider,
|
|
39
|
+
DocstraSearchBox: () => DocstraSearchBox,
|
|
39
40
|
DocstraSidebar: () => DocstraSidebar,
|
|
40
41
|
DocstraTOC: () => DocstraTOC,
|
|
41
42
|
useDocstra: () => useDocstra
|
|
@@ -46,7 +47,7 @@ module.exports = __toCommonJS(client_exports);
|
|
|
46
47
|
var import_react2 = require("react");
|
|
47
48
|
var import_react_toast_msg = require("react-toast-msg");
|
|
48
49
|
|
|
49
|
-
// src/client/search-box.tsx
|
|
50
|
+
// src/client/components/search-box.tsx
|
|
50
51
|
var import_lucide_react = require("lucide-react");
|
|
51
52
|
|
|
52
53
|
// src/utils/cn.ts
|
|
@@ -56,7 +57,7 @@ function cn(...inputs) {
|
|
|
56
57
|
return (0, import_tailwind_merge.twMerge)((0, import_clsx.default)(inputs));
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
// src/client/search-box.tsx
|
|
60
|
+
// src/client/components/search-box.tsx
|
|
60
61
|
var import_react = require("react");
|
|
61
62
|
var import_fuse = __toESM(require("fuse.js"));
|
|
62
63
|
var import_link = __toESM(require("next/link"));
|
|
@@ -80,23 +81,26 @@ function DocstraSearchBox() {
|
|
|
80
81
|
};
|
|
81
82
|
}, []);
|
|
82
83
|
const fuse = (0, import_react.useMemo)(() => {
|
|
84
|
+
if (!docs || docs.length === 0) return null;
|
|
83
85
|
return new import_fuse.default(docs, {
|
|
84
|
-
keys: ["
|
|
86
|
+
keys: ["data.metadata.title", "data.metadata.description"],
|
|
85
87
|
threshold: 0.3
|
|
86
88
|
});
|
|
87
89
|
}, [docs]);
|
|
88
90
|
(0, import_react.useEffect)(() => {
|
|
89
|
-
if (searchQuery) {
|
|
91
|
+
if (searchQuery && fuse) {
|
|
90
92
|
const results = fuse.search(searchQuery);
|
|
91
93
|
setSearchResults(results.map((r) => r.item));
|
|
94
|
+
} else if (!searchQuery) {
|
|
95
|
+
setSearchResults([]);
|
|
92
96
|
}
|
|
93
|
-
}, [searchQuery]);
|
|
97
|
+
}, [searchQuery, fuse]);
|
|
94
98
|
const onSearchHandler = (e) => {
|
|
95
99
|
e.preventDefault();
|
|
96
100
|
if (searchQuery) {
|
|
97
101
|
const component = searchResults[0];
|
|
98
102
|
if (component) {
|
|
99
|
-
router.push(`/docs/${component.
|
|
103
|
+
router.push(`/docs/${component.slug}`);
|
|
100
104
|
setSearchQuery("");
|
|
101
105
|
setOpenSearchBox(false);
|
|
102
106
|
}
|
|
@@ -159,18 +163,18 @@ function DocstraSearchBox() {
|
|
|
159
163
|
searchResults.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
160
164
|
import_link.default,
|
|
161
165
|
{
|
|
162
|
-
href: `/docs/${item.
|
|
163
|
-
|
|
166
|
+
href: `/docs/${item.slug === "index" ? "" : item.slug}`,
|
|
167
|
+
onClick: () => {
|
|
164
168
|
setOpenSearchBox(false);
|
|
165
169
|
setSearchQuery("");
|
|
166
170
|
},
|
|
167
171
|
className: "w-full hover:bg-gray-100/70 border-b border-slate-200 transition-all py-4 px-4 last:mb-2",
|
|
168
172
|
children: [
|
|
169
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "font-medium", children: item.
|
|
170
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm mt-1 text-gray-500", children: item.
|
|
173
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "font-medium", children: item.data?.metadata?.title || item.slug }),
|
|
174
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm mt-1 text-gray-500", children: item.data?.metadata?.description })
|
|
171
175
|
]
|
|
172
176
|
},
|
|
173
|
-
item.
|
|
177
|
+
item.slug
|
|
174
178
|
)),
|
|
175
179
|
searchQuery && searchResults.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-gray-500 text-center py-20", children: "No results found" })
|
|
176
180
|
]
|
|
@@ -190,8 +194,15 @@ function DocstraProvider({
|
|
|
190
194
|
children,
|
|
191
195
|
docstraConfig,
|
|
192
196
|
docs,
|
|
193
|
-
pageData
|
|
197
|
+
pageData: initialPageData,
|
|
198
|
+
slug
|
|
194
199
|
}) {
|
|
200
|
+
const pageData = initialPageData || (() => {
|
|
201
|
+
const normalizedSlug = Array.isArray(slug) ? slug.length === 0 ? "index" : slug.join("/") : slug || "index";
|
|
202
|
+
return docs.find((d) => d.slug === normalizedSlug);
|
|
203
|
+
})();
|
|
204
|
+
if (!pageData) {
|
|
205
|
+
}
|
|
195
206
|
const [openSidebar, setOpenSidebar] = (0, import_react2.useState)(false);
|
|
196
207
|
const [openSearchBox, setOpenSearchBox] = (0, import_react2.useState)(false);
|
|
197
208
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
@@ -220,7 +231,7 @@ function useDocstra() {
|
|
|
220
231
|
return ctx;
|
|
221
232
|
}
|
|
222
233
|
|
|
223
|
-
// src/client/header.tsx
|
|
234
|
+
// src/client/components/header.tsx
|
|
224
235
|
var import_lucide_react2 = require("lucide-react");
|
|
225
236
|
var import_react3 = require("react");
|
|
226
237
|
var import_link2 = __toESM(require("next/link"));
|
|
@@ -258,7 +269,7 @@ function DocstraHeader() {
|
|
|
258
269
|
] });
|
|
259
270
|
}
|
|
260
271
|
|
|
261
|
-
// src/client/sidebar.tsx
|
|
272
|
+
// src/client/components/sidebar.tsx
|
|
262
273
|
var import_lucide_react3 = require("lucide-react");
|
|
263
274
|
var import_navigation2 = require("next/navigation");
|
|
264
275
|
|
|
@@ -269,7 +280,7 @@ function getIcon(name) {
|
|
|
269
280
|
return Icons[name];
|
|
270
281
|
}
|
|
271
282
|
|
|
272
|
-
// src/client/sidebar.tsx
|
|
283
|
+
// src/client/components/sidebar.tsx
|
|
273
284
|
var import_link3 = __toESM(require("next/link"));
|
|
274
285
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
275
286
|
function DocstraSidebar() {
|
|
@@ -339,68 +350,208 @@ function DocstraSidebar() {
|
|
|
339
350
|
] });
|
|
340
351
|
}
|
|
341
352
|
|
|
342
|
-
// src/client/
|
|
353
|
+
// src/client/components/docstra-toc.tsx
|
|
354
|
+
var import_lucide_react4 = require("lucide-react");
|
|
355
|
+
var import_navigation3 = require("next/navigation");
|
|
356
|
+
var import_react4 = require("react");
|
|
343
357
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
344
|
-
function
|
|
345
|
-
|
|
358
|
+
function DocstraTOC() {
|
|
359
|
+
const [activeId, setActiveId] = (0, import_react4.useState)(null);
|
|
360
|
+
const [scrollDir, setScrollDir] = (0, import_react4.useState)("down");
|
|
361
|
+
const [isScrolled, setIsScrolled] = (0, import_react4.useState)(false);
|
|
362
|
+
const [isManualClick, setIsManualClick] = (0, import_react4.useState)(false);
|
|
363
|
+
const { docstraConfig, pageData } = useDocstra();
|
|
364
|
+
const mdxFilePath = pageData?.path;
|
|
365
|
+
const headings = pageData?.data?.tableOfContents || [];
|
|
366
|
+
const lastScrollY = (0, import_react4.useRef)(0);
|
|
367
|
+
const observerRef = (0, import_react4.useRef)(null);
|
|
368
|
+
const pathname = (0, import_navigation3.usePathname)();
|
|
369
|
+
const baseUrlOfGithub = docstraConfig?.githubRepo || "https://github.com/sudhucodes/docstra";
|
|
370
|
+
const githubLink = `${baseUrlOfGithub}/edit/main/${mdxFilePath}`;
|
|
371
|
+
(0, import_react4.useEffect)(() => {
|
|
372
|
+
const onScroll = () => {
|
|
373
|
+
const currentY = window.scrollY;
|
|
374
|
+
setScrollDir(currentY > lastScrollY.current ? "down" : "up");
|
|
375
|
+
setIsScrolled(currentY > 100);
|
|
376
|
+
lastScrollY.current = currentY;
|
|
377
|
+
};
|
|
378
|
+
window.addEventListener("scroll", onScroll);
|
|
379
|
+
return () => window.removeEventListener("scroll", onScroll);
|
|
380
|
+
}, []);
|
|
381
|
+
(0, import_react4.useEffect)(() => {
|
|
382
|
+
const allHeadings = document.querySelectorAll(`h2[id], h3[id]`);
|
|
383
|
+
const observer = new IntersectionObserver(
|
|
384
|
+
(entries) => {
|
|
385
|
+
if (isManualClick) return;
|
|
386
|
+
const visible = entries.filter((e) => e.isIntersecting).sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
|
|
387
|
+
if (visible.length > 0) {
|
|
388
|
+
const nextActive = scrollDir === "down" ? visible[0].target.id : visible[visible.length - 1].target.id;
|
|
389
|
+
setActiveId(nextActive);
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
rootMargin: "-40% 0px -50% 0px",
|
|
394
|
+
threshold: [0, 0.2, 0.6, 1]
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
allHeadings.forEach((heading) => observer.observe(heading));
|
|
398
|
+
observerRef.current = observer;
|
|
399
|
+
return () => observer.disconnect();
|
|
400
|
+
}, [pathname, scrollDir, isManualClick]);
|
|
401
|
+
(0, import_react4.useEffect)(() => {
|
|
402
|
+
const scrolled = window.scrollY > 100;
|
|
403
|
+
!scrolled && setActiveId(headings[0]?.id);
|
|
404
|
+
}, [headings]);
|
|
405
|
+
(0, import_react4.useEffect)(() => {
|
|
406
|
+
if (!activeId) return;
|
|
407
|
+
const container = document.querySelector(".toc-scroll-container");
|
|
408
|
+
if (!container) return;
|
|
409
|
+
const activeLink = container.querySelector(`a[href="#${activeId}"]`);
|
|
410
|
+
if (!activeLink) return;
|
|
411
|
+
const containerRect = container.getBoundingClientRect();
|
|
412
|
+
const linkRect = activeLink.getBoundingClientRect();
|
|
413
|
+
const isOutOfView = linkRect.top < containerRect.top || linkRect.bottom > containerRect.bottom;
|
|
414
|
+
if (isOutOfView) {
|
|
415
|
+
activeLink.scrollIntoView({
|
|
416
|
+
behavior: "smooth",
|
|
417
|
+
block: "nearest"
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}, [activeId]);
|
|
421
|
+
(0, import_react4.useEffect)(() => {
|
|
422
|
+
if (!isManualClick) return;
|
|
423
|
+
const timer = setTimeout(() => setIsManualClick(false), 800);
|
|
424
|
+
return () => clearTimeout(timer);
|
|
425
|
+
}, [isManualClick]);
|
|
426
|
+
const handleClick = (id) => {
|
|
427
|
+
setActiveId(id);
|
|
428
|
+
setIsManualClick(true);
|
|
429
|
+
};
|
|
430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("aside", { className: "sticky top-18 text-sm hidden xl:block text-gray-500 shrink-0 h-[calc(100svh-72px)] w-64 border-l border-gray-200 p-6 overflow-y-auto", children: [
|
|
431
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "flex items-center gap-2 mb-5", children: [
|
|
432
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.TextAlignStartIcon, { className: "size-4" }),
|
|
433
|
+
"On this page"
|
|
434
|
+
] }),
|
|
435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "toc-scroll-container max-h-3/4 overflow-y-auto scrollbar-none", children: headings.map((h2) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("li", { children: [
|
|
436
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TableOfContentsLink, { heading: h2, activeId, handleClick }),
|
|
437
|
+
h2.children.map((h3) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
438
|
+
TableOfContentsLink,
|
|
439
|
+
{
|
|
440
|
+
heading: h3,
|
|
441
|
+
activeId,
|
|
442
|
+
handleClick,
|
|
443
|
+
className: "pl-8"
|
|
444
|
+
},
|
|
445
|
+
h3.id
|
|
446
|
+
))
|
|
447
|
+
] }, h2.id)) }),
|
|
448
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("hr", { className: "my-6 border-gray-200" }),
|
|
449
|
+
docstraConfig.editOnGithub && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
450
|
+
"a",
|
|
451
|
+
{
|
|
452
|
+
href: githubLink,
|
|
453
|
+
rel: "noopener noreferrer",
|
|
454
|
+
className: "flex items-center gap-2 text-gray-400 hover:text-gray-700 transition",
|
|
455
|
+
children: [
|
|
456
|
+
"Edit this page on GitHub",
|
|
457
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.SquareArrowOutUpRightIcon, { className: "size-4" })
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
),
|
|
461
|
+
isScrolled && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
462
|
+
"button",
|
|
463
|
+
{
|
|
464
|
+
onClick: () => scrollTo({ top: 0, behavior: "smooth" }),
|
|
465
|
+
className: "flex items-center cursor-pointer gap-2 mt-3 text-gray-400 hover:text-gray-700 transition",
|
|
466
|
+
children: [
|
|
467
|
+
"Scroll to top",
|
|
468
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.ArrowUpCircleIcon, { className: "size-4" })
|
|
469
|
+
]
|
|
470
|
+
}
|
|
471
|
+
)
|
|
472
|
+
] });
|
|
473
|
+
}
|
|
474
|
+
function TableOfContentsLink({ heading, activeId, handleClick, className }) {
|
|
475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
476
|
+
"a",
|
|
477
|
+
{
|
|
478
|
+
href: `#${heading.id}`,
|
|
479
|
+
className: cn("border-l border-gray-200 block py-1.5 pl-4 transition-colors", className, {
|
|
480
|
+
"border-gray-800 text-gray-900 font-medium": activeId === heading.id,
|
|
481
|
+
"hover:text-gray-800 hover:border-gray-400": activeId !== heading.id
|
|
482
|
+
}),
|
|
483
|
+
onClick: () => handleClick(heading.id),
|
|
484
|
+
children: heading.text
|
|
485
|
+
}
|
|
486
|
+
);
|
|
346
487
|
}
|
|
347
488
|
|
|
348
|
-
// src/client/
|
|
349
|
-
var import_navigation3 = require("next/navigation");
|
|
350
|
-
var import_lucide_react4 = require("lucide-react");
|
|
351
|
-
var import_link4 = __toESM(require("next/link"));
|
|
489
|
+
// src/client/components/docs-page.tsx
|
|
352
490
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
491
|
+
function DocstraPage({ children, toc = true, sidebar = true }) {
|
|
492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "min-h-screen flex bg-white w-full", children: [
|
|
493
|
+
sidebar && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DocstraSidebar, {}),
|
|
494
|
+
children,
|
|
495
|
+
toc && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DocstraTOC, {})
|
|
496
|
+
] });
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/client/components/breadcrumbs.tsx
|
|
500
|
+
var import_navigation4 = require("next/navigation");
|
|
501
|
+
var import_lucide_react5 = require("lucide-react");
|
|
502
|
+
var import_link4 = __toESM(require("next/link"));
|
|
503
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
353
504
|
function DocstraBreadcrumbs() {
|
|
354
|
-
const pathname = (0,
|
|
505
|
+
const pathname = (0, import_navigation4.usePathname)();
|
|
355
506
|
const paths = pathname.split("/").filter(Boolean);
|
|
356
507
|
const breadcrumbs = paths.map((segment, index) => {
|
|
357
508
|
const href = "/" + paths.slice(0, index + 1).join("/");
|
|
358
509
|
const title = segment.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
359
510
|
return { href, title };
|
|
360
511
|
});
|
|
361
|
-
return /* @__PURE__ */ (0,
|
|
362
|
-
/* @__PURE__ */ (0,
|
|
512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { "aria-label": "Breadcrumb", className: "flex text-sm items-center pb-4 text-gray-500", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("ol", { className: "flex items-center space-x-2", children: [
|
|
513
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_link4.default, { href: "/", className: "hover:text-gray-700 transition-colors font-medium", children: "Home" }) }),
|
|
363
514
|
breadcrumbs.map((crumb, index) => {
|
|
364
515
|
const isLast = index === breadcrumbs.length - 1;
|
|
365
|
-
return /* @__PURE__ */ (0,
|
|
366
|
-
/* @__PURE__ */ (0,
|
|
367
|
-
isLast ? /* @__PURE__ */ (0,
|
|
516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("li", { className: "flex items-center space-x-2", children: [
|
|
517
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.ChevronRight, { className: "w-4 h-4 text-gray-400" }),
|
|
518
|
+
isLast ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-gray-600 font-medium", children: crumb.title }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_link4.default, { href: crumb.href, className: "hover:text-gray-700 font-medium transition-colors", children: crumb.title })
|
|
368
519
|
] }, crumb.href);
|
|
369
520
|
})
|
|
370
521
|
] }) });
|
|
371
522
|
}
|
|
372
523
|
|
|
373
|
-
// src/client/page-buttons.tsx
|
|
374
|
-
var
|
|
375
|
-
var
|
|
376
|
-
var
|
|
524
|
+
// src/client/components/page-buttons.tsx
|
|
525
|
+
var import_lucide_react6 = require("lucide-react");
|
|
526
|
+
var import_react5 = require("react");
|
|
527
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
377
528
|
function DocstraPageButtons() {
|
|
378
529
|
const { pageData } = useDocstra();
|
|
379
|
-
const [isCopied, setIsCopied] = (0,
|
|
380
|
-
const [href, setHref] = (0,
|
|
381
|
-
(0,
|
|
530
|
+
const [isCopied, setIsCopied] = (0, import_react5.useState)(false);
|
|
531
|
+
const [href, setHref] = (0, import_react5.useState)(null);
|
|
532
|
+
(0, import_react5.useEffect)(() => {
|
|
382
533
|
setHref(window.location.href);
|
|
383
534
|
}, []);
|
|
384
535
|
const prompt = `Read from this URL: ${href} and explain it to me.`;
|
|
385
536
|
const handleCopy = () => {
|
|
386
|
-
navigator.clipboard.writeText(pageData?.
|
|
537
|
+
navigator.clipboard.writeText(pageData?.data.raw || "");
|
|
387
538
|
setIsCopied(true);
|
|
388
539
|
setTimeout(() => setIsCopied(false), 3e3);
|
|
389
540
|
};
|
|
390
|
-
return /* @__PURE__ */ (0,
|
|
391
|
-
/* @__PURE__ */ (0,
|
|
541
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-3 mt-6", children: [
|
|
542
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
392
543
|
"button",
|
|
393
544
|
{
|
|
394
545
|
title: "Copy Markdown",
|
|
395
546
|
onClick: handleCopy,
|
|
396
547
|
className: "flex items-center cursor-pointer gap-2 bg-gray-50 hover:bg-gray-100 border border-gray-200 px-3 py-2 rounded-md text-xs",
|
|
397
548
|
children: [
|
|
398
|
-
isCopied ? /* @__PURE__ */ (0,
|
|
549
|
+
isCopied ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react6.CheckIcon, { className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react6.CopyIcon, { className: "size-3.5" }),
|
|
399
550
|
"Copy Markdown"
|
|
400
551
|
]
|
|
401
552
|
}
|
|
402
553
|
),
|
|
403
|
-
/* @__PURE__ */ (0,
|
|
554
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
404
555
|
"a",
|
|
405
556
|
{
|
|
406
557
|
title: "Ask ChatGPT",
|
|
@@ -413,26 +564,26 @@ function DocstraPageButtons() {
|
|
|
413
564
|
] });
|
|
414
565
|
}
|
|
415
566
|
|
|
416
|
-
// src/client/docstra-page-head.tsx
|
|
417
|
-
var
|
|
567
|
+
// src/client/components/docstra-page-head.tsx
|
|
568
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
418
569
|
function DocstraPageHead() {
|
|
419
570
|
const { pageData } = useDocstra();
|
|
420
|
-
const title = pageData?.
|
|
421
|
-
const description = pageData?.
|
|
422
|
-
return /* @__PURE__ */ (0,
|
|
423
|
-
/* @__PURE__ */ (0,
|
|
424
|
-
/* @__PURE__ */ (0,
|
|
425
|
-
/* @__PURE__ */ (0,
|
|
426
|
-
/* @__PURE__ */ (0,
|
|
571
|
+
const title = pageData?.data?.metadata?.title;
|
|
572
|
+
const description = pageData?.data?.metadata?.description;
|
|
573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
574
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h1", { className: "text-3xl font-bold", children: title }),
|
|
575
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "my-4 text-gray-500", children: description }),
|
|
576
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DocstraPageButtons, {}),
|
|
577
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("hr", { className: "my-10 border-gray-200" })
|
|
427
578
|
] });
|
|
428
579
|
}
|
|
429
580
|
|
|
430
|
-
// src/client/feedback.tsx
|
|
431
|
-
var
|
|
432
|
-
var
|
|
581
|
+
// src/client/components/feedback.tsx
|
|
582
|
+
var import_react6 = require("react");
|
|
583
|
+
var import_lucide_react8 = require("lucide-react");
|
|
433
584
|
|
|
434
|
-
// src/client/input.tsx
|
|
435
|
-
var
|
|
585
|
+
// src/client/components/input.tsx
|
|
586
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
436
587
|
function Input({
|
|
437
588
|
label,
|
|
438
589
|
type,
|
|
@@ -445,12 +596,12 @@ function Input({
|
|
|
445
596
|
className = "",
|
|
446
597
|
optional = false
|
|
447
598
|
}) {
|
|
448
|
-
return /* @__PURE__ */ (0,
|
|
449
|
-
label && /* @__PURE__ */ (0,
|
|
599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: cn("flex flex-col mt-4 w-full", className), children: [
|
|
600
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { htmlFor: id, className: "font-medium w-max cursor-pointer", children: [
|
|
450
601
|
label,
|
|
451
|
-
optional && /* @__PURE__ */ (0,
|
|
602
|
+
optional && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-xs font-normal text-gray-400 ml-1 mt-1", children: "(Optional)" })
|
|
452
603
|
] }),
|
|
453
|
-
type === "textarea" ? /* @__PURE__ */ (0,
|
|
604
|
+
type === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
454
605
|
"textarea",
|
|
455
606
|
{
|
|
456
607
|
id,
|
|
@@ -466,7 +617,7 @@ function Input({
|
|
|
466
617
|
value,
|
|
467
618
|
readOnly
|
|
468
619
|
}
|
|
469
|
-
) : /* @__PURE__ */ (0,
|
|
620
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
470
621
|
"input",
|
|
471
622
|
{
|
|
472
623
|
type,
|
|
@@ -483,11 +634,11 @@ function Input({
|
|
|
483
634
|
] });
|
|
484
635
|
}
|
|
485
636
|
|
|
486
|
-
// src/client/button.tsx
|
|
487
|
-
var
|
|
488
|
-
var
|
|
637
|
+
// src/client/components/button.tsx
|
|
638
|
+
var import_lucide_react7 = require("lucide-react");
|
|
639
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
489
640
|
function Button({ label, loading, type = "submit", className = "", disabled = false, onClick }) {
|
|
490
|
-
return /* @__PURE__ */ (0,
|
|
641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
491
642
|
"button",
|
|
492
643
|
{
|
|
493
644
|
type,
|
|
@@ -498,21 +649,21 @@ function Button({ label, loading, type = "submit", className = "", disabled = fa
|
|
|
498
649
|
),
|
|
499
650
|
"aria-label": label,
|
|
500
651
|
onClick,
|
|
501
|
-
children: loading ? /* @__PURE__ */ (0,
|
|
652
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react7.Loader2Icon, { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 animate-spin mx-auto" }) : label
|
|
502
653
|
}
|
|
503
654
|
);
|
|
504
655
|
}
|
|
505
656
|
|
|
506
|
-
// src/client/feedback.tsx
|
|
507
|
-
var
|
|
657
|
+
// src/client/components/feedback.tsx
|
|
658
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
508
659
|
function DocstraFeedback() {
|
|
509
|
-
const [opinion, setOpinion] = (0,
|
|
660
|
+
const [opinion, setOpinion] = (0, import_react6.useState)(null);
|
|
510
661
|
const { docstraConfig } = useDocstra();
|
|
511
|
-
const [message, setMessage] = (0,
|
|
512
|
-
const [submitted, setSubmitted] = (0,
|
|
513
|
-
return /* @__PURE__ */ (0,
|
|
514
|
-
/* @__PURE__ */ (0,
|
|
515
|
-
/* @__PURE__ */ (0,
|
|
662
|
+
const [message, setMessage] = (0, import_react6.useState)("");
|
|
663
|
+
const [submitted, setSubmitted] = (0, import_react6.useState)(false);
|
|
664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "border-y border-gray-200 mt-20 py-10 space-y-4", children: submitted ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
665
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium text-gray-900", children: "Thank you for your feedback!" }),
|
|
666
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
516
667
|
Button,
|
|
517
668
|
{
|
|
518
669
|
onClick: () => {
|
|
@@ -524,28 +675,28 @@ function DocstraFeedback() {
|
|
|
524
675
|
className: "w-max text-sm"
|
|
525
676
|
}
|
|
526
677
|
)
|
|
527
|
-
] }) : /* @__PURE__ */ (0,
|
|
528
|
-
/* @__PURE__ */ (0,
|
|
529
|
-
/* @__PURE__ */ (0,
|
|
530
|
-
/* @__PURE__ */ (0,
|
|
678
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
679
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "font-medium", children: "How is this guide?" }),
|
|
680
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex gap-2", children: [
|
|
681
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
531
682
|
"button",
|
|
532
683
|
{
|
|
533
684
|
onClick: () => setOpinion("good"),
|
|
534
685
|
className: `flex items-center cursor-pointer gap-1 px-3 py-2 rounded-full border text-sm ${opinion === "good" ? "bg-green-100 text-green-600 border-green-300" : "border-gray-200 text-gray-600 hover:bg-gray-100"}`,
|
|
535
686
|
children: [
|
|
536
|
-
/* @__PURE__ */ (0,
|
|
687
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react8.ThumbsUp, { className: `size-4 ${opinion === "good" ? "fill-green-600" : "text-gray-500"}` }),
|
|
537
688
|
"Good"
|
|
538
689
|
]
|
|
539
690
|
}
|
|
540
691
|
),
|
|
541
|
-
/* @__PURE__ */ (0,
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
542
693
|
"button",
|
|
543
694
|
{
|
|
544
695
|
onClick: () => setOpinion("bad"),
|
|
545
696
|
className: `flex items-center cursor-pointer gap-1 px-3 py-2 rounded-full border text-sm ${opinion === "bad" ? "bg-red-100 text-red-600 border-red-300" : "border-gray-200 text-gray-600 hover:bg-gray-100"}`,
|
|
546
697
|
children: [
|
|
547
|
-
/* @__PURE__ */ (0,
|
|
548
|
-
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
699
|
+
import_lucide_react8.ThumbsDown,
|
|
549
700
|
{
|
|
550
701
|
className: `size-4 pt-0.5 ${opinion === "bad" ? "fill-red-600" : "text-gray-500"}`
|
|
551
702
|
}
|
|
@@ -555,14 +706,14 @@ function DocstraFeedback() {
|
|
|
555
706
|
}
|
|
556
707
|
)
|
|
557
708
|
] }),
|
|
558
|
-
opinion && /* @__PURE__ */ (0,
|
|
709
|
+
opinion && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
559
710
|
"form",
|
|
560
711
|
{
|
|
561
712
|
className: "flex flex-col gap-2",
|
|
562
713
|
action: `https://formsync.app/v1/s/${docstraConfig?.feedback?.formSyncFormID || ""}`,
|
|
563
714
|
method: "POST",
|
|
564
715
|
children: [
|
|
565
|
-
/* @__PURE__ */ (0,
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
566
717
|
Input,
|
|
567
718
|
{
|
|
568
719
|
value: message,
|
|
@@ -573,14 +724,14 @@ function DocstraFeedback() {
|
|
|
573
724
|
type: "textarea"
|
|
574
725
|
}
|
|
575
726
|
),
|
|
576
|
-
/* @__PURE__ */ (0,
|
|
577
|
-
/* @__PURE__ */ (0,
|
|
578
|
-
/* @__PURE__ */ (0,
|
|
579
|
-
/* @__PURE__ */ (0,
|
|
580
|
-
docstraConfig?.feedback?.watermark !== false && /* @__PURE__ */ (0,
|
|
727
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "hidden", name: "opinion", value: opinion }),
|
|
728
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "hidden", name: "page", value: window.location.href }),
|
|
729
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "hidden", name: "_redirect", value: window.location.href }),
|
|
730
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { label: "Submit", className: "w-max text-sm" }),
|
|
731
|
+
docstraConfig?.feedback?.watermark !== false && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "text-left text-sm text-gray-500 mt-6", children: [
|
|
581
732
|
"Powered by",
|
|
582
733
|
" ",
|
|
583
|
-
/* @__PURE__ */ (0,
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
584
735
|
"a",
|
|
585
736
|
{
|
|
586
737
|
href: `https://www.formsync.app?utm_source=${docstraConfig?.githubRepo}`,
|
|
@@ -595,243 +746,75 @@ function DocstraFeedback() {
|
|
|
595
746
|
] }) });
|
|
596
747
|
}
|
|
597
748
|
|
|
598
|
-
// src/client/pagination.tsx
|
|
599
|
-
var
|
|
749
|
+
// src/client/components/pagination.tsx
|
|
750
|
+
var import_navigation5 = require("next/navigation");
|
|
600
751
|
var import_link5 = __toESM(require("next/link"));
|
|
601
|
-
var
|
|
602
|
-
var
|
|
752
|
+
var import_lucide_react9 = require("lucide-react");
|
|
753
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
603
754
|
function DocstraPagination() {
|
|
604
|
-
const pathname = (0,
|
|
755
|
+
const pathname = (0, import_navigation5.usePathname)();
|
|
605
756
|
const { docstraConfig } = useDocstra();
|
|
606
757
|
const flatLinks = docstraConfig?.sidebar?.links?.flatMap((section) => section.items);
|
|
607
758
|
const currentIndex = flatLinks.findIndex((item) => item.href === pathname);
|
|
608
759
|
const prev = currentIndex > 0 ? flatLinks[currentIndex - 1] : null;
|
|
609
760
|
const next = currentIndex < flatLinks.length - 1 ? flatLinks[currentIndex + 1] : null;
|
|
610
|
-
return /* @__PURE__ */ (0,
|
|
611
|
-
prev ? /* @__PURE__ */ (0,
|
|
761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col md:flex-row gap-2 justify-between py-10 mt-10", children: [
|
|
762
|
+
prev ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
612
763
|
import_link5.default,
|
|
613
764
|
{
|
|
614
765
|
href: prev.href,
|
|
615
766
|
className: "flex flex-col items-start gap-2 border border-gray-200 hover:bg-gray-50 py-3 md:min-w-62 pl-4 pr-10 rounded-lg text-sm",
|
|
616
767
|
children: [
|
|
617
|
-
/* @__PURE__ */ (0,
|
|
618
|
-
/* @__PURE__ */ (0,
|
|
619
|
-
/* @__PURE__ */ (0,
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-gray-500", children: "Previous" }),
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "flex items-center font-medium", children: [
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react9.ArrowLeftIcon, { className: "size-5 mr-2" }),
|
|
620
771
|
prev.name
|
|
621
772
|
] })
|
|
622
773
|
]
|
|
623
774
|
}
|
|
624
|
-
) : /* @__PURE__ */ (0,
|
|
625
|
-
next ? /* @__PURE__ */ (0,
|
|
775
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", {}),
|
|
776
|
+
next ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
626
777
|
import_link5.default,
|
|
627
778
|
{
|
|
628
779
|
href: next.href,
|
|
629
780
|
className: "flex flex-col items-end gap-2 border border-gray-200 hover:bg-gray-50 py-3 pr-4 md:min-w-62 pl-10 rounded-lg text-sm",
|
|
630
781
|
children: [
|
|
631
|
-
/* @__PURE__ */ (0,
|
|
632
|
-
/* @__PURE__ */ (0,
|
|
782
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-gray-500", children: "Next" }),
|
|
783
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "flex items-center font-medium", children: [
|
|
633
784
|
next.name,
|
|
634
|
-
/* @__PURE__ */ (0,
|
|
785
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react9.ArrowRightIcon, { className: "size-5 ml-2" })
|
|
635
786
|
] })
|
|
636
787
|
]
|
|
637
788
|
}
|
|
638
|
-
) : /* @__PURE__ */ (0,
|
|
789
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", {})
|
|
639
790
|
] });
|
|
640
791
|
}
|
|
641
792
|
|
|
642
|
-
// src/client/docs-body.tsx
|
|
643
|
-
var
|
|
793
|
+
// src/client/components/docs-body.tsx
|
|
794
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
644
795
|
function DocstraBody({ children }) {
|
|
645
796
|
const { docstraConfig } = useDocstra();
|
|
646
|
-
return /* @__PURE__ */ (0,
|
|
647
|
-
/* @__PURE__ */ (0,
|
|
648
|
-
/* @__PURE__ */ (0,
|
|
797
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("main", { className: "flex-1 px-4 md:px-8 py-10 max-w-full text-base/7", children: [
|
|
798
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocstraBreadcrumbs, {}),
|
|
799
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocstraPageHead, {}),
|
|
649
800
|
children,
|
|
650
|
-
docstraConfig?.feedback?.enabled && /* @__PURE__ */ (0,
|
|
651
|
-
/* @__PURE__ */ (0,
|
|
801
|
+
docstraConfig?.feedback?.enabled && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocstraFeedback, {}),
|
|
802
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocstraPagination, {})
|
|
652
803
|
] });
|
|
653
804
|
}
|
|
654
805
|
|
|
655
|
-
// src/client/
|
|
656
|
-
var import_lucide_react9 = require("lucide-react");
|
|
657
|
-
var import_navigation5 = require("next/navigation");
|
|
658
|
-
var import_react6 = require("react");
|
|
659
|
-
|
|
660
|
-
// src/utils/generate-id-from-text.ts
|
|
661
|
-
function generateIdFromText(text) {
|
|
662
|
-
return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
// src/utils/extract-headings-from-mdx.ts
|
|
666
|
-
function extractHeadingsFromMdx(raw) {
|
|
667
|
-
const lines = raw.split("\n");
|
|
668
|
-
const results = [];
|
|
669
|
-
let currentH2 = null;
|
|
670
|
-
for (let line of lines) {
|
|
671
|
-
line = line.trim();
|
|
672
|
-
const h2Match = line.match(/^##\s+(.*)/);
|
|
673
|
-
const h3Match = line.match(/^###\s+(.*)/);
|
|
674
|
-
if (h2Match) {
|
|
675
|
-
const text = h2Match[1].trim();
|
|
676
|
-
const id = generateIdFromText(text);
|
|
677
|
-
currentH2 = { id, text, children: [] };
|
|
678
|
-
results.push(currentH2);
|
|
679
|
-
}
|
|
680
|
-
if (h3Match && currentH2) {
|
|
681
|
-
const text = h3Match[1].trim();
|
|
682
|
-
const id = generateIdFromText(text);
|
|
683
|
-
currentH2.children.push({ id, text });
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
return results;
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
// src/client/docstra-toc.tsx
|
|
690
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
691
|
-
function DocstraTOC() {
|
|
692
|
-
const [headings, setHeadings] = (0, import_react6.useState)([]);
|
|
693
|
-
const [activeId, setActiveId] = (0, import_react6.useState)(null);
|
|
694
|
-
const [scrollDir, setScrollDir] = (0, import_react6.useState)("down");
|
|
695
|
-
const [isScrolled, setIsScrolled] = (0, import_react6.useState)(false);
|
|
696
|
-
const [isManualClick, setIsManualClick] = (0, import_react6.useState)(false);
|
|
697
|
-
const { docstraConfig, pageData } = useDocstra();
|
|
698
|
-
const mdxFilePath = pageData?.info.fullPath;
|
|
699
|
-
const rawMdxContent = pageData?.content;
|
|
700
|
-
const lastScrollY = (0, import_react6.useRef)(0);
|
|
701
|
-
const observerRef = (0, import_react6.useRef)(null);
|
|
702
|
-
const pathname = (0, import_navigation5.usePathname)();
|
|
703
|
-
const baseUrlOfGithub = docstraConfig?.githubRepo || "https://github.com/sudhucodes/docstra";
|
|
704
|
-
const githubLink = `${baseUrlOfGithub}/edit/main/${mdxFilePath}`;
|
|
705
|
-
(0, import_react6.useEffect)(() => {
|
|
706
|
-
const onScroll = () => {
|
|
707
|
-
const currentY = window.scrollY;
|
|
708
|
-
setScrollDir(currentY > lastScrollY.current ? "down" : "up");
|
|
709
|
-
setIsScrolled(currentY > 100);
|
|
710
|
-
lastScrollY.current = currentY;
|
|
711
|
-
};
|
|
712
|
-
window.addEventListener("scroll", onScroll);
|
|
713
|
-
return () => window.removeEventListener("scroll", onScroll);
|
|
714
|
-
}, []);
|
|
715
|
-
(0, import_react6.useEffect)(() => {
|
|
716
|
-
const structured = extractHeadingsFromMdx(rawMdxContent);
|
|
717
|
-
setHeadings(structured);
|
|
718
|
-
}, [rawMdxContent]);
|
|
719
|
-
(0, import_react6.useEffect)(() => {
|
|
720
|
-
const allHeadings = document.querySelectorAll(`h2[id], h3[id]`);
|
|
721
|
-
const observer = new IntersectionObserver(
|
|
722
|
-
(entries) => {
|
|
723
|
-
if (isManualClick) return;
|
|
724
|
-
const visible = entries.filter((e) => e.isIntersecting).sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
|
|
725
|
-
if (visible.length > 0) {
|
|
726
|
-
const nextActive = scrollDir === "down" ? visible[0].target.id : visible[visible.length - 1].target.id;
|
|
727
|
-
setActiveId(nextActive);
|
|
728
|
-
}
|
|
729
|
-
},
|
|
730
|
-
{
|
|
731
|
-
rootMargin: "-40% 0px -50% 0px",
|
|
732
|
-
threshold: [0, 0.2, 0.6, 1]
|
|
733
|
-
}
|
|
734
|
-
);
|
|
735
|
-
allHeadings.forEach((heading) => observer.observe(heading));
|
|
736
|
-
observerRef.current = observer;
|
|
737
|
-
return () => observer.disconnect();
|
|
738
|
-
}, [pathname, scrollDir, isManualClick]);
|
|
739
|
-
(0, import_react6.useEffect)(() => {
|
|
740
|
-
const scrolled = window.scrollY > 100;
|
|
741
|
-
!scrolled && setActiveId(headings[0]?.id);
|
|
742
|
-
}, [headings]);
|
|
743
|
-
(0, import_react6.useEffect)(() => {
|
|
744
|
-
if (!activeId) return;
|
|
745
|
-
const container = document.querySelector(".toc-scroll-container");
|
|
746
|
-
if (!container) return;
|
|
747
|
-
const activeLink = container.querySelector(`a[href="#${activeId}"]`);
|
|
748
|
-
if (!activeLink) return;
|
|
749
|
-
const containerRect = container.getBoundingClientRect();
|
|
750
|
-
const linkRect = activeLink.getBoundingClientRect();
|
|
751
|
-
const isOutOfView = linkRect.top < containerRect.top || linkRect.bottom > containerRect.bottom;
|
|
752
|
-
if (isOutOfView) {
|
|
753
|
-
activeLink.scrollIntoView({
|
|
754
|
-
behavior: "smooth",
|
|
755
|
-
block: "nearest"
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
}, [activeId]);
|
|
759
|
-
(0, import_react6.useEffect)(() => {
|
|
760
|
-
if (!isManualClick) return;
|
|
761
|
-
const timer = setTimeout(() => setIsManualClick(false), 800);
|
|
762
|
-
return () => clearTimeout(timer);
|
|
763
|
-
}, [isManualClick]);
|
|
764
|
-
const handleClick = (id) => {
|
|
765
|
-
setActiveId(id);
|
|
766
|
-
setIsManualClick(true);
|
|
767
|
-
};
|
|
768
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("aside", { className: "sticky top-18 text-sm hidden xl:block text-gray-500 shrink-0 h-[calc(100svh-72px)] w-64 border-l border-gray-200 p-6 overflow-y-auto", children: [
|
|
769
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "flex items-center gap-2 mb-5", children: [
|
|
770
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react9.TextAlignStartIcon, { className: "size-4" }),
|
|
771
|
-
"On this page"
|
|
772
|
-
] }),
|
|
773
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "toc-scroll-container max-h-3/4 overflow-y-auto scrollbar-none", children: headings.map((h2) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { children: [
|
|
774
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TableOfContentsLink, { heading: h2, activeId, handleClick }),
|
|
775
|
-
h2.children.map((h3) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
776
|
-
TableOfContentsLink,
|
|
777
|
-
{
|
|
778
|
-
heading: h3,
|
|
779
|
-
activeId,
|
|
780
|
-
handleClick,
|
|
781
|
-
className: "pl-8"
|
|
782
|
-
},
|
|
783
|
-
h3.id
|
|
784
|
-
))
|
|
785
|
-
] }, h2.id)) }),
|
|
786
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("hr", { className: "my-6 border-gray-200" }),
|
|
787
|
-
docstraConfig.editOnGithub && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
788
|
-
"a",
|
|
789
|
-
{
|
|
790
|
-
href: githubLink,
|
|
791
|
-
rel: "noopener noreferrer",
|
|
792
|
-
className: "flex items-center gap-2 text-gray-400 hover:text-gray-700 transition",
|
|
793
|
-
children: [
|
|
794
|
-
"Edit this page on GitHub",
|
|
795
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react9.SquareArrowOutUpRightIcon, { className: "size-4" })
|
|
796
|
-
]
|
|
797
|
-
}
|
|
798
|
-
),
|
|
799
|
-
isScrolled && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
800
|
-
"button",
|
|
801
|
-
{
|
|
802
|
-
onClick: () => scrollTo({ top: 0, behavior: "smooth" }),
|
|
803
|
-
className: "flex items-center gap-2 mt-3 text-gray-400 hover:text-gray-700 transition",
|
|
804
|
-
children: [
|
|
805
|
-
"Scroll to top",
|
|
806
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react9.ArrowUpCircleIcon, { className: "size-4" })
|
|
807
|
-
]
|
|
808
|
-
}
|
|
809
|
-
)
|
|
810
|
-
] });
|
|
811
|
-
}
|
|
812
|
-
function TableOfContentsLink({ heading, activeId, handleClick, className }) {
|
|
813
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
814
|
-
"a",
|
|
815
|
-
{
|
|
816
|
-
href: `#${heading.id}`,
|
|
817
|
-
className: cn("border-l border-gray-200 block py-1.5 pl-4 transition-colors", className, {
|
|
818
|
-
"border-gray-800 text-gray-900 font-medium": activeId === heading.id,
|
|
819
|
-
"hover:text-gray-800 hover:border-gray-400": activeId !== heading.id
|
|
820
|
-
}),
|
|
821
|
-
onClick: () => handleClick(heading.id),
|
|
822
|
-
children: heading.text
|
|
823
|
-
}
|
|
824
|
-
);
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
// src/client/code-block.tsx
|
|
806
|
+
// src/client/components/code-block.tsx
|
|
828
807
|
var import_react7 = require("react");
|
|
829
808
|
var import_prism_react_renderer = require("prism-react-renderer");
|
|
830
809
|
var import_lucide_react10 = require("lucide-react");
|
|
831
810
|
var import_react_toast_msg2 = require("react-toast-msg");
|
|
832
811
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
833
812
|
function DocstraCodeBlock(props) {
|
|
834
|
-
const {
|
|
813
|
+
const { title, children } = props;
|
|
814
|
+
const childProps = children?.props || {};
|
|
815
|
+
const className = childProps.className || "";
|
|
816
|
+
const matches = className.match(/language-(?<lang>.*)/);
|
|
817
|
+
const language = props.language || matches && matches.groups && matches.groups.lang || "text";
|
|
835
818
|
const code = typeof children === "string" ? children.trim() : children?.props?.children?.toString()?.trim() || "";
|
|
836
819
|
const [copied, setCopied] = (0, import_react7.useState)(false);
|
|
837
820
|
const handleCopy = () => {
|
|
@@ -867,6 +850,7 @@ function DocstraCodeBlock(props) {
|
|
|
867
850
|
DocstraHeader,
|
|
868
851
|
DocstraPage,
|
|
869
852
|
DocstraProvider,
|
|
853
|
+
DocstraSearchBox,
|
|
870
854
|
DocstraSidebar,
|
|
871
855
|
DocstraTOC,
|
|
872
856
|
useDocstra
|