@usecross/docs 0.10.1 → 0.11.0
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/index.d.ts +9 -5
- package/dist/index.js +48 -17
- package/dist/index.js.map +1 -1
- package/dist/ssr.d.ts +1 -1
- package/dist/{types-DlTTA3Dc.d.ts → types-Qbhh2Ihz.d.ts} +8 -0
- package/package.json +1 -1
- package/src/components/DocsLayout.tsx +75 -59
- package/src/components/Sidebar.tsx +4 -4
- package/src/components/TableOfContents.tsx +6 -6
- package/src/components/index.ts +1 -1
- package/src/index.ts +1 -0
- package/src/styles.css +4 -2
- package/src/types.ts +5 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { C as CodeBlockProps, D as DocSetMeta, a as DocsLayoutProps, b as DocContent, M as MarkdownProps, S as SidebarProps, T as TableOfContentsProps, c as DocsAppConfig } from './types-
|
|
3
|
-
export { N as NavItem, d as NavSection, e as SharedProps, f as TOCItem } from './types-
|
|
2
|
+
import { C as CodeBlockProps, D as DocSetMeta, a as DocsLayoutProps, b as DocContent, M as MarkdownProps, S as SidebarProps, T as TableOfContentsProps, c as DocsAppConfig } from './types-Qbhh2Ihz.js';
|
|
3
|
+
export { N as NavItem, d as NavSection, e as SharedProps, f as TOCItem } from './types-Qbhh2Ihz.js';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
import { ClassValue } from 'clsx';
|
|
6
6
|
import { HighlighterCore } from 'shiki/core';
|
|
@@ -27,10 +27,14 @@ interface DocSetSelectorProps {
|
|
|
27
27
|
*/
|
|
28
28
|
declare function DocSetSelector({ docSets, currentDocSet, className }: DocSetSelectorProps): react_jsx_runtime.JSX.Element;
|
|
29
29
|
|
|
30
|
+
declare function MobileMenuButton({ onClick, isOpen }: {
|
|
31
|
+
onClick: () => void;
|
|
32
|
+
isOpen: boolean;
|
|
33
|
+
}): react_jsx_runtime.JSX.Element;
|
|
30
34
|
/**
|
|
31
35
|
* Full-featured documentation layout with sidebar, mobile menu, and header.
|
|
32
36
|
*/
|
|
33
|
-
declare function DocsLayout({ children, title, description: _description, logo, logoInverted, logoUrl: propLogoUrl, logoInvertedUrl: propLogoInvertedUrl, githubUrl: propGithubUrl, navLinks: propNavLinks, footer, toc, }: DocsLayoutProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
declare function DocsLayout({ children, title, description: _description, logo, logoInverted, logoUrl: propLogoUrl, logoInvertedUrl: propLogoInvertedUrl, githubUrl: propGithubUrl, navLinks: propNavLinks, header, headerHeight, footer, toc, }: DocsLayoutProps): react_jsx_runtime.JSX.Element;
|
|
34
38
|
|
|
35
39
|
interface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {
|
|
36
40
|
content: DocContent;
|
|
@@ -161,7 +165,7 @@ declare function Sidebar({ nav, currentPath, className, docSets, currentDocSet }
|
|
|
161
165
|
* Table of contents component with scroll spy functionality.
|
|
162
166
|
* Displays "ON THIS PAGE" sidebar with heading links.
|
|
163
167
|
*/
|
|
164
|
-
declare function TableOfContents({ items, className }: TableOfContentsProps): react_jsx_runtime.JSX.Element | null;
|
|
168
|
+
declare function TableOfContents({ items, className, ...props }: TableOfContentsProps): react_jsx_runtime.JSX.Element | null;
|
|
165
169
|
|
|
166
170
|
type Theme = 'light' | 'dark' | 'system';
|
|
167
171
|
type ResolvedTheme = 'light' | 'dark';
|
|
@@ -233,4 +237,4 @@ declare function configureHighlighter(options: {
|
|
|
233
237
|
langs?: Promise<any>[];
|
|
234
238
|
}): void;
|
|
235
239
|
|
|
236
|
-
export { CodeBlock, CodeBlockProps, DocContent, DocSetMeta, DocSetSelector, DocsAppConfig, DocsLayout, DocsLayoutProps, DocsPage, EmojiConfetti, HomeCTA, type HomeFeature, HomeFeatureItem, type HomeFeatureItemProps, HomeFeatures, type HomeFeaturesProps, HomeFooter, HomeHeader, type HomeHeaderProps, HomeHero, HomePage, type HomePageContextValue, type HomePageProps, InlineCode, Markdown, MarkdownProps, type ResolvedTheme, Sidebar, SidebarProps, TableOfContents, TableOfContentsProps, type Theme, ThemeProvider, ThemeToggle, cn, configureHighlighter, createDocsApp, getHighlighter, themeInitScript, useTheme };
|
|
240
|
+
export { CodeBlock, CodeBlockProps, DocContent, DocSetMeta, DocSetSelector, DocsAppConfig, DocsLayout, DocsLayoutProps, DocsPage, EmojiConfetti, HomeCTA, type HomeFeature, HomeFeatureItem, type HomeFeatureItemProps, HomeFeatures, type HomeFeaturesProps, HomeFooter, HomeHeader, type HomeHeaderProps, HomeHero, HomePage, type HomePageContextValue, type HomePageProps, InlineCode, Markdown, MarkdownProps, MobileMenuButton, type ResolvedTheme, Sidebar, SidebarProps, TableOfContents, TableOfContentsProps, type Theme, ThemeProvider, ThemeToggle, cn, configureHighlighter, createDocsApp, getHighlighter, themeInitScript, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -316,14 +316,14 @@ function Sidebar({ nav, currentPath, className, docSets, currentDocSet }) {
|
|
|
316
316
|
return /* @__PURE__ */ jsxs3("nav", { className: cn("space-y-6", className), children: [
|
|
317
317
|
docSets && docSets.length > 1 && /* @__PURE__ */ jsx3(DocSetSelector, { docSets, currentDocSet: currentDocSet ?? "", className: "mb-6" }),
|
|
318
318
|
/* @__PURE__ */ jsx3("div", { className: "space-y-8", children: nav.map((section) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
319
|
-
/* @__PURE__ */ jsx3("h3", { className: "mb-3 text-
|
|
320
|
-
/* @__PURE__ */ jsx3("ul", { className: "space-y-
|
|
319
|
+
/* @__PURE__ */ jsx3("h3", { className: "mb-3 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400", children: section.title }),
|
|
320
|
+
/* @__PURE__ */ jsx3("ul", { className: "space-y-1.5 border-l-2 border-gray-200 dark:border-gray-700", children: section.items.map((item) => /* @__PURE__ */ jsx3("li", { children: /* @__PURE__ */ jsx3(
|
|
321
321
|
Link,
|
|
322
322
|
{
|
|
323
323
|
href: item.href,
|
|
324
324
|
className: cn(
|
|
325
|
-
"block border-l-2 py-
|
|
326
|
-
currentPath === item.href ? "border-primary-500 text-gray-900 dark:text-white font-bold" : "border-transparent text-gray-600 dark:text-gray-300 hover:border-
|
|
325
|
+
"block border-l-2 py-1 pl-4 text-[17px] leading-snug transition-colors -ml-0.5",
|
|
326
|
+
currentPath === item.href ? "border-primary-500 text-gray-900 dark:text-white font-bold" : "border-transparent text-gray-600 dark:text-gray-300 hover:border-primary-300 dark:hover:border-primary-400 hover:text-gray-900 dark:hover:text-white"
|
|
327
327
|
),
|
|
328
328
|
children: item.title
|
|
329
329
|
}
|
|
@@ -335,7 +335,7 @@ function Sidebar({ nav, currentPath, className, docSets, currentDocSet }) {
|
|
|
335
335
|
// src/components/TableOfContents.tsx
|
|
336
336
|
import { useEffect as useEffect3, useState as useState3, useRef as useRef2 } from "react";
|
|
337
337
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
338
|
-
function TableOfContents({ items, className = "" }) {
|
|
338
|
+
function TableOfContents({ items, className = "", ...props }) {
|
|
339
339
|
const [activeId, setActiveId] = useState3(() => {
|
|
340
340
|
if (typeof window !== "undefined" && window.location.hash) {
|
|
341
341
|
return window.location.hash.slice(1);
|
|
@@ -440,9 +440,9 @@ function TableOfContents({ items, className = "" }) {
|
|
|
440
440
|
if (items.length === 0) {
|
|
441
441
|
return null;
|
|
442
442
|
}
|
|
443
|
-
return /* @__PURE__ */ jsxs4("nav", { className, children: [
|
|
444
|
-
/* @__PURE__ */ jsx4("h3", { className: "mb-3 text-
|
|
445
|
-
/* @__PURE__ */ jsx4("ul", { className: "space-y-1 border-l-2 border-gray-200 dark:border-gray-700", children: items.map((item) => {
|
|
443
|
+
return /* @__PURE__ */ jsxs4("nav", { className, ...props, children: [
|
|
444
|
+
/* @__PURE__ */ jsx4("h3", { className: "mb-3 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400", children: "On this page" }),
|
|
445
|
+
/* @__PURE__ */ jsx4("ul", { className: "space-y-1.5 border-l-2 border-gray-200 dark:border-gray-700", children: items.map((item) => {
|
|
446
446
|
const isActive = activeId === item.id;
|
|
447
447
|
const indent = item.level === 3 ? "pl-6" : "pl-4";
|
|
448
448
|
return /* @__PURE__ */ jsx4("li", { children: /* @__PURE__ */ jsx4(
|
|
@@ -450,7 +450,7 @@ function TableOfContents({ items, className = "" }) {
|
|
|
450
450
|
{
|
|
451
451
|
href: `#${item.id}`,
|
|
452
452
|
onClick: (e) => handleClick(e, item.id),
|
|
453
|
-
className: `block border-l-2 py-1
|
|
453
|
+
className: `block border-l-2 py-1 ${indent} -ml-0.5 text-base leading-snug transition-colors ${isActive ? "border-primary-500 text-gray-900 dark:text-white font-bold" : "border-transparent text-gray-600 dark:text-gray-300 hover:border-primary-300 dark:hover:border-primary-400 hover:text-gray-900 dark:hover:text-white"}`,
|
|
454
454
|
children: item.text
|
|
455
455
|
}
|
|
456
456
|
) }, item.id);
|
|
@@ -728,6 +728,8 @@ function DocsLayout({
|
|
|
728
728
|
logoInvertedUrl: propLogoInvertedUrl,
|
|
729
729
|
githubUrl: propGithubUrl,
|
|
730
730
|
navLinks: propNavLinks,
|
|
731
|
+
header,
|
|
732
|
+
headerHeight = 64,
|
|
731
733
|
footer,
|
|
732
734
|
toc
|
|
733
735
|
}) {
|
|
@@ -746,7 +748,7 @@ function DocsLayout({
|
|
|
746
748
|
const footerLogo = logo || (currentFooterLogoUrl ? /* @__PURE__ */ jsx7("img", { src: currentFooterLogoUrl, alt: "Logo", className: "h-6" }) : null);
|
|
747
749
|
return /* @__PURE__ */ jsxs6("div", { className: "min-h-screen bg-white dark:bg-[#0f0f0f] flex flex-col transition-colors duration-200", children: [
|
|
748
750
|
/* @__PURE__ */ jsx7(Head, { title }),
|
|
749
|
-
/* @__PURE__ */ jsx7("nav", { className: "fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors", children: /* @__PURE__ */ jsx7("div", { className: "px-4 lg:px-10", children: /* @__PURE__ */ jsxs6("div", { className: "flex justify-between h-16 items-center", children: [
|
|
751
|
+
(typeof header === "function" ? header({ mobileMenuOpen, toggleMobileMenu: () => setMobileMenuOpen(!mobileMenuOpen) }) : header) || /* @__PURE__ */ jsx7("nav", { className: "fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors", children: /* @__PURE__ */ jsx7("div", { className: "px-4 lg:px-10", children: /* @__PURE__ */ jsxs6("div", { className: "flex justify-between h-16 items-center", children: [
|
|
750
752
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
751
753
|
/* @__PURE__ */ jsx7(MobileMenuButton, { onClick: () => setMobileMenuOpen(!mobileMenuOpen), isOpen: mobileMenuOpen }),
|
|
752
754
|
headerLogo ? /* @__PURE__ */ jsx7(Link2, { href: "/", className: "flex items-center", children: headerLogo }) : /* @__PURE__ */ jsx7(Link2, { href: "/", className: "font-bold text-lg text-gray-900 dark:text-white", children: "Docs" })
|
|
@@ -776,15 +778,43 @@ function DocsLayout({
|
|
|
776
778
|
] }) }) }),
|
|
777
779
|
mobileMenuOpen && /* @__PURE__ */ jsxs6("div", { className: "fixed inset-0 z-40 lg:hidden", children: [
|
|
778
780
|
/* @__PURE__ */ jsx7("div", { className: "fixed inset-0 bg-black/50 dark:bg-black/70", onClick: () => setMobileMenuOpen(false) }),
|
|
779
|
-
/* @__PURE__ */ jsx7(
|
|
781
|
+
/* @__PURE__ */ jsx7(
|
|
782
|
+
"div",
|
|
783
|
+
{
|
|
784
|
+
className: "fixed inset-y-0 left-0 w-72 overflow-y-auto bg-white dark:bg-[#0f0f0f] px-4 py-6 border-r border-gray-200 dark:border-gray-800 transition-colors",
|
|
785
|
+
style: { paddingTop: headerHeight + 16 },
|
|
786
|
+
children: /* @__PURE__ */ jsx7(Sidebar, { nav, currentPath, docSets, currentDocSet })
|
|
787
|
+
}
|
|
788
|
+
)
|
|
780
789
|
] }),
|
|
781
|
-
/* @__PURE__ */ jsx7("div", { className: "bg-white dark:bg-[#0f0f0f]
|
|
782
|
-
/* @__PURE__ */ jsx7(
|
|
790
|
+
/* @__PURE__ */ jsx7("div", { className: "bg-white dark:bg-[#0f0f0f] w-full flex-1 transition-colors", style: { paddingTop: headerHeight }, children: /* @__PURE__ */ jsxs6("div", { className: "flex", children: [
|
|
791
|
+
/* @__PURE__ */ jsx7(
|
|
792
|
+
"aside",
|
|
793
|
+
{
|
|
794
|
+
className: "hidden lg:block w-[24rem] shrink-0 border-r border-gray-200 dark:border-gray-800 transition-colors",
|
|
795
|
+
style: { minHeight: `calc(100vh - ${headerHeight}px)` },
|
|
796
|
+
children: /* @__PURE__ */ jsx7(
|
|
797
|
+
"nav",
|
|
798
|
+
{
|
|
799
|
+
className: "sticky px-4 lg:px-10 py-6 overflow-y-auto",
|
|
800
|
+
style: { top: headerHeight, maxHeight: `calc(100vh - ${headerHeight}px)` },
|
|
801
|
+
children: /* @__PURE__ */ jsx7(Sidebar, { nav, currentPath, docSets, currentDocSet })
|
|
802
|
+
}
|
|
803
|
+
)
|
|
804
|
+
}
|
|
805
|
+
),
|
|
783
806
|
/* @__PURE__ */ jsxs6("div", { className: "flex-1 min-w-0 flex flex-col", children: [
|
|
784
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex
|
|
785
|
-
/* @__PURE__ */ jsx7("main", { className: "
|
|
786
|
-
toc && toc.length > 0 && /* @__PURE__ */ jsx7("aside", { className: "hidden xl:block w-
|
|
787
|
-
|
|
807
|
+
/* @__PURE__ */ jsx7("div", { className: "flex-1 p-4 lg:px-10 lg:py-6", children: /* @__PURE__ */ jsxs6("div", { className: "flex gap-5", children: [
|
|
808
|
+
/* @__PURE__ */ jsx7("main", { className: "min-w-0 w-full max-w-4xl", children: /* @__PURE__ */ jsx7("article", { className: "prose prose-lg max-w-none prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-3xl prose-h1:mb-4 prose-h2:text-2xl prose-h2:mt-10 first:prose-h2:mt-0 prose-h3:text-xl prose-a:text-primary-600 dark:prose-a:text-primary-400 prose-a:no-underline hover:prose-a:underline prose-code:bg-gray-100 dark:prose-code:bg-gray-800 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none dark:prose-headings:text-white dark:prose-strong:text-white dark:text-gray-300", children }) }),
|
|
809
|
+
toc && toc.length > 0 && /* @__PURE__ */ jsx7("aside", { className: "hidden xl:block w-56 shrink-0 transition-colors", children: /* @__PURE__ */ jsx7(
|
|
810
|
+
TableOfContents,
|
|
811
|
+
{
|
|
812
|
+
items: toc,
|
|
813
|
+
className: "sticky overflow-y-auto",
|
|
814
|
+
style: { top: headerHeight + 24, maxHeight: `calc(100vh - ${headerHeight + 24}px)` }
|
|
815
|
+
}
|
|
816
|
+
) })
|
|
817
|
+
] }) }),
|
|
788
818
|
footer || /* @__PURE__ */ jsx7("footer", { className: "border-t border-gray-200 dark:border-gray-800 py-8 px-4 lg:px-10 transition-colors", children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col md:flex-row justify-between items-center gap-6", children: [
|
|
789
819
|
footerLogo && /* @__PURE__ */ jsx7(Link2, { href: "/", children: footerLogo }),
|
|
790
820
|
/* @__PURE__ */ jsxs6("div", { className: "flex gap-8 text-sm text-gray-600 dark:text-gray-400", children: [
|
|
@@ -1346,6 +1376,7 @@ export {
|
|
|
1346
1376
|
HomePage,
|
|
1347
1377
|
InlineCode,
|
|
1348
1378
|
Markdown,
|
|
1379
|
+
MobileMenuButton,
|
|
1349
1380
|
Sidebar,
|
|
1350
1381
|
TableOfContents,
|
|
1351
1382
|
ThemeProvider,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/CodeBlock.tsx","../src/lib/utils.ts","../src/lib/shiki.ts","../src/components/DocSetSelector.tsx","../src/components/DocsLayout.tsx","../src/components/Sidebar.tsx","../src/components/TableOfContents.tsx","../src/components/ThemeToggle.tsx","../src/components/ThemeProvider.tsx","../src/components/Markdown.tsx","../src/context/ComponentsContext.tsx","../src/components/DocsPage.tsx","../src/components/EmojiConfetti.tsx","../src/components/HomePage.tsx","../src/app.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\nimport { cn } from '../lib/utils'\nimport { getHighlighter } from '../lib/shiki'\nimport type { CodeBlockProps } from '../types'\n\n/**\n * Syntax-highlighted code block component using Shiki.\n */\nexport function CodeBlock({\n code,\n language = 'python',\n filename,\n showLineNumbers = false,\n theme = 'github-dark-dimmed',\n className,\n}: CodeBlockProps) {\n const [html, setHtml] = useState<string>('')\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n async function highlight() {\n const highlighter = await getHighlighter()\n const langs = highlighter.getLoadedLanguages()\n const lang = langs.includes(language) ? language : 'text'\n const highlighted = highlighter.codeToHtml(code.trim(), {\n lang,\n theme,\n })\n setHtml(highlighted)\n }\n highlight()\n }, [code, language, theme])\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(code.trim())\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <div className={cn('group relative overflow-hidden rounded-lg bg-[#24292f] not-prose mb-6', className)}>\n {filename && (\n <div className=\"flex items-center gap-2 border-b border-slate-700 bg-slate-900 px-4 py-2 text-sm text-slate-400\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n {filename}\n </div>\n )}\n <button\n onClick={copyToClipboard}\n className=\"absolute right-2 top-2 z-10 rounded-md bg-slate-700/50 px-2 py-1 text-xs text-slate-400 opacity-0 transition-opacity hover:bg-slate-600 hover:text-white group-hover:opacity-100\"\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n {html ? (\n <div\n className={cn(\n 'overflow-x-auto text-sm [&_pre]:m-0 [&_pre]:bg-transparent [&_code]:p-4',\n showLineNumbers && '[&_code]:grid [&_code]:grid-cols-[auto_1fr]'\n )}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre className=\"shiki overflow-x-auto m-0 bg-transparent\">\n <code className=\"block p-4 text-sm leading-relaxed text-gray-300\">{code.trim()}</code>\n </pre>\n )}\n </div>\n )\n}\n\n/**\n * Simple inline code component.\n */\nexport function InlineCode({ children }: { children: React.ReactNode }) {\n return (\n <code className=\"rounded bg-slate-100 px-1.5 py-0.5 text-sm font-medium text-slate-800\">\n {children}\n </code>\n )\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\n/**\n * Merge Tailwind CSS classes with clsx\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { createHighlighterCore, type HighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null\n\n// Default languages to load\nconst defaultLangs = [\n import('shiki/langs/python.mjs'),\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/shellscript.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/toml.mjs'),\n import('shiki/langs/markdown.mjs'),\n]\n\n// Default theme\nconst defaultTheme = import('shiki/themes/github-dark-dimmed.mjs')\n\n/**\n * Get or create a Shiki highlighter instance.\n * Uses a singleton pattern to avoid creating multiple highlighters.\n */\nexport function getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = createHighlighterCore({\n themes: [defaultTheme],\n langs: defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n }\n return highlighterPromise\n}\n\n/**\n * Configure the highlighter with custom themes and languages.\n * Must be called before getHighlighter() is first called.\n */\nexport function configureHighlighter(options: {\n theme?: Promise<any>\n langs?: Promise<any>[]\n}): void {\n if (highlighterPromise) {\n console.warn('configureHighlighter called after highlighter was created')\n return\n }\n\n highlighterPromise = createHighlighterCore({\n themes: [options.theme ?? defaultTheme],\n langs: options.langs ?? defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n}\n","import { useState, useRef, useEffect } from 'react'\nimport { router } from '@inertiajs/react'\nimport { cn } from '../lib/utils'\nimport type { DocSetMeta } from '../types'\n\ninterface DocSetSelectorProps {\n docSets: DocSetMeta[]\n currentDocSet: string\n className?: string\n}\n\n// Chevron icon with up/down indicators like Fumadocs\nconst ChevronUpDownIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 6l3-3 3 3M5 10l3 3 3-3\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n)\n\n// Checkmark for selected state\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.5 8.5l3 3 6-6.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n)\n\n// Default package/docs icon when no iconUrl is provided\nconst PackageIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 2L17 6v8l-7 4-7-4V6l7-4z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M10 10v8M10 10l7-4M10 10L3 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n)\n\n/**\n * Dropdown selector for switching between documentation sets.\n * Inspired by Fumadocs design - clean and minimal.\n */\nexport function DocSetSelector({ docSets, currentDocSet, className }: DocSetSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n\n const current = docSets.find((ds) => ds.slug === currentDocSet) || docSets[0]\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n // Close on escape key\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setIsOpen(false)\n }\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape)\n return () => document.removeEventListener('keydown', handleEscape)\n }\n }, [isOpen])\n\n const handleSelect = (docSet: DocSetMeta) => {\n setIsOpen(false)\n if (docSet.slug !== currentDocSet) {\n router.visit(`${docSet.prefix}/`)\n }\n }\n\n return (\n <div className={cn('relative', className)} ref={dropdownRef}>\n {/* Trigger Button - Clean, flat design like Fumadocs */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2',\n 'bg-gray-100/80 dark:bg-white/5',\n 'border border-gray-200 dark:border-white/10',\n 'rounded-lg',\n 'hover:bg-gray-200/80 dark:hover:bg-white/10',\n 'transition-colors duration-150',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50'\n )}\n aria-label=\"Select documentation\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n {/* Icon */}\n <div className=\"flex-shrink-0 w-5 h-5 flex items-center justify-center text-gray-600 dark:text-gray-400\">\n {current.icon ? (\n <span className=\"text-base leading-none\">{current.icon}</span>\n ) : current.iconUrl ? (\n <img src={current.iconUrl} alt=\"\" className=\"w-5 h-5\" />\n ) : (\n <PackageIcon className=\"w-5 h-5\" />\n )}\n </div>\n\n {/* Text */}\n <span className=\"flex-1 text-left text-sm font-medium text-gray-900 dark:text-white truncate\">\n {current.name}\n </span>\n\n {/* Chevron */}\n <ChevronUpDownIcon className=\"flex-shrink-0 w-4 h-4 text-gray-400 dark:text-gray-500\" />\n </button>\n\n {/* Dropdown Menu */}\n <div\n className={cn(\n 'absolute left-0 right-0 mt-1.5',\n 'py-1',\n 'bg-white dark:bg-[#1a1a1a]',\n 'border border-gray-200 dark:border-white/10',\n 'rounded-lg',\n 'shadow-lg shadow-black/5 dark:shadow-black/30',\n 'z-50',\n 'transition-all duration-150 ease-out origin-top',\n isOpen\n ? 'opacity-100 scale-100'\n : 'opacity-0 scale-95 pointer-events-none'\n )}\n role=\"listbox\"\n aria-label=\"Select documentation set\"\n >\n {docSets.map((docSet) => {\n const isSelected = docSet.slug === currentDocSet\n\n return (\n <button\n key={docSet.slug || '_root'}\n onClick={() => handleSelect(docSet)}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2',\n 'transition-colors duration-100',\n 'focus:outline-none',\n isSelected\n ? 'bg-primary-50 dark:bg-primary-500/10'\n : 'hover:bg-gray-50 dark:hover:bg-white/5'\n )}\n role=\"option\"\n aria-selected={isSelected}\n >\n {/* Icon */}\n <div className={cn(\n 'flex-shrink-0 w-5 h-5 flex items-center justify-center',\n isSelected\n ? 'text-primary-600 dark:text-primary-400'\n : 'text-gray-500 dark:text-gray-400'\n )}>\n {docSet.icon ? (\n <span className=\"text-base leading-none\">{docSet.icon}</span>\n ) : docSet.iconUrl ? (\n <img src={docSet.iconUrl} alt=\"\" className=\"w-5 h-5\" />\n ) : (\n <PackageIcon className=\"w-5 h-5\" />\n )}\n </div>\n\n {/* Text Content */}\n <div className=\"flex-1 text-left min-w-0\">\n <div\n className={cn(\n 'text-sm font-medium truncate',\n isSelected\n ? 'text-primary-700 dark:text-primary-300'\n : 'text-gray-900 dark:text-white'\n )}\n >\n {docSet.name}\n </div>\n {docSet.description && (\n <div className={cn(\n 'text-xs truncate',\n isSelected\n ? 'text-primary-600/70 dark:text-primary-400/70'\n : 'text-gray-500 dark:text-gray-400'\n )}>\n {docSet.description}\n </div>\n )}\n </div>\n\n {/* Checkmark indicator */}\n {isSelected && (\n <CheckIcon className=\"flex-shrink-0 w-4 h-4 text-primary-600 dark:text-primary-400\" />\n )}\n </button>\n )\n })}\n </div>\n </div>\n )\n}\n","import { Head, Link, usePage } from '@inertiajs/react'\nimport { useState } from 'react'\nimport { Sidebar } from './Sidebar'\nimport { TableOfContents } from './TableOfContents'\nimport { ThemeToggle } from './ThemeToggle'\nimport { useTheme } from './ThemeProvider'\nimport type { DocsLayoutProps, SharedProps } from '../types'\n\nfunction MobileMenuButton({ onClick, isOpen }: { onClick: () => void; isOpen: boolean }) {\n return (\n <button\n onClick={onClick}\n className=\"inline-flex items-center justify-center p-2 -ml-2 text-gray-700 hover:text-primary-500 dark:text-gray-300 dark:hover:text-primary-400 lg:hidden transition-colors\"\n aria-expanded={isOpen}\n >\n <span className=\"sr-only\">{isOpen ? 'Close menu' : 'Open menu'}</span>\n {isOpen ? (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ) : (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n )}\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n/**\n * Full-featured documentation layout with sidebar, mobile menu, and header.\n */\nexport function DocsLayout({\n children,\n title,\n description: _description,\n logo,\n logoInverted,\n logoUrl: propLogoUrl,\n logoInvertedUrl: propLogoInvertedUrl,\n githubUrl: propGithubUrl,\n navLinks: propNavLinks,\n footer,\n toc,\n}: DocsLayoutProps) {\n const sharedProps = usePage<{ props: SharedProps }>().props as unknown as SharedProps\n const { nav, currentPath, docSets, currentDocSet } = sharedProps\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n const { resolvedTheme } = useTheme()\n\n // Merge props - component props take precedence over shared props from Python\n const logoUrl = propLogoUrl ?? sharedProps.logoUrl\n const logoInvertedUrl = propLogoInvertedUrl ?? sharedProps.logoInvertedUrl\n const githubUrl = propGithubUrl ?? sharedProps.githubUrl\n const navLinks = propNavLinks ?? sharedProps.navLinks ?? []\n\n // Determine which logo to display in header (prefer inverted/dark version)\n const headerLogo = logoInverted || logo || (logoInvertedUrl ? (\n <img src={logoInvertedUrl} alt=\"Logo\" className=\"h-8\" />\n ) : logoUrl ? (\n <img src={logoUrl} alt=\"Logo\" className=\"h-8\" />\n ) : null)\n\n // Determine which logo to display in footer (theme-aware)\n const footerLogoUrl = sharedProps.footerLogoUrl || logoUrl\n const footerLogoInvertedUrl = sharedProps.footerLogoInvertedUrl || logoInvertedUrl\n const currentFooterLogoUrl = resolvedTheme === 'dark' ? (footerLogoInvertedUrl || footerLogoUrl) : footerLogoUrl\n const footerLogo = logo || (currentFooterLogoUrl ? (\n <img src={currentFooterLogoUrl} alt=\"Logo\" className=\"h-6\" />\n ) : null)\n\n return (\n <div className=\"min-h-screen bg-white dark:bg-[#0f0f0f] flex flex-col transition-colors duration-200\">\n <Head title={title} />\n\n {/* Fixed navigation */}\n <nav className=\"fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n <div className=\"flex items-center gap-2\">\n <MobileMenuButton onClick={() => setMobileMenuOpen(!mobileMenuOpen)} isOpen={mobileMenuOpen} />\n {headerLogo ? (\n <Link href=\"/\" className=\"flex items-center\">\n {headerLogo}\n </Link>\n ) : (\n <Link href=\"/\" className=\"font-bold text-lg text-gray-900 dark:text-white\">\n Docs\n </Link>\n )}\n </div>\n <div className=\"flex items-center gap-6\">\n <div className=\"-mr-2\">\n <ThemeToggle size=\"sm\" />\n </div>\n\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"hidden sm:block text-gray-700 dark:text-gray-300 font-medium hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n\n {/* Mobile sidebar */}\n {mobileMenuOpen && (\n <div className=\"fixed inset-0 z-40 lg:hidden\">\n <div className=\"fixed inset-0 bg-black/50 dark:bg-black/70\" onClick={() => setMobileMenuOpen(false)} />\n <div className=\"fixed inset-y-0 left-0 w-64 overflow-y-auto bg-white dark:bg-[#0f0f0f] px-4 py-6 pt-20 border-r border-gray-200 dark:border-gray-800 transition-colors\">\n <Sidebar nav={nav} currentPath={currentPath} docSets={docSets} currentDocSet={currentDocSet} />\n </div>\n </div>\n )}\n\n {/* Main content area */}\n <div className=\"bg-white dark:bg-[#0f0f0f] pt-16 w-full flex-1 transition-colors\">\n <div className=\"flex\">\n {/* Desktop sidebar - fixed width */}\n <aside className=\"hidden lg:block w-72 flex-shrink-0 border-r border-gray-200 dark:border-gray-800 min-h-[calc(100vh-4rem)] transition-colors\">\n <nav className=\"sticky top-16 px-4 py-6 max-h-[calc(100vh-4rem)] overflow-y-auto\">\n <Sidebar nav={nav} currentPath={currentPath} docSets={docSets} currentDocSet={currentDocSet} />\n </nav>\n </aside>\n\n {/* Right section: content + TOC + footer (not under left sidebar) */}\n <div className=\"flex-1 min-w-0 flex flex-col\">\n <div className=\"flex flex-1\">\n {/* Main content */}\n <main className=\"flex-1 min-w-0 p-4 lg:px-10 lg:py-6\">\n <article className=\"prose prose-lg max-w-3xl prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-3xl prose-h1:mb-4 prose-h2:text-2xl prose-h2:mt-10 first:prose-h2:mt-0 prose-h3:text-xl prose-a:text-primary-600 dark:prose-a:text-primary-400 prose-a:no-underline hover:prose-a:underline prose-code:bg-gray-100 dark:prose-code:bg-gray-800 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none dark:prose-headings:text-white dark:prose-strong:text-white dark:text-gray-300\">\n {children}\n </article>\n </main>\n\n {/* Table of Contents - desktop only */}\n {toc && toc.length > 0 && (\n <aside className=\"hidden xl:block w-64 flex-shrink-0 transition-colors\">\n <div className=\"sticky top-16 px-4 py-6 max-h-[calc(100vh-4rem)] overflow-y-auto\">\n <TableOfContents items={toc} />\n </div>\n </aside>\n )}\n </div>\n\n {/* Footer - spans from after sidebar to right edge */}\n {footer || (\n <footer className=\"border-t border-gray-200 dark:border-gray-800 py-8 px-4 lg:px-10 transition-colors\">\n <div className=\"flex flex-col md:flex-row justify-between items-center gap-6\">\n {footerLogo && <Link href=\"/\">{footerLogo}</Link>}\n <div className=\"flex gap-8 text-sm text-gray-600 dark:text-gray-400\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black dark:hover:text-white transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black dark:hover:text-white transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n}\n","import { Link } from '@inertiajs/react'\nimport { cn } from '../lib/utils'\nimport { DocSetSelector } from './DocSetSelector'\nimport type { SidebarProps } from '../types'\n\n/**\n * Documentation sidebar with section-based navigation.\n * In multi-docs mode, includes a dropdown selector at the top.\n */\nexport function Sidebar({ nav, currentPath, className, docSets, currentDocSet }: SidebarProps) {\n return (\n <nav className={cn('space-y-6', className)}>\n {/* Doc Set Selector - only shown in multi-docs mode */}\n {docSets && docSets.length > 1 && (\n <DocSetSelector docSets={docSets} currentDocSet={currentDocSet ?? ''} className=\"mb-6\" />\n )}\n\n {/* Navigation Sections */}\n <div className=\"space-y-8\">\n {nav.map((section) => (\n <div key={section.title}>\n <h3 className=\"mb-3 text-xs font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400\">\n {section.title}\n </h3>\n <ul className=\"space-y-2 border-l-2 border-gray-200 dark:border-gray-700\">\n {section.items.map((item) => (\n <li key={item.href}>\n <Link\n href={item.href}\n className={cn(\n 'block border-l-2 py-2 pl-4 text-base transition-colors -ml-0.5',\n currentPath === item.href\n ? 'border-primary-500 text-gray-900 dark:text-white font-bold'\n : 'border-transparent text-gray-600 dark:text-gray-300 hover:border-gray-900 dark:hover:border-white hover:text-gray-900 dark:hover:text-white'\n )}\n >\n {item.title}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </nav>\n )\n}\n","import { useEffect, useState, useRef } from 'react'\nimport type { TableOfContentsProps } from '../types'\n\n/**\n * Table of contents component with scroll spy functionality.\n * Displays \"ON THIS PAGE\" sidebar with heading links.\n */\nexport function TableOfContents({ items, className = '' }: TableOfContentsProps) {\n const [activeId, setActiveId] = useState<string>(() => {\n // Initialize with hash from URL if present\n if (typeof window !== 'undefined' && window.location.hash) {\n return window.location.hash.slice(1)\n }\n return ''\n })\n\n // Track if we're currently scrolling from a click\n const isClickScrolling = useRef(false)\n\n useEffect(() => {\n if (items.length === 0) return\n\n // Listen for hash changes\n const handleHashChange = () => {\n const hash = window.location.hash.slice(1)\n if (hash) {\n setActiveId(hash)\n }\n }\n window.addEventListener('hashchange', handleHashChange)\n\n // Scroll-based detection - find the heading closest to top of viewport\n const handleScroll = () => {\n // Skip if we're in the middle of a click-initiated scroll\n if (isClickScrolling.current) return\n\n const headerOffset = 100\n let currentId = ''\n\n // Check if we're at the bottom of the page\n const scrollTop = window.scrollY\n const scrollHeight = document.documentElement.scrollHeight\n const clientHeight = document.documentElement.clientHeight\n const isAtBottom = scrollTop + clientHeight >= scrollHeight - 50\n\n if (isAtBottom) {\n // At bottom of page - find the last heading that's visible in viewport\n for (let i = items.length - 1; i >= 0; i--) {\n const element = document.getElementById(items[i].id)\n if (element) {\n const rect = element.getBoundingClientRect()\n // If this heading is visible in the viewport\n if (rect.top < clientHeight && rect.bottom > 0) {\n currentId = items[i].id\n break\n }\n }\n }\n } else {\n // Normal scroll detection\n for (const item of items) {\n const element = document.getElementById(item.id)\n if (element) {\n const rect = element.getBoundingClientRect()\n // If the heading is at or above the threshold, it's the current section\n if (rect.top <= headerOffset) {\n currentId = item.id\n } else {\n // Once we find a heading below the threshold, stop\n break\n }\n }\n }\n }\n\n // If no heading is above threshold, use the first one\n if (!currentId && items.length > 0) {\n currentId = items[0].id\n }\n\n if (currentId) {\n setActiveId(currentId)\n }\n }\n\n // Throttle scroll handler\n let ticking = false\n const scrollListener = () => {\n if (!ticking) {\n requestAnimationFrame(() => {\n handleScroll()\n ticking = false\n })\n ticking = true\n }\n }\n\n window.addEventListener('scroll', scrollListener, { passive: true })\n\n // Initial check (only if no hash in URL)\n if (!window.location.hash) {\n handleScroll()\n }\n\n return () => {\n window.removeEventListener('scroll', scrollListener)\n window.removeEventListener('hashchange', handleHashChange)\n }\n }, [items])\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {\n e.preventDefault()\n const element = document.getElementById(id)\n if (element) {\n // Mark that we're click-scrolling to prevent scroll handler from overriding\n isClickScrolling.current = true\n setActiveId(id)\n\n const top = element.getBoundingClientRect().top + window.scrollY - 80\n window.scrollTo({ top, behavior: 'smooth' })\n\n // Update URL hash without jumping\n window.history.pushState(null, '', `#${id}`)\n\n // Re-enable scroll detection after scroll settles\n // Use requestAnimationFrame loop to wait for scroll to stabilize\n let lastScrollY = window.scrollY\n let stableCount = 0\n const checkScrollEnd = () => {\n if (window.scrollY === lastScrollY) {\n stableCount++\n if (stableCount >= 5) {\n // Scroll has been stable for ~5 frames, animation is done\n isClickScrolling.current = false\n return\n }\n } else {\n stableCount = 0\n lastScrollY = window.scrollY\n }\n requestAnimationFrame(checkScrollEnd)\n }\n requestAnimationFrame(checkScrollEnd)\n }\n }\n\n if (items.length === 0) {\n return null\n }\n\n return (\n <nav className={className}>\n <h3 className=\"mb-3 text-xs font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400\">\n On this page\n </h3>\n <ul className=\"space-y-1 border-l-2 border-gray-200 dark:border-gray-700\">\n {items.map((item) => {\n const isActive = activeId === item.id\n const indent = item.level === 3 ? 'pl-6' : 'pl-4'\n\n return (\n <li key={item.id}>\n <a\n href={`#${item.id}`}\n onClick={(e) => handleClick(e, item.id)}\n className={`block border-l-2 py-1.5 ${indent} -ml-0.5 text-sm transition-colors ${\n isActive\n ? 'border-primary-500 text-gray-900 dark:text-white font-bold'\n : 'border-transparent text-gray-600 dark:text-gray-300 hover:border-gray-900 dark:hover:border-white hover:text-gray-900 dark:hover:text-white'\n }`}\n >\n {item.text}\n </a>\n </li>\n )\n })}\n </ul>\n </nav>\n )\n}\n","import { useState, useRef, useEffect } from 'react'\nimport { useTheme, type Theme } from './ThemeProvider'\nimport { cn } from '../lib/utils'\n\ninterface ThemeToggleProps {\n /** Additional CSS classes */\n className?: string\n /** Size variant */\n size?: 'sm' | 'md' | 'lg'\n}\n\n// Refined sun icon with balanced proportions\nconst SunIcon = ({ className }: { className?: string }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M12 5V3M12 21v-2M5 12H3m18 0h-2M7.05 7.05 5.636 5.636m12.728 12.728L16.95 16.95M7.05 16.95l-1.414 1.414M18.364 5.636 16.95 7.05\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n)\n\n// Refined moon icon - elegant crescent\nconst MoonIcon = ({ className }: { className?: string }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.752 15.002A9.718 9.718 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n)\n\n// Refined monitor icon - clean display shape\nconst MonitorIcon = ({ className }: { className?: string }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 21h8m-4-4v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n)\n\nconst themeOptions: { value: Theme; label: string; icon: typeof SunIcon }[] = [\n { value: 'light', label: 'Light', icon: SunIcon },\n { value: 'dark', label: 'Dark', icon: MoonIcon },\n { value: 'system', label: 'System', icon: MonitorIcon },\n]\n\n/**\n * Theme toggle dropdown with Light, Dark, and System options.\n * Refined design with smooth animations and premium feel.\n */\nexport function ThemeToggle({ className, size = 'md' }: ThemeToggleProps) {\n const { theme, resolvedTheme, setTheme } = useTheme()\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n // Close on escape key\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setIsOpen(false)\n }\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape)\n return () => document.removeEventListener('keydown', handleEscape)\n }\n }, [isOpen])\n\n const iconSizes = {\n sm: 'w-[18px] h-[18px]',\n md: 'w-5 h-5',\n lg: 'w-[22px] h-[22px]',\n }\n\n return (\n <div className=\"relative\" ref={dropdownRef}>\n {/* Toggle Button */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'relative inline-flex items-center justify-center',\n 'rounded-full p-4',\n 'text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white',\n 'hover:bg-gray-100 dark:hover:bg-white/10',\n 'transition-all duration-200 ease-out',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-[#0f0f0f]',\n iconSizes[size],\n className\n )}\n aria-label=\"Toggle theme\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n {/* Sun icon - visible in light mode */}\n <SunIcon\n className={cn(\n iconSizes[size],\n 'absolute inset-0 m-auto transition-all duration-300 ease-out',\n resolvedTheme === 'light'\n ? 'rotate-0 scale-100 opacity-100'\n : 'rotate-90 scale-75 opacity-0'\n )}\n />\n\n {/* Moon icon - visible in dark mode */}\n <MoonIcon\n className={cn(\n iconSizes[size],\n 'absolute inset-0 m-auto transition-all duration-300 ease-out',\n resolvedTheme === 'dark'\n ? 'rotate-0 scale-100 opacity-100'\n : '-rotate-90 scale-75 opacity-0'\n )}\n />\n </button>\n\n {/* Dropdown Menu */}\n <div\n className={cn(\n 'absolute right-0 mt-2 min-w-[140px]',\n 'p-1',\n 'bg-white dark:bg-[#171717]',\n 'border border-gray-200 dark:border-[#262626]',\n 'rounded-xl',\n 'shadow-lg shadow-black/5 dark:shadow-black/40',\n 'z-50',\n 'transition-all duration-200 ease-out origin-top-right',\n isOpen\n ? 'opacity-100 scale-100 translate-y-0'\n : 'opacity-0 scale-95 -translate-y-1 pointer-events-none'\n )}\n role=\"listbox\"\n aria-label=\"Select theme\"\n >\n {themeOptions.map((option, index) => {\n const Icon = option.icon\n const isSelected = theme === option.value\n\n return (\n <button\n key={option.value}\n onClick={() => {\n setTheme(option.value)\n setIsOpen(false)\n }}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2',\n 'rounded-lg',\n 'text-[13px] font-medium',\n 'transition-all duration-150 ease-out',\n 'focus:outline-none',\n isSelected\n ? 'text-gray-900 dark:text-white bg-gray-100 dark:bg-[#262626]'\n : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-[#1f1f1f]'\n )}\n role=\"option\"\n aria-selected={isSelected}\n style={{\n animationDelay: isOpen ? `${index * 25}ms` : '0ms'\n }}\n >\n <Icon className={cn(\n 'w-4 h-4 flex-shrink-0',\n 'transition-transform duration-150',\n isSelected ? 'scale-110' : 'scale-100'\n )} />\n <span className=\"flex-1 text-left\">{option.label}</span>\n <div className={cn(\n 'w-1.5 h-1.5 rounded-full',\n 'transition-all duration-200',\n isSelected\n ? 'bg-primary-500 scale-100 opacity-100'\n : 'bg-transparent scale-0 opacity-0'\n )} />\n </button>\n )\n })}\n </div>\n </div>\n )\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'\n\nexport type Theme = 'light' | 'dark' | 'system'\nexport type ResolvedTheme = 'light' | 'dark'\n\ninterface ThemeContextValue {\n theme: Theme\n resolvedTheme: ResolvedTheme\n setTheme: (theme: Theme) => void\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nconst STORAGE_KEY = 'cross-docs-theme'\n\nfunction getSystemTheme(): ResolvedTheme {\n if (typeof window === 'undefined') return 'light'\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\nfunction getStoredTheme(): Theme | null {\n if (typeof window === 'undefined') return null\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored === 'light' || stored === 'dark' || stored === 'system') {\n return stored\n }\n return null\n}\n\ninterface ThemeProviderProps {\n children: ReactNode\n /** Default theme if no preference is stored. Defaults to 'system'. */\n defaultTheme?: Theme\n /** Force a specific theme, ignoring user preference */\n forcedTheme?: ResolvedTheme\n}\n\nexport function ThemeProvider({\n children,\n defaultTheme = 'system',\n forcedTheme,\n}: ThemeProviderProps) {\n const [theme, setThemeState] = useState<Theme>(() => {\n // During SSR, use defaultTheme\n if (typeof window === 'undefined') return defaultTheme\n return getStoredTheme() ?? defaultTheme\n })\n\n const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>(() => {\n if (forcedTheme) return forcedTheme\n if (typeof window === 'undefined') return 'light'\n if (theme === 'system') return getSystemTheme()\n return theme\n })\n\n // Update resolved theme when theme changes or system preference changes\n useEffect(() => {\n if (forcedTheme) {\n setResolvedTheme(forcedTheme)\n return\n }\n\n const updateResolvedTheme = () => {\n if (theme === 'system') {\n setResolvedTheme(getSystemTheme())\n } else {\n setResolvedTheme(theme)\n }\n }\n\n updateResolvedTheme()\n\n // Listen for system preference changes\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n const handleChange = () => {\n if (theme === 'system') {\n setResolvedTheme(getSystemTheme())\n }\n }\n\n mediaQuery.addEventListener('change', handleChange)\n return () => mediaQuery.removeEventListener('change', handleChange)\n }, [theme, forcedTheme])\n\n // Apply theme class to document\n useEffect(() => {\n const root = document.documentElement\n root.classList.remove('light', 'dark')\n root.classList.add(resolvedTheme)\n }, [resolvedTheme])\n\n const setTheme = (newTheme: Theme) => {\n setThemeState(newTheme)\n localStorage.setItem(STORAGE_KEY, newTheme)\n }\n\n return (\n <ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>\n {children}\n </ThemeContext.Provider>\n )\n}\n\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext)\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider')\n }\n return context\n}\n\n/**\n * Script to prevent flash of unstyled content (FOUC) during page load.\n * Include this in your HTML <head> before any stylesheets.\n */\nexport const themeInitScript = `\n(function() {\n try {\n var stored = localStorage.getItem('${STORAGE_KEY}');\n var theme = stored === 'light' || stored === 'dark' ? stored :\n (stored === 'system' || !stored) && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n document.documentElement.classList.add(theme);\n } catch (e) {}\n})();\n`.trim()\n","import ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport remarkEmoji from 'remark-emoji'\nimport { remarkAlert } from 'remark-github-blockquote-alert'\nimport rehypeRaw from 'rehype-raw'\nimport { CodeBlock } from './CodeBlock'\nimport type { MarkdownProps } from '../types'\n\n/**\n * Convert heading text to URL-safe slug.\n * Must match the Python slugify function in markdown.py.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\n/**\n * Extract text content from React children.\n */\nfunction getTextContent(children: React.ReactNode): string {\n if (typeof children === 'string') return children\n if (typeof children === 'number') return String(children)\n if (Array.isArray(children)) return children.map(getTextContent).join('')\n if (children && typeof children === 'object' && 'props' in children) {\n return getTextContent((children as React.ReactElement).props.children)\n }\n return ''\n}\n\n/**\n * Markdown renderer with syntax highlighting and GFM support.\n */\nexport function Markdown({ content, components }: MarkdownProps) {\n // Create lowercase mappings for custom components\n // HTML tag names are case-insensitive, so <TerminalExample> becomes <terminalexample>\n const lowercaseComponents = components\n ? Object.entries(components).reduce(\n (acc, [name, Component]) => {\n acc[name.toLowerCase()] = Component\n return acc\n },\n {} as Record<string, React.ComponentType<any>>\n )\n : {}\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkEmoji, remarkAlert]}\n rehypePlugins={[rehypeRaw]}\n components={{\n ...lowercaseComponents,\n // Override pre to avoid double wrapping with CodeBlock\n pre({ children }) {\n return <>{children}</>\n },\n // Custom code block rendering with syntax highlighting\n code({ node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || '')\n const isInline = !match && !className\n\n if (isInline) {\n return (\n <code\n className=\"rounded bg-gray-100 px-1.5 py-0.5 text-sm font-medium text-gray-800 dark:bg-gray-800 dark:text-gray-200\"\n {...props}\n >\n {children}\n </code>\n )\n }\n\n // Parse meta string from the code fence (e.g., ```python title=\"app.py\" showLineNumbers)\n const meta = (node?.data?.meta as string) || ''\n const titleMatch = /title=\"([^\"]+)\"/.exec(meta)\n const filename = titleMatch ? titleMatch[1] : undefined\n const showLineNumbers = meta.includes('showLineNumbers')\n\n return (\n <CodeBlock\n code={String(children).replace(/\\n$/, '')}\n language={match ? match[1] : 'text'}\n filename={filename}\n showLineNumbers={showLineNumbers}\n />\n )\n },\n // Custom link styling\n a({ href, children, node, ...props }) {\n const isExternal = href?.startsWith('http')\n return (\n <a\n href={href}\n className=\"text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300\"\n {...(isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n {...props}\n >\n {children}\n </a>\n )\n },\n // Tables\n table({ children }) {\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-left text-sm\">{children}</table>\n </div>\n )\n },\n th({ children }) {\n return (\n <th className=\"border-b border-gray-200 bg-gray-50 px-4 py-2 font-semibold dark:border-gray-700 dark:bg-gray-800\">\n {children}\n </th>\n )\n },\n td({ children }) {\n return (\n <td className=\"border-b border-gray-200 px-4 py-2 dark:border-gray-700\">\n {children}\n </td>\n )\n },\n // Headings with anchor IDs for TOC\n h2({ children }) {\n const text = getTextContent(children)\n const id = slugify(text)\n return (\n <h2 id={id}>\n {children}\n </h2>\n )\n },\n h3({ children }) {\n const text = getTextContent(children)\n const id = slugify(text)\n return (\n <h3 id={id}>\n {children}\n </h3>\n )\n },\n // Task list checkbox styling\n input({ type, checked, disabled, ...props }) {\n if (type === 'checkbox') {\n return (\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n className=\"mr-2 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700\"\n {...props}\n />\n )\n }\n return <input type={type} checked={checked} disabled={disabled} {...props} />\n },\n // Footnote section styling\n section({ className, children, ...props }) {\n if (className?.includes('footnotes')) {\n return (\n <section\n className=\"mt-8 border-t border-gray-200 pt-6 text-sm text-gray-600 dark:border-gray-700 dark:text-gray-400\"\n {...props}\n >\n {children}\n </section>\n )\n }\n return <section className={className} {...props}>{children}</section>\n },\n }}\n >\n {content}\n </ReactMarkdown>\n )\n}\n","import React, { createContext, useContext } from 'react'\n\ninterface ComponentsContextValue {\n components?: Record<string, React.ComponentType<any>>\n}\n\nconst ComponentsContext = createContext<ComponentsContextValue>({})\n\nexport function ComponentsProvider({\n children,\n components,\n}: {\n children: React.ReactNode\n components?: Record<string, React.ComponentType<any>>\n}) {\n return (\n <ComponentsContext.Provider value={{ components }}>\n {children}\n </ComponentsContext.Provider>\n )\n}\n\nexport function useComponents() {\n return useContext(ComponentsContext)\n}\n","import { DocsLayout } from './DocsLayout'\nimport { Markdown } from './Markdown'\nimport type { DocContent, DocsLayoutProps } from '../types'\nimport { useComponents } from '../context/ComponentsContext'\n\ninterface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {\n content: DocContent\n}\n\n/**\n * Default documentation page component.\n * Renders markdown content within the DocsLayout.\n */\nexport function DocsPage({ content, ...layoutProps }: DocsPageProps) {\n const { components } = useComponents()\n\n return (\n <DocsLayout\n title={content?.title ?? ''}\n description={content?.description}\n toc={content?.toc}\n {...layoutProps}\n >\n <Markdown content={content?.body ?? ''} components={components} />\n </DocsLayout>\n )\n}\n","import { useState, useCallback } from 'react'\n\ninterface ConfettiParticle {\n id: number\n x: number\n y: number\n angle: number\n velocity: number\n spin: number\n scale: number\n}\n\nexport function EmojiConfetti({ children, emoji }: { children: React.ReactNode; emoji: string }) {\n const [particles, setParticles] = useState<ConfettiParticle[]>([])\n const [isActive, setIsActive] = useState(false)\n\n const triggerBurst = useCallback(() => {\n if (isActive) return\n setIsActive(true)\n\n const newParticles: ConfettiParticle[] = []\n const count = 15\n\n for (let i = 0; i < count; i++) {\n // Burst in all directions from center\n const angle = (i / count) * Math.PI * 2 + (Math.random() - 0.5) * 0.5\n newParticles.push({\n id: Date.now() + i,\n x: 50, // Start from center\n y: 50,\n angle,\n velocity: 80 + Math.random() * 60, // Distance to travel\n spin: (Math.random() - 0.5) * 720, // Random rotation\n scale: 0.7 + Math.random() * 0.6,\n })\n }\n setParticles(newParticles)\n\n setTimeout(() => {\n setParticles([])\n setIsActive(false)\n }, 1000)\n }, [isActive])\n\n return (\n <span\n className=\"relative inline-block\"\n onMouseEnter={triggerBurst}\n >\n {children}\n <span className=\"absolute inset-0 pointer-events-none overflow-visible\">\n {particles.map((p) => {\n const endX = p.x + Math.cos(p.angle) * p.velocity\n const endY = p.y + Math.sin(p.angle) * p.velocity\n\n return (\n <span\n key={p.id}\n className=\"absolute\"\n style={{\n left: '50%',\n top: '50%',\n fontSize: `${p.scale}rem`,\n transform: 'translate(-50%, -50%)',\n animation: `emojiConfettiBurst 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards`,\n '--end-x': `${(endX - 50)}px`,\n '--end-y': `${(endY - 50)}px`,\n '--spin': `${p.spin}deg`,\n } as React.CSSProperties}\n >\n {emoji}\n </span>\n )\n })}\n </span>\n </span>\n )\n}\n","import { Head, Link } from '@inertiajs/react'\nimport { createContext, useContext, useState, type ReactNode } from 'react'\nimport { ThemeToggle } from './ThemeToggle'\nimport { useTheme } from './ThemeProvider'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HomeFeature {\n title: string\n description: ReactNode\n}\n\nexport interface HomePageContextValue {\n title: string\n tagline: string\n description: string\n installCommand: string\n ctaText: string\n ctaHref: string\n features: HomeFeature[]\n logoUrl?: string\n heroLogoUrl?: string\n footerLogoUrl?: string\n footerLogoInvertedUrl?: string\n githubUrl?: string\n navLinks: Array<{ label: string; href: string }>\n}\n\nexport interface HomePageProps extends Omit<HomePageContextValue, 'navLinks'> {\n navLinks?: Array<{ label: string; href: string }>\n children?: ReactNode\n}\n\nexport interface HomeHeaderProps {\n renderLogo?: () => ReactNode\n}\n\nexport interface HomeFeaturesProps {\n renderFeature?: (\n feature: HomeFeature,\n index: number,\n DefaultFeature: typeof HomeFeatureItem\n ) => ReactNode\n}\n\nexport interface HomeFeatureItemProps {\n feature: HomeFeature\n index: number\n totalFeatures: number\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst HomePageContext = createContext<HomePageContextValue | null>(null)\n\nfunction useHomePage(): HomePageContextValue {\n const context = useContext(HomePageContext)\n if (!context) {\n throw new Error('HomePage sub-components must be used within <HomePage>')\n }\n return context\n}\n\n// ============================================================================\n// Utility Components\n// ============================================================================\n\nfunction InstallCommand({ command }: { command: string }) {\n const [copied, setCopied] = useState(false)\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(command)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n onClick={copyToClipboard}\n className=\"group relative flex items-center bg-gray-900 dark:bg-white border border-gray-900 dark:border-white px-4 h-14 font-mono text-sm text-white dark:text-gray-900 hover:bg-white dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-white transition-colors cursor-pointer\"\n >\n <span className=\"text-primary-500 dark:text-primary-600 mr-2\">$</span>\n <span>{command}</span>\n <svg\n className={`ml-4 w-4 h-4 transition ${copied ? 'text-green-400' : 'opacity-50 group-hover:opacity-100'}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span\n className={`absolute -top-8 left-1/2 -translate-x-1/2 bg-gray-900 dark:bg-white text-white dark:text-gray-900 text-xs py-1 px-2 rounded transition-opacity duration-300 whitespace-nowrap ${\n copied ? 'opacity-100' : 'opacity-0'\n }`}\n >\n Copied!\n </span>\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n// ============================================================================\n// Sub-Components\n// ============================================================================\n\n/**\n * Default logo component that renders an image or text.\n */\nfunction DefaultLogo() {\n const { title, logoUrl } = useHomePage()\n\n if (logoUrl) {\n return (\n <Link href=\"/\" className=\"flex items-center\">\n <img src={logoUrl} alt={title} className=\"h-8\" />\n </Link>\n )\n }\n\n return (\n <Link href=\"/\" className=\"font-bold text-lg text-gray-900 dark:text-white\">\n {title}\n </Link>\n )\n}\n\n/**\n * Navigation header for the homepage.\n * Accepts an optional renderLogo prop for custom logo rendering.\n */\nexport function HomeHeader({ renderLogo }: HomeHeaderProps = {}) {\n const { navLinks, githubUrl } = useHomePage()\n\n return (\n <nav className=\"fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n {renderLogo ? renderLogo() : <DefaultLogo />}\n <div className=\"flex items-center gap-6\">\n <div className=\"-mr-2\">\n <ThemeToggle size=\"sm\" />\n </div>\n\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"hidden sm:block text-gray-700 dark:text-gray-300 font-medium hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n )\n}\n\n/**\n * Hero section with title, tagline, description, and CTA.\n * If heroLogoUrl is provided, displays an image instead of text title.\n */\nexport function HomeHero() {\n const { title, tagline, description, ctaText, ctaHref, installCommand, heroLogoUrl } = useHomePage()\n\n return (\n <section className=\"pt-16\">\n <div className=\"px-4 lg:px-10 py-16 lg:py-24\">\n <div className=\"max-w-4xl\">\n <div className=\"mb-4 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400\">\n {tagline}\n </div>\n {heroLogoUrl ? (\n <h1 className=\"mb-6 lg:mb-8\">\n <img\n src={heroLogoUrl}\n alt={title}\n className=\"h-auto w-auto max-w-[580px]\"\n />\n </h1>\n ) : (\n <h1 className=\"text-5xl lg:text-7xl font-bold tracking-tight mb-6 text-gray-900 dark:text-white\">\n {title}\n </h1>\n )}\n <p className=\"text-xl lg:text-2xl text-gray-600 dark:text-gray-300 max-w-2xl leading-relaxed mb-8\">\n {description}\n </p>\n\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 h-14 bg-gray-900 dark:bg-white text-white dark:text-gray-900 font-bold text-lg hover:bg-primary-500 dark:hover:bg-primary-500 dark:hover:text-white transition-colors border border-gray-900 dark:border-white hover:border-primary-500 dark:hover:border-primary-500\"\n >\n {ctaText}\n </Link>\n {installCommand && <InstallCommand command={installCommand} />}\n </div>\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Single feature item within the features grid.\n */\nexport function HomeFeatureItem({ feature, index, totalFeatures }: HomeFeatureItemProps) {\n return (\n <div\n className={`p-4 lg:p-10 border-b sm:border-b border-gray-200 dark:border-gray-800 ${\n index % 2 === 0 ? 'sm:border-r' : ''\n } ${index >= totalFeatures - 2 ? 'sm:border-b-0' : ''} ${\n index === totalFeatures - 1 && totalFeatures % 2 === 1 ? 'border-b-0' : ''\n } transition-colors`}\n >\n <div className=\"text-5xl font-bold text-primary-500 dark:text-primary-400 mb-4\">\n {String(index + 1).padStart(2, '0')}\n </div>\n <h3 className=\"text-xl font-bold mb-2 text-gray-900 dark:text-white\">{feature.title}</h3>\n <p className=\"text-gray-600 dark:text-gray-300\">{feature.description}</p>\n </div>\n )\n}\n\n/**\n * Features section with customizable feature rendering.\n */\nexport function HomeFeatures({ renderFeature }: HomeFeaturesProps = {}) {\n const { title, features } = useHomePage()\n\n if (features.length === 0) {\n return null\n }\n\n return (\n <section className=\"border-t border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"grid grid-cols-12\">\n <div className=\"col-span-12 lg:col-span-4 p-4 lg:p-10 border-b lg:border-b-0 lg:border-r border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400 mb-4\">\n Features\n </div>\n <h2 className=\"text-4xl lg:text-5xl font-bold tracking-tight text-gray-900 dark:text-white\">\n Why {title}?\n </h2>\n </div>\n\n <div className=\"col-span-12 lg:col-span-8 grid grid-cols-1 sm:grid-cols-2\">\n {features.map((feature, index) =>\n renderFeature ? (\n <div key={index}>\n {renderFeature(feature, index, HomeFeatureItem)}\n </div>\n ) : (\n <HomeFeatureItem\n key={index}\n feature={feature}\n index={index}\n totalFeatures={features.length}\n />\n )\n )}\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Call-to-action section.\n */\nexport function HomeCTA() {\n const { ctaHref } = useHomePage()\n\n return (\n <section className=\"border-t border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"grid grid-cols-12 items-center\">\n <div className=\"col-span-12 lg:col-span-8 p-4 lg:p-10\">\n <h2 className=\"text-4xl lg:text-6xl font-bold tracking-tight mb-4 text-gray-900 dark:text-white\">\n Ready to start?\n </h2>\n <p className=\"text-xl text-gray-600 dark:text-gray-300 mb-8 max-w-2xl\">\n Get up and running in minutes. Check out our documentation to learn more.\n </p>\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 py-4 bg-primary-500 text-white font-bold text-lg hover:bg-gray-900 dark:hover:bg-white dark:hover:text-gray-900 transition-colors border border-primary-500 hover:border-gray-900 dark:hover:border-white\"\n >\n Read the Docs\n </Link>\n </div>\n <Link\n href={ctaHref}\n className=\"col-span-12 lg:col-span-4 h-full bg-primary-500 hidden lg:flex items-center justify-center p-4 lg:p-10 hover:bg-gray-900 dark:hover:bg-white transition-colors min-h-[200px] group\"\n >\n <div className=\"text-white group-hover:text-white dark:group-hover:text-gray-900 text-8xl font-bold transition-colors\">→</div>\n </Link>\n </div>\n </section>\n )\n}\n\n/**\n * Footer section.\n */\nexport function HomeFooter() {\n const { title, logoUrl, footerLogoUrl, footerLogoInvertedUrl, navLinks, githubUrl } = useHomePage()\n const { resolvedTheme } = useTheme()\n\n // Select appropriate logo based on theme\n const currentLogoUrl = resolvedTheme === 'dark'\n ? (footerLogoInvertedUrl || footerLogoUrl || logoUrl)\n : (footerLogoUrl || logoUrl)\n\n return (\n <footer className=\"border-t border-gray-200 dark:border-gray-800 py-8 bg-white dark:bg-[#0f0f0f] transition-colors\">\n <div className=\"px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6\">\n {currentLogoUrl && (\n <Link href=\"/\">\n <img src={currentLogoUrl} alt={title} className=\"h-6\" />\n </Link>\n )}\n <div className=\"flex gap-8 text-sm text-gray-600 dark:text-gray-300\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black dark:hover:text-white transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black dark:hover:text-white transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )\n}\n\n/**\n * Spacer that fills remaining vertical space.\n * Shows a top border (via gradient) only when it has height.\n */\nfunction HomeSpacer() {\n return (\n <div\n className=\"grow dark:hidden\"\n style={{ backgroundImage: 'linear-gradient(rgb(229, 231, 235) 1px, transparent 1px)' }}\n />\n )\n}\n\nfunction HomeSpacerDark() {\n return (\n <div\n className=\"grow hidden dark:block\"\n style={{ backgroundImage: 'linear-gradient(rgb(38, 38, 38) 1px, transparent 1px)' }}\n />\n )\n}\n\nfunction DefaultHomeLayout() {\n return (\n <>\n <HomeHeader />\n <HomeHero />\n <HomeFeatures />\n <HomeCTA />\n <HomeSpacer />\n <HomeSpacerDark />\n <HomeFooter />\n </>\n )\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Homepage component for documentation sites.\n *\n * Can be used in two ways:\n *\n * 1. Simple - everything from config:\n * ```tsx\n * <HomePage {...props} />\n * ```\n *\n * 2. Composable - full control via children:\n * ```tsx\n * <HomePage {...props}>\n * <HomePage.Header />\n * <HomePage.Hero />\n * <MyCustomSection />\n * <HomePage.Features renderFeature={(feature, i, Default) => (\n * <Default feature={feature} index={i} totalFeatures={4} />\n * )} />\n * <HomePage.CTA />\n * <HomePage.Footer />\n * </HomePage>\n * ```\n */\nexport function HomePage({\n children,\n navLinks = [],\n ...props\n}: HomePageProps) {\n const contextValue: HomePageContextValue = {\n ...props,\n navLinks,\n }\n\n return (\n <HomePageContext.Provider value={contextValue}>\n <div className=\"min-h-screen bg-white dark:bg-[#0f0f0f] flex flex-col transition-colors duration-200\">\n <Head title={props.title} />\n {children || <DefaultHomeLayout />}\n </div>\n </HomePageContext.Provider>\n )\n}\n\n// Attach sub-components for compound component pattern\nHomePage.Header = HomeHeader\nHomePage.Hero = HomeHero\nHomePage.Features = HomeFeatures\nHomePage.Feature = HomeFeatureItem\nHomePage.CTA = HomeCTA\nHomePage.Footer = HomeFooter\n","import { createInertiaApp } from '@inertiajs/react'\nimport { createRoot, hydrateRoot } from 'react-dom/client'\nimport type { DocsAppConfig } from './types'\nimport { ComponentsProvider } from './context/ComponentsContext'\nimport { ThemeProvider } from './components/ThemeProvider'\n\n/**\n * Create and mount an Inertia.js documentation app.\n *\n * @example\n * ```tsx\n * import { createDocsApp, DocsPage } from '@usecross/docs'\n *\n * createDocsApp({\n * pages: {\n * 'docs/DocsPage': DocsPage,\n * },\n * title: (title) => `${title} - My Docs`,\n * })\n * ```\n */\nexport function createDocsApp(config: DocsAppConfig): void {\n const { pages, title, components } = config\n\n // Disable scroll restoration on initial page load\n if (typeof window !== 'undefined') {\n window.history.scrollRestoration = 'manual'\n window.scrollTo(0, 0)\n }\n\n createInertiaApp({\n title: title ?? ((pageTitle) => (pageTitle ? `${pageTitle}` : 'Documentation')),\n resolve: (name) => {\n const page = pages[name]\n if (!page) {\n throw new Error(`Page component \"${name}\" not found`)\n }\n return page\n },\n setup({ el, App, props }) {\n const appElement = (\n <ThemeProvider>\n <ComponentsProvider components={components}>\n <App {...props} />\n </ComponentsProvider>\n </ThemeProvider>\n )\n\n if (el.hasChildNodes()) {\n hydrateRoot(el, appElement)\n } else {\n createRoot(el).render(appElement)\n }\n },\n })\n}\n"],"mappings":"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","names":["useState","useEffect","jsx","jsxs","useState","useEffect","Link","useState","jsx","jsxs","useEffect","useState","useRef","jsx","jsxs","useState","useRef","useEffect","useEffect","useState","jsx","defaultTheme","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useState","Link","jsx","createContext","useContext","jsx","jsx","useState","jsx","jsxs","Head","Link","createContext","useContext","useState","Fragment","jsx","jsxs","createContext","useContext","useState","GitHubIcon","Link","Head","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/CodeBlock.tsx","../src/lib/utils.ts","../src/lib/shiki.ts","../src/components/DocSetSelector.tsx","../src/components/DocsLayout.tsx","../src/components/Sidebar.tsx","../src/components/TableOfContents.tsx","../src/components/ThemeToggle.tsx","../src/components/ThemeProvider.tsx","../src/components/Markdown.tsx","../src/context/ComponentsContext.tsx","../src/components/DocsPage.tsx","../src/components/EmojiConfetti.tsx","../src/components/HomePage.tsx","../src/app.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\nimport { cn } from '../lib/utils'\nimport { getHighlighter } from '../lib/shiki'\nimport type { CodeBlockProps } from '../types'\n\n/**\n * Syntax-highlighted code block component using Shiki.\n */\nexport function CodeBlock({\n code,\n language = 'python',\n filename,\n showLineNumbers = false,\n theme = 'github-dark-dimmed',\n className,\n}: CodeBlockProps) {\n const [html, setHtml] = useState<string>('')\n const [copied, setCopied] = useState(false)\n\n useEffect(() => {\n async function highlight() {\n const highlighter = await getHighlighter()\n const langs = highlighter.getLoadedLanguages()\n const lang = langs.includes(language) ? language : 'text'\n const highlighted = highlighter.codeToHtml(code.trim(), {\n lang,\n theme,\n })\n setHtml(highlighted)\n }\n highlight()\n }, [code, language, theme])\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(code.trim())\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <div className={cn('group relative overflow-hidden rounded-lg bg-[#24292f] not-prose mb-6', className)}>\n {filename && (\n <div className=\"flex items-center gap-2 border-b border-slate-700 bg-slate-900 px-4 py-2 text-sm text-slate-400\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n {filename}\n </div>\n )}\n <button\n onClick={copyToClipboard}\n className=\"absolute right-2 top-2 z-10 rounded-md bg-slate-700/50 px-2 py-1 text-xs text-slate-400 opacity-0 transition-opacity hover:bg-slate-600 hover:text-white group-hover:opacity-100\"\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n {html ? (\n <div\n className={cn(\n 'overflow-x-auto text-sm [&_pre]:m-0 [&_pre]:bg-transparent [&_code]:p-4',\n showLineNumbers && '[&_code]:grid [&_code]:grid-cols-[auto_1fr]'\n )}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n ) : (\n <pre className=\"shiki overflow-x-auto m-0 bg-transparent\">\n <code className=\"block p-4 text-sm leading-relaxed text-gray-300\">{code.trim()}</code>\n </pre>\n )}\n </div>\n )\n}\n\n/**\n * Simple inline code component.\n */\nexport function InlineCode({ children }: { children: React.ReactNode }) {\n return (\n <code className=\"rounded bg-slate-100 px-1.5 py-0.5 text-sm font-medium text-slate-800\">\n {children}\n </code>\n )\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\n/**\n * Merge Tailwind CSS classes with clsx\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { createHighlighterCore, type HighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null\n\n// Default languages to load\nconst defaultLangs = [\n import('shiki/langs/python.mjs'),\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/shellscript.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/toml.mjs'),\n import('shiki/langs/markdown.mjs'),\n]\n\n// Default theme\nconst defaultTheme = import('shiki/themes/github-dark-dimmed.mjs')\n\n/**\n * Get or create a Shiki highlighter instance.\n * Uses a singleton pattern to avoid creating multiple highlighters.\n */\nexport function getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = createHighlighterCore({\n themes: [defaultTheme],\n langs: defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n }\n return highlighterPromise\n}\n\n/**\n * Configure the highlighter with custom themes and languages.\n * Must be called before getHighlighter() is first called.\n */\nexport function configureHighlighter(options: {\n theme?: Promise<any>\n langs?: Promise<any>[]\n}): void {\n if (highlighterPromise) {\n console.warn('configureHighlighter called after highlighter was created')\n return\n }\n\n highlighterPromise = createHighlighterCore({\n themes: [options.theme ?? defaultTheme],\n langs: options.langs ?? defaultLangs,\n engine: createJavaScriptRegexEngine(),\n })\n}\n","import { useState, useRef, useEffect } from 'react'\nimport { router } from '@inertiajs/react'\nimport { cn } from '../lib/utils'\nimport type { DocSetMeta } from '../types'\n\ninterface DocSetSelectorProps {\n docSets: DocSetMeta[]\n currentDocSet: string\n className?: string\n}\n\n// Chevron icon with up/down indicators like Fumadocs\nconst ChevronUpDownIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 6l3-3 3 3M5 10l3 3 3-3\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n)\n\n// Checkmark for selected state\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3.5 8.5l3 3 6-6.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n)\n\n// Default package/docs icon when no iconUrl is provided\nconst PackageIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 2L17 6v8l-7 4-7-4V6l7-4z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M10 10v8M10 10l7-4M10 10L3 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n)\n\n/**\n * Dropdown selector for switching between documentation sets.\n * Inspired by Fumadocs design - clean and minimal.\n */\nexport function DocSetSelector({ docSets, currentDocSet, className }: DocSetSelectorProps) {\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n\n const current = docSets.find((ds) => ds.slug === currentDocSet) || docSets[0]\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n // Close on escape key\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setIsOpen(false)\n }\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape)\n return () => document.removeEventListener('keydown', handleEscape)\n }\n }, [isOpen])\n\n const handleSelect = (docSet: DocSetMeta) => {\n setIsOpen(false)\n if (docSet.slug !== currentDocSet) {\n router.visit(`${docSet.prefix}/`)\n }\n }\n\n return (\n <div className={cn('relative', className)} ref={dropdownRef}>\n {/* Trigger Button - Clean, flat design like Fumadocs */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2',\n 'bg-gray-100/80 dark:bg-white/5',\n 'border border-gray-200 dark:border-white/10',\n 'rounded-lg',\n 'hover:bg-gray-200/80 dark:hover:bg-white/10',\n 'transition-colors duration-150',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50'\n )}\n aria-label=\"Select documentation\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n {/* Icon */}\n <div className=\"flex-shrink-0 w-5 h-5 flex items-center justify-center text-gray-600 dark:text-gray-400\">\n {current.icon ? (\n <span className=\"text-base leading-none\">{current.icon}</span>\n ) : current.iconUrl ? (\n <img src={current.iconUrl} alt=\"\" className=\"w-5 h-5\" />\n ) : (\n <PackageIcon className=\"w-5 h-5\" />\n )}\n </div>\n\n {/* Text */}\n <span className=\"flex-1 text-left text-sm font-medium text-gray-900 dark:text-white truncate\">\n {current.name}\n </span>\n\n {/* Chevron */}\n <ChevronUpDownIcon className=\"flex-shrink-0 w-4 h-4 text-gray-400 dark:text-gray-500\" />\n </button>\n\n {/* Dropdown Menu */}\n <div\n className={cn(\n 'absolute left-0 right-0 mt-1.5',\n 'py-1',\n 'bg-white dark:bg-[#1a1a1a]',\n 'border border-gray-200 dark:border-white/10',\n 'rounded-lg',\n 'shadow-lg shadow-black/5 dark:shadow-black/30',\n 'z-50',\n 'transition-all duration-150 ease-out origin-top',\n isOpen\n ? 'opacity-100 scale-100'\n : 'opacity-0 scale-95 pointer-events-none'\n )}\n role=\"listbox\"\n aria-label=\"Select documentation set\"\n >\n {docSets.map((docSet) => {\n const isSelected = docSet.slug === currentDocSet\n\n return (\n <button\n key={docSet.slug || '_root'}\n onClick={() => handleSelect(docSet)}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2',\n 'transition-colors duration-100',\n 'focus:outline-none',\n isSelected\n ? 'bg-primary-50 dark:bg-primary-500/10'\n : 'hover:bg-gray-50 dark:hover:bg-white/5'\n )}\n role=\"option\"\n aria-selected={isSelected}\n >\n {/* Icon */}\n <div className={cn(\n 'flex-shrink-0 w-5 h-5 flex items-center justify-center',\n isSelected\n ? 'text-primary-600 dark:text-primary-400'\n : 'text-gray-500 dark:text-gray-400'\n )}>\n {docSet.icon ? (\n <span className=\"text-base leading-none\">{docSet.icon}</span>\n ) : docSet.iconUrl ? (\n <img src={docSet.iconUrl} alt=\"\" className=\"w-5 h-5\" />\n ) : (\n <PackageIcon className=\"w-5 h-5\" />\n )}\n </div>\n\n {/* Text Content */}\n <div className=\"flex-1 text-left min-w-0\">\n <div\n className={cn(\n 'text-sm font-medium truncate',\n isSelected\n ? 'text-primary-700 dark:text-primary-300'\n : 'text-gray-900 dark:text-white'\n )}\n >\n {docSet.name}\n </div>\n {docSet.description && (\n <div className={cn(\n 'text-xs truncate',\n isSelected\n ? 'text-primary-600/70 dark:text-primary-400/70'\n : 'text-gray-500 dark:text-gray-400'\n )}>\n {docSet.description}\n </div>\n )}\n </div>\n\n {/* Checkmark indicator */}\n {isSelected && (\n <CheckIcon className=\"flex-shrink-0 w-4 h-4 text-primary-600 dark:text-primary-400\" />\n )}\n </button>\n )\n })}\n </div>\n </div>\n )\n}\n","import { Head, Link, usePage } from '@inertiajs/react'\nimport { useState } from 'react'\nimport { Sidebar } from './Sidebar'\nimport { TableOfContents } from './TableOfContents'\nimport { ThemeToggle } from './ThemeToggle'\nimport { useTheme } from './ThemeProvider'\nimport type { DocsLayoutProps, SharedProps } from '../types'\n\nexport function MobileMenuButton({ onClick, isOpen }: { onClick: () => void; isOpen: boolean }) {\n return (\n <button\n onClick={onClick}\n className=\"inline-flex items-center justify-center p-2 -ml-2 text-gray-700 hover:text-primary-500 dark:text-gray-300 dark:hover:text-primary-400 lg:hidden transition-colors\"\n aria-expanded={isOpen}\n >\n <span className=\"sr-only\">{isOpen ? 'Close menu' : 'Open menu'}</span>\n {isOpen ? (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n ) : (\n <svg className=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n )}\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n/**\n * Full-featured documentation layout with sidebar, mobile menu, and header.\n */\nexport function DocsLayout({\n children,\n title,\n description: _description,\n logo,\n logoInverted,\n logoUrl: propLogoUrl,\n logoInvertedUrl: propLogoInvertedUrl,\n githubUrl: propGithubUrl,\n navLinks: propNavLinks,\n header,\n headerHeight = 64,\n footer,\n toc,\n}: DocsLayoutProps) {\n const sharedProps = usePage<{ props: SharedProps }>().props as unknown as SharedProps\n const { nav, currentPath, docSets, currentDocSet } = sharedProps\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false)\n const { resolvedTheme } = useTheme()\n\n // Merge props - component props take precedence over shared props from Python\n const logoUrl = propLogoUrl ?? sharedProps.logoUrl\n const logoInvertedUrl = propLogoInvertedUrl ?? sharedProps.logoInvertedUrl\n const githubUrl = propGithubUrl ?? sharedProps.githubUrl\n const navLinks = propNavLinks ?? sharedProps.navLinks ?? []\n\n // Determine which logo to display in header (prefer inverted/dark version)\n const headerLogo = logoInverted || logo || (logoInvertedUrl ? (\n <img src={logoInvertedUrl} alt=\"Logo\" className=\"h-8\" />\n ) : logoUrl ? (\n <img src={logoUrl} alt=\"Logo\" className=\"h-8\" />\n ) : null)\n\n // Determine which logo to display in footer (theme-aware)\n const footerLogoUrl = sharedProps.footerLogoUrl || logoUrl\n const footerLogoInvertedUrl = sharedProps.footerLogoInvertedUrl || logoInvertedUrl\n const currentFooterLogoUrl = resolvedTheme === 'dark' ? (footerLogoInvertedUrl || footerLogoUrl) : footerLogoUrl\n const footerLogo = logo || (currentFooterLogoUrl ? (\n <img src={currentFooterLogoUrl} alt=\"Logo\" className=\"h-6\" />\n ) : null)\n\n return (\n <div className=\"min-h-screen bg-white dark:bg-[#0f0f0f] flex flex-col transition-colors duration-200\">\n <Head title={title} />\n\n {/* Fixed navigation */}\n {(typeof header === 'function'\n ? header({ mobileMenuOpen, toggleMobileMenu: () => setMobileMenuOpen(!mobileMenuOpen) })\n : header) || (\n <nav className=\"fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n <div className=\"flex items-center gap-2\">\n <MobileMenuButton onClick={() => setMobileMenuOpen(!mobileMenuOpen)} isOpen={mobileMenuOpen} />\n {headerLogo ? (\n <Link href=\"/\" className=\"flex items-center\">\n {headerLogo}\n </Link>\n ) : (\n <Link href=\"/\" className=\"font-bold text-lg text-gray-900 dark:text-white\">\n Docs\n </Link>\n )}\n </div>\n <div className=\"flex items-center gap-6\">\n <div className=\"-mr-2\">\n <ThemeToggle size=\"sm\" />\n </div>\n\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"hidden sm:block text-gray-700 dark:text-gray-300 font-medium hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n )}\n\n {/* Mobile sidebar */}\n {mobileMenuOpen && (\n <div className=\"fixed inset-0 z-40 lg:hidden\">\n <div className=\"fixed inset-0 bg-black/50 dark:bg-black/70\" onClick={() => setMobileMenuOpen(false)} />\n <div\n className=\"fixed inset-y-0 left-0 w-72 overflow-y-auto bg-white dark:bg-[#0f0f0f] px-4 py-6 border-r border-gray-200 dark:border-gray-800 transition-colors\"\n style={{ paddingTop: headerHeight + 16 }}\n >\n <Sidebar nav={nav} currentPath={currentPath} docSets={docSets} currentDocSet={currentDocSet} />\n </div>\n </div>\n )}\n\n {/* Main content area */}\n <div className=\"bg-white dark:bg-[#0f0f0f] w-full flex-1 transition-colors\" style={{ paddingTop: headerHeight }}>\n <div className=\"flex\">\n {/* Desktop sidebar - fixed width */}\n <aside\n className=\"hidden lg:block w-[24rem] shrink-0 border-r border-gray-200 dark:border-gray-800 transition-colors\"\n style={{ minHeight: `calc(100vh - ${headerHeight}px)` }}\n >\n <nav\n className=\"sticky px-4 lg:px-10 py-6 overflow-y-auto\"\n style={{ top: headerHeight, maxHeight: `calc(100vh - ${headerHeight}px)` }}\n >\n <Sidebar nav={nav} currentPath={currentPath} docSets={docSets} currentDocSet={currentDocSet} />\n </nav>\n </aside>\n\n {/* Right section: content + TOC + footer (not under left sidebar) */}\n <div className=\"flex-1 min-w-0 flex flex-col\">\n <div className=\"flex-1 p-4 lg:px-10 lg:py-6\">\n <div className=\"flex gap-5\">\n {/* Main content */}\n <main className=\"min-w-0 w-full max-w-4xl\">\n <article className=\"prose prose-lg max-w-none prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-3xl prose-h1:mb-4 prose-h2:text-2xl prose-h2:mt-10 first:prose-h2:mt-0 prose-h3:text-xl prose-a:text-primary-600 dark:prose-a:text-primary-400 prose-a:no-underline hover:prose-a:underline prose-code:bg-gray-100 dark:prose-code:bg-gray-800 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none dark:prose-headings:text-white dark:prose-strong:text-white dark:text-gray-300\">\n {children}\n </article>\n </main>\n\n {/* Table of Contents - desktop only */}\n {toc && toc.length > 0 && (\n <aside className=\"hidden xl:block w-56 shrink-0 transition-colors\">\n <TableOfContents items={toc} className=\"sticky overflow-y-auto\"\n style={{ top: headerHeight + 24, maxHeight: `calc(100vh - ${headerHeight + 24}px)` }} />\n </aside>\n )}\n </div>\n </div>\n\n {/* Footer - spans from after sidebar to right edge */}\n {footer || (\n <footer className=\"border-t border-gray-200 dark:border-gray-800 py-8 px-4 lg:px-10 transition-colors\">\n <div className=\"flex flex-col md:flex-row justify-between items-center gap-6\">\n {footerLogo && <Link href=\"/\">{footerLogo}</Link>}\n <div className=\"flex gap-8 text-sm text-gray-600 dark:text-gray-400\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black dark:hover:text-white transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black dark:hover:text-white transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n}\n","import { Link } from '@inertiajs/react'\nimport { cn } from '../lib/utils'\nimport { DocSetSelector } from './DocSetSelector'\nimport type { SidebarProps } from '../types'\n\n/**\n * Documentation sidebar with section-based navigation.\n * In multi-docs mode, includes a dropdown selector at the top.\n */\nexport function Sidebar({ nav, currentPath, className, docSets, currentDocSet }: SidebarProps) {\n return (\n <nav className={cn('space-y-6', className)}>\n {/* Doc Set Selector - only shown in multi-docs mode */}\n {docSets && docSets.length > 1 && (\n <DocSetSelector docSets={docSets} currentDocSet={currentDocSet ?? ''} className=\"mb-6\" />\n )}\n\n {/* Navigation Sections */}\n <div className=\"space-y-8\">\n {nav.map((section) => (\n <div key={section.title}>\n <h3 className=\"mb-3 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400\">\n {section.title}\n </h3>\n <ul className=\"space-y-1.5 border-l-2 border-gray-200 dark:border-gray-700\">\n {section.items.map((item) => (\n <li key={item.href}>\n <Link\n href={item.href}\n className={cn(\n 'block border-l-2 py-1 pl-4 text-[17px] leading-snug transition-colors -ml-0.5',\n currentPath === item.href\n ? 'border-primary-500 text-gray-900 dark:text-white font-bold'\n : 'border-transparent text-gray-600 dark:text-gray-300 hover:border-primary-300 dark:hover:border-primary-400 hover:text-gray-900 dark:hover:text-white'\n )}\n >\n {item.title}\n </Link>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </nav>\n )\n}\n","import { useEffect, useState, useRef } from 'react'\nimport type { TableOfContentsProps } from '../types'\n\n/**\n * Table of contents component with scroll spy functionality.\n * Displays \"ON THIS PAGE\" sidebar with heading links.\n */\nexport function TableOfContents({ items, className = '', ...props }: TableOfContentsProps) {\n const [activeId, setActiveId] = useState<string>(() => {\n // Initialize with hash from URL if present\n if (typeof window !== 'undefined' && window.location.hash) {\n return window.location.hash.slice(1)\n }\n return ''\n })\n\n // Track if we're currently scrolling from a click\n const isClickScrolling = useRef(false)\n\n useEffect(() => {\n if (items.length === 0) return\n\n // Listen for hash changes\n const handleHashChange = () => {\n const hash = window.location.hash.slice(1)\n if (hash) {\n setActiveId(hash)\n }\n }\n window.addEventListener('hashchange', handleHashChange)\n\n // Scroll-based detection - find the heading closest to top of viewport\n const handleScroll = () => {\n // Skip if we're in the middle of a click-initiated scroll\n if (isClickScrolling.current) return\n\n const headerOffset = 100\n let currentId = ''\n\n // Check if we're at the bottom of the page\n const scrollTop = window.scrollY\n const scrollHeight = document.documentElement.scrollHeight\n const clientHeight = document.documentElement.clientHeight\n const isAtBottom = scrollTop + clientHeight >= scrollHeight - 50\n\n if (isAtBottom) {\n // At bottom of page - find the last heading that's visible in viewport\n for (let i = items.length - 1; i >= 0; i--) {\n const element = document.getElementById(items[i].id)\n if (element) {\n const rect = element.getBoundingClientRect()\n // If this heading is visible in the viewport\n if (rect.top < clientHeight && rect.bottom > 0) {\n currentId = items[i].id\n break\n }\n }\n }\n } else {\n // Normal scroll detection\n for (const item of items) {\n const element = document.getElementById(item.id)\n if (element) {\n const rect = element.getBoundingClientRect()\n // If the heading is at or above the threshold, it's the current section\n if (rect.top <= headerOffset) {\n currentId = item.id\n } else {\n // Once we find a heading below the threshold, stop\n break\n }\n }\n }\n }\n\n // If no heading is above threshold, use the first one\n if (!currentId && items.length > 0) {\n currentId = items[0].id\n }\n\n if (currentId) {\n setActiveId(currentId)\n }\n }\n\n // Throttle scroll handler\n let ticking = false\n const scrollListener = () => {\n if (!ticking) {\n requestAnimationFrame(() => {\n handleScroll()\n ticking = false\n })\n ticking = true\n }\n }\n\n window.addEventListener('scroll', scrollListener, { passive: true })\n\n // Initial check (only if no hash in URL)\n if (!window.location.hash) {\n handleScroll()\n }\n\n return () => {\n window.removeEventListener('scroll', scrollListener)\n window.removeEventListener('hashchange', handleHashChange)\n }\n }, [items])\n\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {\n e.preventDefault()\n const element = document.getElementById(id)\n if (element) {\n // Mark that we're click-scrolling to prevent scroll handler from overriding\n isClickScrolling.current = true\n setActiveId(id)\n\n const top = element.getBoundingClientRect().top + window.scrollY - 80\n window.scrollTo({ top, behavior: 'smooth' })\n\n // Update URL hash without jumping\n window.history.pushState(null, '', `#${id}`)\n\n // Re-enable scroll detection after scroll settles\n // Use requestAnimationFrame loop to wait for scroll to stabilize\n let lastScrollY = window.scrollY\n let stableCount = 0\n const checkScrollEnd = () => {\n if (window.scrollY === lastScrollY) {\n stableCount++\n if (stableCount >= 5) {\n // Scroll has been stable for ~5 frames, animation is done\n isClickScrolling.current = false\n return\n }\n } else {\n stableCount = 0\n lastScrollY = window.scrollY\n }\n requestAnimationFrame(checkScrollEnd)\n }\n requestAnimationFrame(checkScrollEnd)\n }\n }\n\n if (items.length === 0) {\n return null\n }\n\n return (\n <nav className={className} {...props}>\n <h3 className=\"mb-3 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400\">\n On this page\n </h3>\n <ul className=\"space-y-1.5 border-l-2 border-gray-200 dark:border-gray-700\">\n {items.map((item) => {\n const isActive = activeId === item.id\n const indent = item.level === 3 ? 'pl-6' : 'pl-4'\n\n return (\n <li key={item.id}>\n <a\n href={`#${item.id}`}\n onClick={(e) => handleClick(e, item.id)}\n className={`block border-l-2 py-1 ${indent} -ml-0.5 text-base leading-snug transition-colors ${\n isActive\n ? 'border-primary-500 text-gray-900 dark:text-white font-bold'\n : 'border-transparent text-gray-600 dark:text-gray-300 hover:border-primary-300 dark:hover:border-primary-400 hover:text-gray-900 dark:hover:text-white'\n }`}\n >\n {item.text}\n </a>\n </li>\n )\n })}\n </ul>\n </nav>\n )\n}\n","import { useState, useRef, useEffect } from 'react'\nimport { useTheme, type Theme } from './ThemeProvider'\nimport { cn } from '../lib/utils'\n\ninterface ThemeToggleProps {\n /** Additional CSS classes */\n className?: string\n /** Size variant */\n size?: 'sm' | 'md' | 'lg'\n}\n\n// Refined sun icon with balanced proportions\nconst SunIcon = ({ className }: { className?: string }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M12 5V3M12 21v-2M5 12H3m18 0h-2M7.05 7.05 5.636 5.636m12.728 12.728L16.95 16.95M7.05 16.95l-1.414 1.414M18.364 5.636 16.95 7.05\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n)\n\n// Refined moon icon - elegant crescent\nconst MoonIcon = ({ className }: { className?: string }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.752 15.002A9.718 9.718 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n)\n\n// Refined monitor icon - clean display shape\nconst MonitorIcon = ({ className }: { className?: string }) => (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M8 21h8m-4-4v4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n)\n\nconst themeOptions: { value: Theme; label: string; icon: typeof SunIcon }[] = [\n { value: 'light', label: 'Light', icon: SunIcon },\n { value: 'dark', label: 'Dark', icon: MoonIcon },\n { value: 'system', label: 'System', icon: MonitorIcon },\n]\n\n/**\n * Theme toggle dropdown with Light, Dark, and System options.\n * Refined design with smooth animations and premium feel.\n */\nexport function ThemeToggle({ className, size = 'md' }: ThemeToggleProps) {\n const { theme, resolvedTheme, setTheme } = useTheme()\n const [isOpen, setIsOpen] = useState(false)\n const dropdownRef = useRef<HTMLDivElement>(null)\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n // Close on escape key\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === 'Escape') setIsOpen(false)\n }\n\n if (isOpen) {\n document.addEventListener('keydown', handleEscape)\n return () => document.removeEventListener('keydown', handleEscape)\n }\n }, [isOpen])\n\n const iconSizes = {\n sm: 'w-[18px] h-[18px]',\n md: 'w-5 h-5',\n lg: 'w-[22px] h-[22px]',\n }\n\n return (\n <div className=\"relative\" ref={dropdownRef}>\n {/* Toggle Button */}\n <button\n onClick={() => setIsOpen(!isOpen)}\n className={cn(\n 'relative inline-flex items-center justify-center',\n 'rounded-full p-4',\n 'text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white',\n 'hover:bg-gray-100 dark:hover:bg-white/10',\n 'transition-all duration-200 ease-out',\n 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500/50 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-[#0f0f0f]',\n iconSizes[size],\n className\n )}\n aria-label=\"Toggle theme\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n {/* Sun icon - visible in light mode */}\n <SunIcon\n className={cn(\n iconSizes[size],\n 'absolute inset-0 m-auto transition-all duration-300 ease-out',\n resolvedTheme === 'light'\n ? 'rotate-0 scale-100 opacity-100'\n : 'rotate-90 scale-75 opacity-0'\n )}\n />\n\n {/* Moon icon - visible in dark mode */}\n <MoonIcon\n className={cn(\n iconSizes[size],\n 'absolute inset-0 m-auto transition-all duration-300 ease-out',\n resolvedTheme === 'dark'\n ? 'rotate-0 scale-100 opacity-100'\n : '-rotate-90 scale-75 opacity-0'\n )}\n />\n </button>\n\n {/* Dropdown Menu */}\n <div\n className={cn(\n 'absolute right-0 mt-2 min-w-[140px]',\n 'p-1',\n 'bg-white dark:bg-[#171717]',\n 'border border-gray-200 dark:border-[#262626]',\n 'rounded-xl',\n 'shadow-lg shadow-black/5 dark:shadow-black/40',\n 'z-50',\n 'transition-all duration-200 ease-out origin-top-right',\n isOpen\n ? 'opacity-100 scale-100 translate-y-0'\n : 'opacity-0 scale-95 -translate-y-1 pointer-events-none'\n )}\n role=\"listbox\"\n aria-label=\"Select theme\"\n >\n {themeOptions.map((option, index) => {\n const Icon = option.icon\n const isSelected = theme === option.value\n\n return (\n <button\n key={option.value}\n onClick={() => {\n setTheme(option.value)\n setIsOpen(false)\n }}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2',\n 'rounded-lg',\n 'text-[13px] font-medium',\n 'transition-all duration-150 ease-out',\n 'focus:outline-none',\n isSelected\n ? 'text-gray-900 dark:text-white bg-gray-100 dark:bg-[#262626]'\n : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:bg-gray-50 dark:hover:bg-[#1f1f1f]'\n )}\n role=\"option\"\n aria-selected={isSelected}\n style={{\n animationDelay: isOpen ? `${index * 25}ms` : '0ms'\n }}\n >\n <Icon className={cn(\n 'w-4 h-4 flex-shrink-0',\n 'transition-transform duration-150',\n isSelected ? 'scale-110' : 'scale-100'\n )} />\n <span className=\"flex-1 text-left\">{option.label}</span>\n <div className={cn(\n 'w-1.5 h-1.5 rounded-full',\n 'transition-all duration-200',\n isSelected\n ? 'bg-primary-500 scale-100 opacity-100'\n : 'bg-transparent scale-0 opacity-0'\n )} />\n </button>\n )\n })}\n </div>\n </div>\n )\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'\n\nexport type Theme = 'light' | 'dark' | 'system'\nexport type ResolvedTheme = 'light' | 'dark'\n\ninterface ThemeContextValue {\n theme: Theme\n resolvedTheme: ResolvedTheme\n setTheme: (theme: Theme) => void\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null)\n\nconst STORAGE_KEY = 'cross-docs-theme'\n\nfunction getSystemTheme(): ResolvedTheme {\n if (typeof window === 'undefined') return 'light'\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\nfunction getStoredTheme(): Theme | null {\n if (typeof window === 'undefined') return null\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored === 'light' || stored === 'dark' || stored === 'system') {\n return stored\n }\n return null\n}\n\ninterface ThemeProviderProps {\n children: ReactNode\n /** Default theme if no preference is stored. Defaults to 'system'. */\n defaultTheme?: Theme\n /** Force a specific theme, ignoring user preference */\n forcedTheme?: ResolvedTheme\n}\n\nexport function ThemeProvider({\n children,\n defaultTheme = 'system',\n forcedTheme,\n}: ThemeProviderProps) {\n const [theme, setThemeState] = useState<Theme>(() => {\n // During SSR, use defaultTheme\n if (typeof window === 'undefined') return defaultTheme\n return getStoredTheme() ?? defaultTheme\n })\n\n const [resolvedTheme, setResolvedTheme] = useState<ResolvedTheme>(() => {\n if (forcedTheme) return forcedTheme\n if (typeof window === 'undefined') return 'light'\n if (theme === 'system') return getSystemTheme()\n return theme\n })\n\n // Update resolved theme when theme changes or system preference changes\n useEffect(() => {\n if (forcedTheme) {\n setResolvedTheme(forcedTheme)\n return\n }\n\n const updateResolvedTheme = () => {\n if (theme === 'system') {\n setResolvedTheme(getSystemTheme())\n } else {\n setResolvedTheme(theme)\n }\n }\n\n updateResolvedTheme()\n\n // Listen for system preference changes\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n const handleChange = () => {\n if (theme === 'system') {\n setResolvedTheme(getSystemTheme())\n }\n }\n\n mediaQuery.addEventListener('change', handleChange)\n return () => mediaQuery.removeEventListener('change', handleChange)\n }, [theme, forcedTheme])\n\n // Apply theme class to document\n useEffect(() => {\n const root = document.documentElement\n root.classList.remove('light', 'dark')\n root.classList.add(resolvedTheme)\n }, [resolvedTheme])\n\n const setTheme = (newTheme: Theme) => {\n setThemeState(newTheme)\n localStorage.setItem(STORAGE_KEY, newTheme)\n }\n\n return (\n <ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>\n {children}\n </ThemeContext.Provider>\n )\n}\n\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext)\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider')\n }\n return context\n}\n\n/**\n * Script to prevent flash of unstyled content (FOUC) during page load.\n * Include this in your HTML <head> before any stylesheets.\n */\nexport const themeInitScript = `\n(function() {\n try {\n var stored = localStorage.getItem('${STORAGE_KEY}');\n var theme = stored === 'light' || stored === 'dark' ? stored :\n (stored === 'system' || !stored) && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n document.documentElement.classList.add(theme);\n } catch (e) {}\n})();\n`.trim()\n","import ReactMarkdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport remarkEmoji from 'remark-emoji'\nimport { remarkAlert } from 'remark-github-blockquote-alert'\nimport rehypeRaw from 'rehype-raw'\nimport { CodeBlock } from './CodeBlock'\nimport type { MarkdownProps } from '../types'\n\n/**\n * Convert heading text to URL-safe slug.\n * Must match the Python slugify function in markdown.py.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\n/**\n * Extract text content from React children.\n */\nfunction getTextContent(children: React.ReactNode): string {\n if (typeof children === 'string') return children\n if (typeof children === 'number') return String(children)\n if (Array.isArray(children)) return children.map(getTextContent).join('')\n if (children && typeof children === 'object' && 'props' in children) {\n return getTextContent((children as React.ReactElement).props.children)\n }\n return ''\n}\n\n/**\n * Markdown renderer with syntax highlighting and GFM support.\n */\nexport function Markdown({ content, components }: MarkdownProps) {\n // Create lowercase mappings for custom components\n // HTML tag names are case-insensitive, so <TerminalExample> becomes <terminalexample>\n const lowercaseComponents = components\n ? Object.entries(components).reduce(\n (acc, [name, Component]) => {\n acc[name.toLowerCase()] = Component\n return acc\n },\n {} as Record<string, React.ComponentType<any>>\n )\n : {}\n\n return (\n <ReactMarkdown\n remarkPlugins={[remarkGfm, remarkEmoji, remarkAlert]}\n rehypePlugins={[rehypeRaw]}\n components={{\n ...lowercaseComponents,\n // Override pre to avoid double wrapping with CodeBlock\n pre({ children }) {\n return <>{children}</>\n },\n // Custom code block rendering with syntax highlighting\n code({ node, className, children, ...props }) {\n const match = /language-(\\w+)/.exec(className || '')\n const isInline = !match && !className\n\n if (isInline) {\n return (\n <code\n className=\"rounded bg-gray-100 px-1.5 py-0.5 text-sm font-medium text-gray-800 dark:bg-gray-800 dark:text-gray-200\"\n {...props}\n >\n {children}\n </code>\n )\n }\n\n // Parse meta string from the code fence (e.g., ```python title=\"app.py\" showLineNumbers)\n const meta = (node?.data?.meta as string) || ''\n const titleMatch = /title=\"([^\"]+)\"/.exec(meta)\n const filename = titleMatch ? titleMatch[1] : undefined\n const showLineNumbers = meta.includes('showLineNumbers')\n\n return (\n <CodeBlock\n code={String(children).replace(/\\n$/, '')}\n language={match ? match[1] : 'text'}\n filename={filename}\n showLineNumbers={showLineNumbers}\n />\n )\n },\n // Custom link styling\n a({ href, children, node, ...props }) {\n const isExternal = href?.startsWith('http')\n return (\n <a\n href={href}\n className=\"text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-300\"\n {...(isExternal ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n {...props}\n >\n {children}\n </a>\n )\n },\n // Tables\n table({ children }) {\n return (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-left text-sm\">{children}</table>\n </div>\n )\n },\n th({ children }) {\n return (\n <th className=\"border-b border-gray-200 bg-gray-50 px-4 py-2 font-semibold dark:border-gray-700 dark:bg-gray-800\">\n {children}\n </th>\n )\n },\n td({ children }) {\n return (\n <td className=\"border-b border-gray-200 px-4 py-2 dark:border-gray-700\">\n {children}\n </td>\n )\n },\n // Headings with anchor IDs for TOC\n h2({ children }) {\n const text = getTextContent(children)\n const id = slugify(text)\n return (\n <h2 id={id}>\n {children}\n </h2>\n )\n },\n h3({ children }) {\n const text = getTextContent(children)\n const id = slugify(text)\n return (\n <h3 id={id}>\n {children}\n </h3>\n )\n },\n // Task list checkbox styling\n input({ type, checked, disabled, ...props }) {\n if (type === 'checkbox') {\n return (\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n className=\"mr-2 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-700\"\n {...props}\n />\n )\n }\n return <input type={type} checked={checked} disabled={disabled} {...props} />\n },\n // Footnote section styling\n section({ className, children, ...props }) {\n if (className?.includes('footnotes')) {\n return (\n <section\n className=\"mt-8 border-t border-gray-200 pt-6 text-sm text-gray-600 dark:border-gray-700 dark:text-gray-400\"\n {...props}\n >\n {children}\n </section>\n )\n }\n return <section className={className} {...props}>{children}</section>\n },\n }}\n >\n {content}\n </ReactMarkdown>\n )\n}\n","import React, { createContext, useContext } from 'react'\n\ninterface ComponentsContextValue {\n components?: Record<string, React.ComponentType<any>>\n}\n\nconst ComponentsContext = createContext<ComponentsContextValue>({})\n\nexport function ComponentsProvider({\n children,\n components,\n}: {\n children: React.ReactNode\n components?: Record<string, React.ComponentType<any>>\n}) {\n return (\n <ComponentsContext.Provider value={{ components }}>\n {children}\n </ComponentsContext.Provider>\n )\n}\n\nexport function useComponents() {\n return useContext(ComponentsContext)\n}\n","import { DocsLayout } from './DocsLayout'\nimport { Markdown } from './Markdown'\nimport type { DocContent, DocsLayoutProps } from '../types'\nimport { useComponents } from '../context/ComponentsContext'\n\ninterface DocsPageProps extends Omit<DocsLayoutProps, 'children' | 'title'> {\n content: DocContent\n}\n\n/**\n * Default documentation page component.\n * Renders markdown content within the DocsLayout.\n */\nexport function DocsPage({ content, ...layoutProps }: DocsPageProps) {\n const { components } = useComponents()\n\n return (\n <DocsLayout\n title={content?.title ?? ''}\n description={content?.description}\n toc={content?.toc}\n {...layoutProps}\n >\n <Markdown content={content?.body ?? ''} components={components} />\n </DocsLayout>\n )\n}\n","import { useState, useCallback } from 'react'\n\ninterface ConfettiParticle {\n id: number\n x: number\n y: number\n angle: number\n velocity: number\n spin: number\n scale: number\n}\n\nexport function EmojiConfetti({ children, emoji }: { children: React.ReactNode; emoji: string }) {\n const [particles, setParticles] = useState<ConfettiParticle[]>([])\n const [isActive, setIsActive] = useState(false)\n\n const triggerBurst = useCallback(() => {\n if (isActive) return\n setIsActive(true)\n\n const newParticles: ConfettiParticle[] = []\n const count = 15\n\n for (let i = 0; i < count; i++) {\n // Burst in all directions from center\n const angle = (i / count) * Math.PI * 2 + (Math.random() - 0.5) * 0.5\n newParticles.push({\n id: Date.now() + i,\n x: 50, // Start from center\n y: 50,\n angle,\n velocity: 80 + Math.random() * 60, // Distance to travel\n spin: (Math.random() - 0.5) * 720, // Random rotation\n scale: 0.7 + Math.random() * 0.6,\n })\n }\n setParticles(newParticles)\n\n setTimeout(() => {\n setParticles([])\n setIsActive(false)\n }, 1000)\n }, [isActive])\n\n return (\n <span\n className=\"relative inline-block\"\n onMouseEnter={triggerBurst}\n >\n {children}\n <span className=\"absolute inset-0 pointer-events-none overflow-visible\">\n {particles.map((p) => {\n const endX = p.x + Math.cos(p.angle) * p.velocity\n const endY = p.y + Math.sin(p.angle) * p.velocity\n\n return (\n <span\n key={p.id}\n className=\"absolute\"\n style={{\n left: '50%',\n top: '50%',\n fontSize: `${p.scale}rem`,\n transform: 'translate(-50%, -50%)',\n animation: `emojiConfettiBurst 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards`,\n '--end-x': `${(endX - 50)}px`,\n '--end-y': `${(endY - 50)}px`,\n '--spin': `${p.spin}deg`,\n } as React.CSSProperties}\n >\n {emoji}\n </span>\n )\n })}\n </span>\n </span>\n )\n}\n","import { Head, Link } from '@inertiajs/react'\nimport { createContext, useContext, useState, type ReactNode } from 'react'\nimport { ThemeToggle } from './ThemeToggle'\nimport { useTheme } from './ThemeProvider'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface HomeFeature {\n title: string\n description: ReactNode\n}\n\nexport interface HomePageContextValue {\n title: string\n tagline: string\n description: string\n installCommand: string\n ctaText: string\n ctaHref: string\n features: HomeFeature[]\n logoUrl?: string\n heroLogoUrl?: string\n footerLogoUrl?: string\n footerLogoInvertedUrl?: string\n githubUrl?: string\n navLinks: Array<{ label: string; href: string }>\n}\n\nexport interface HomePageProps extends Omit<HomePageContextValue, 'navLinks'> {\n navLinks?: Array<{ label: string; href: string }>\n children?: ReactNode\n}\n\nexport interface HomeHeaderProps {\n renderLogo?: () => ReactNode\n}\n\nexport interface HomeFeaturesProps {\n renderFeature?: (\n feature: HomeFeature,\n index: number,\n DefaultFeature: typeof HomeFeatureItem\n ) => ReactNode\n}\n\nexport interface HomeFeatureItemProps {\n feature: HomeFeature\n index: number\n totalFeatures: number\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst HomePageContext = createContext<HomePageContextValue | null>(null)\n\nfunction useHomePage(): HomePageContextValue {\n const context = useContext(HomePageContext)\n if (!context) {\n throw new Error('HomePage sub-components must be used within <HomePage>')\n }\n return context\n}\n\n// ============================================================================\n// Utility Components\n// ============================================================================\n\nfunction InstallCommand({ command }: { command: string }) {\n const [copied, setCopied] = useState(false)\n\n const copyToClipboard = async () => {\n await navigator.clipboard.writeText(command)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }\n\n return (\n <button\n onClick={copyToClipboard}\n className=\"group relative flex items-center bg-gray-900 dark:bg-white border border-gray-900 dark:border-white px-4 h-14 font-mono text-sm text-white dark:text-gray-900 hover:bg-white dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-white transition-colors cursor-pointer\"\n >\n <span className=\"text-primary-500 dark:text-primary-600 mr-2\">$</span>\n <span>{command}</span>\n <svg\n className={`ml-4 w-4 h-4 transition ${copied ? 'text-green-400' : 'opacity-50 group-hover:opacity-100'}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span\n className={`absolute -top-8 left-1/2 -translate-x-1/2 bg-gray-900 dark:bg-white text-white dark:text-gray-900 text-xs py-1 px-2 rounded transition-opacity duration-300 whitespace-nowrap ${\n copied ? 'opacity-100' : 'opacity-0'\n }`}\n >\n Copied!\n </span>\n </button>\n )\n}\n\nfunction GitHubIcon() {\n return (\n <svg className=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path\n fillRule=\"evenodd\"\n d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )\n}\n\n// ============================================================================\n// Sub-Components\n// ============================================================================\n\n/**\n * Default logo component that renders an image or text.\n */\nfunction DefaultLogo() {\n const { title, logoUrl } = useHomePage()\n\n if (logoUrl) {\n return (\n <Link href=\"/\" className=\"flex items-center\">\n <img src={logoUrl} alt={title} className=\"h-8\" />\n </Link>\n )\n }\n\n return (\n <Link href=\"/\" className=\"font-bold text-lg text-gray-900 dark:text-white\">\n {title}\n </Link>\n )\n}\n\n/**\n * Navigation header for the homepage.\n * Accepts an optional renderLogo prop for custom logo rendering.\n */\nexport function HomeHeader({ renderLogo }: HomeHeaderProps = {}) {\n const { navLinks, githubUrl } = useHomePage()\n\n return (\n <nav className=\"fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"px-4 lg:px-10\">\n <div className=\"flex justify-between h-16 items-center\">\n {renderLogo ? renderLogo() : <DefaultLogo />}\n <div className=\"flex items-center gap-6\">\n <div className=\"-mr-2\">\n <ThemeToggle size=\"sm\" />\n </div>\n\n {navLinks.map((link) => (\n <Link\n key={link.href}\n href={link.href}\n className=\"hidden sm:block text-gray-700 dark:text-gray-300 font-medium hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-gray-700 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400 transition-colors\"\n >\n <GitHubIcon />\n </a>\n )}\n </div>\n </div>\n </div>\n </nav>\n )\n}\n\n/**\n * Hero section with title, tagline, description, and CTA.\n * If heroLogoUrl is provided, displays an image instead of text title.\n */\nexport function HomeHero() {\n const { title, tagline, description, ctaText, ctaHref, installCommand, heroLogoUrl } = useHomePage()\n\n return (\n <section className=\"pt-16\">\n <div className=\"px-4 lg:px-10 py-16 lg:py-24\">\n <div className=\"max-w-4xl\">\n <div className=\"mb-4 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400\">\n {tagline}\n </div>\n {heroLogoUrl ? (\n <h1 className=\"mb-6 lg:mb-8\">\n <img\n src={heroLogoUrl}\n alt={title}\n className=\"h-auto w-auto max-w-[580px]\"\n />\n </h1>\n ) : (\n <h1 className=\"text-5xl lg:text-7xl font-bold tracking-tight mb-6 text-gray-900 dark:text-white\">\n {title}\n </h1>\n )}\n <p className=\"text-xl lg:text-2xl text-gray-600 dark:text-gray-300 max-w-2xl leading-relaxed mb-8\">\n {description}\n </p>\n\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 h-14 bg-gray-900 dark:bg-white text-white dark:text-gray-900 font-bold text-lg hover:bg-primary-500 dark:hover:bg-primary-500 dark:hover:text-white transition-colors border border-gray-900 dark:border-white hover:border-primary-500 dark:hover:border-primary-500\"\n >\n {ctaText}\n </Link>\n {installCommand && <InstallCommand command={installCommand} />}\n </div>\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Single feature item within the features grid.\n */\nexport function HomeFeatureItem({ feature, index, totalFeatures }: HomeFeatureItemProps) {\n return (\n <div\n className={`p-4 lg:p-10 border-b sm:border-b border-gray-200 dark:border-gray-800 ${\n index % 2 === 0 ? 'sm:border-r' : ''\n } ${index >= totalFeatures - 2 ? 'sm:border-b-0' : ''} ${\n index === totalFeatures - 1 && totalFeatures % 2 === 1 ? 'border-b-0' : ''\n } transition-colors`}\n >\n <div className=\"text-5xl font-bold text-primary-500 dark:text-primary-400 mb-4\">\n {String(index + 1).padStart(2, '0')}\n </div>\n <h3 className=\"text-xl font-bold mb-2 text-gray-900 dark:text-white\">{feature.title}</h3>\n <p className=\"text-gray-600 dark:text-gray-300\">{feature.description}</p>\n </div>\n )\n}\n\n/**\n * Features section with customizable feature rendering.\n */\nexport function HomeFeatures({ renderFeature }: HomeFeaturesProps = {}) {\n const { title, features } = useHomePage()\n\n if (features.length === 0) {\n return null\n }\n\n return (\n <section className=\"border-t border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"grid grid-cols-12\">\n <div className=\"col-span-12 lg:col-span-4 p-4 lg:p-10 border-b lg:border-b-0 lg:border-r border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400 mb-4\">\n Features\n </div>\n <h2 className=\"text-4xl lg:text-5xl font-bold tracking-tight text-gray-900 dark:text-white\">\n Why {title}?\n </h2>\n </div>\n\n <div className=\"col-span-12 lg:col-span-8 grid grid-cols-1 sm:grid-cols-2\">\n {features.map((feature, index) =>\n renderFeature ? (\n <div key={index}>\n {renderFeature(feature, index, HomeFeatureItem)}\n </div>\n ) : (\n <HomeFeatureItem\n key={index}\n feature={feature}\n index={index}\n totalFeatures={features.length}\n />\n )\n )}\n </div>\n </div>\n </section>\n )\n}\n\n/**\n * Call-to-action section.\n */\nexport function HomeCTA() {\n const { ctaHref } = useHomePage()\n\n return (\n <section className=\"border-t border-gray-200 dark:border-gray-800 transition-colors\">\n <div className=\"grid grid-cols-12 items-center\">\n <div className=\"col-span-12 lg:col-span-8 p-4 lg:p-10\">\n <h2 className=\"text-4xl lg:text-6xl font-bold tracking-tight mb-4 text-gray-900 dark:text-white\">\n Ready to start?\n </h2>\n <p className=\"text-xl text-gray-600 dark:text-gray-300 mb-8 max-w-2xl\">\n Get up and running in minutes. Check out our documentation to learn more.\n </p>\n <Link\n href={ctaHref}\n className=\"inline-flex items-center justify-center px-8 py-4 bg-primary-500 text-white font-bold text-lg hover:bg-gray-900 dark:hover:bg-white dark:hover:text-gray-900 transition-colors border border-primary-500 hover:border-gray-900 dark:hover:border-white\"\n >\n Read the Docs\n </Link>\n </div>\n <Link\n href={ctaHref}\n className=\"col-span-12 lg:col-span-4 h-full bg-primary-500 hidden lg:flex items-center justify-center p-4 lg:p-10 hover:bg-gray-900 dark:hover:bg-white transition-colors min-h-[200px] group\"\n >\n <div className=\"text-white group-hover:text-white dark:group-hover:text-gray-900 text-8xl font-bold transition-colors\">→</div>\n </Link>\n </div>\n </section>\n )\n}\n\n/**\n * Footer section.\n */\nexport function HomeFooter() {\n const { title, logoUrl, footerLogoUrl, footerLogoInvertedUrl, navLinks, githubUrl } = useHomePage()\n const { resolvedTheme } = useTheme()\n\n // Select appropriate logo based on theme\n const currentLogoUrl = resolvedTheme === 'dark'\n ? (footerLogoInvertedUrl || footerLogoUrl || logoUrl)\n : (footerLogoUrl || logoUrl)\n\n return (\n <footer className=\"border-t border-gray-200 dark:border-gray-800 py-8 bg-white dark:bg-[#0f0f0f] transition-colors\">\n <div className=\"px-4 lg:px-10 flex flex-col md:flex-row justify-between items-center gap-6\">\n {currentLogoUrl && (\n <Link href=\"/\">\n <img src={currentLogoUrl} alt={title} className=\"h-6\" />\n </Link>\n )}\n <div className=\"flex gap-8 text-sm text-gray-600 dark:text-gray-300\">\n {navLinks.map((link) => (\n <Link key={link.href} href={link.href} className=\"hover:text-black dark:hover:text-white transition-colors\">\n {link.label}\n </Link>\n ))}\n {githubUrl && (\n <a\n href={githubUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-black dark:hover:text-white transition-colors\"\n >\n GitHub\n </a>\n )}\n </div>\n </div>\n </footer>\n )\n}\n\n/**\n * Spacer that fills remaining vertical space.\n * Shows a top border (via gradient) only when it has height.\n */\nfunction HomeSpacer() {\n return (\n <div\n className=\"grow dark:hidden\"\n style={{ backgroundImage: 'linear-gradient(rgb(229, 231, 235) 1px, transparent 1px)' }}\n />\n )\n}\n\nfunction HomeSpacerDark() {\n return (\n <div\n className=\"grow hidden dark:block\"\n style={{ backgroundImage: 'linear-gradient(rgb(38, 38, 38) 1px, transparent 1px)' }}\n />\n )\n}\n\nfunction DefaultHomeLayout() {\n return (\n <>\n <HomeHeader />\n <HomeHero />\n <HomeFeatures />\n <HomeCTA />\n <HomeSpacer />\n <HomeSpacerDark />\n <HomeFooter />\n </>\n )\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * Homepage component for documentation sites.\n *\n * Can be used in two ways:\n *\n * 1. Simple - everything from config:\n * ```tsx\n * <HomePage {...props} />\n * ```\n *\n * 2. Composable - full control via children:\n * ```tsx\n * <HomePage {...props}>\n * <HomePage.Header />\n * <HomePage.Hero />\n * <MyCustomSection />\n * <HomePage.Features renderFeature={(feature, i, Default) => (\n * <Default feature={feature} index={i} totalFeatures={4} />\n * )} />\n * <HomePage.CTA />\n * <HomePage.Footer />\n * </HomePage>\n * ```\n */\nexport function HomePage({\n children,\n navLinks = [],\n ...props\n}: HomePageProps) {\n const contextValue: HomePageContextValue = {\n ...props,\n navLinks,\n }\n\n return (\n <HomePageContext.Provider value={contextValue}>\n <div className=\"min-h-screen bg-white dark:bg-[#0f0f0f] flex flex-col transition-colors duration-200\">\n <Head title={props.title} />\n {children || <DefaultHomeLayout />}\n </div>\n </HomePageContext.Provider>\n )\n}\n\n// Attach sub-components for compound component pattern\nHomePage.Header = HomeHeader\nHomePage.Hero = HomeHero\nHomePage.Features = HomeFeatures\nHomePage.Feature = HomeFeatureItem\nHomePage.CTA = HomeCTA\nHomePage.Footer = HomeFooter\n","import { createInertiaApp } from '@inertiajs/react'\nimport { createRoot, hydrateRoot } from 'react-dom/client'\nimport type { DocsAppConfig } from './types'\nimport { ComponentsProvider } from './context/ComponentsContext'\nimport { ThemeProvider } from './components/ThemeProvider'\n\n/**\n * Create and mount an Inertia.js documentation app.\n *\n * @example\n * ```tsx\n * import { createDocsApp, DocsPage } from '@usecross/docs'\n *\n * createDocsApp({\n * pages: {\n * 'docs/DocsPage': DocsPage,\n * },\n * title: (title) => `${title} - My Docs`,\n * })\n * ```\n */\nexport function createDocsApp(config: DocsAppConfig): void {\n const { pages, title, components } = config\n\n // Disable scroll restoration on initial page load\n if (typeof window !== 'undefined') {\n window.history.scrollRestoration = 'manual'\n window.scrollTo(0, 0)\n }\n\n createInertiaApp({\n title: title ?? ((pageTitle) => (pageTitle ? `${pageTitle}` : 'Documentation')),\n resolve: (name) => {\n const page = pages[name]\n if (!page) {\n throw new Error(`Page component \"${name}\" not found`)\n }\n return page\n },\n setup({ el, App, props }) {\n const appElement = (\n <ThemeProvider>\n <ComponentsProvider components={components}>\n <App {...props} />\n </ComponentsProvider>\n </ThemeProvider>\n )\n\n if (el.hasChildNodes()) {\n hydrateRoot(el, appElement)\n } else {\n createRoot(el).render(appElement)\n }\n },\n })\n}\n"],"mappings":"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","names":["useState","useEffect","jsx","jsxs","useState","useEffect","Link","useState","jsx","jsxs","useEffect","useState","useRef","jsx","jsxs","useState","useRef","useEffect","useEffect","useState","jsx","defaultTheme","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useState","Link","jsx","createContext","useContext","jsx","jsx","useState","jsx","jsxs","Head","Link","createContext","useContext","useState","Fragment","jsx","jsxs","createContext","useContext","useState","GitHubIcon","Link","Head","jsx"]}
|
package/dist/ssr.d.ts
CHANGED
|
@@ -82,6 +82,13 @@ interface DocsLayoutProps {
|
|
|
82
82
|
label: string;
|
|
83
83
|
href: string;
|
|
84
84
|
}>;
|
|
85
|
+
/** Custom header component (replaces entire header). Can be a ReactNode or a function that receives mobile menu props. */
|
|
86
|
+
header?: ReactNode | ((props: {
|
|
87
|
+
mobileMenuOpen: boolean;
|
|
88
|
+
toggleMobileMenu: () => void;
|
|
89
|
+
}) => ReactNode);
|
|
90
|
+
/** Header height in pixels. Used to calculate content offset. Defaults to 64 (h-16). */
|
|
91
|
+
headerHeight?: number;
|
|
85
92
|
/** Custom footer component */
|
|
86
93
|
footer?: ReactNode;
|
|
87
94
|
/** Table of contents items for the current page */
|
|
@@ -91,6 +98,7 @@ interface DocsLayoutProps {
|
|
|
91
98
|
interface TableOfContentsProps {
|
|
92
99
|
items: TOCItem[];
|
|
93
100
|
className?: string;
|
|
101
|
+
style: any;
|
|
94
102
|
}
|
|
95
103
|
/** Props for Sidebar component */
|
|
96
104
|
interface SidebarProps {
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import { ThemeToggle } from './ThemeToggle'
|
|
|
6
6
|
import { useTheme } from './ThemeProvider'
|
|
7
7
|
import type { DocsLayoutProps, SharedProps } from '../types'
|
|
8
8
|
|
|
9
|
-
function MobileMenuButton({ onClick, isOpen }: { onClick: () => void; isOpen: boolean }) {
|
|
9
|
+
export function MobileMenuButton({ onClick, isOpen }: { onClick: () => void; isOpen: boolean }) {
|
|
10
10
|
return (
|
|
11
11
|
<button
|
|
12
12
|
onClick={onClick}
|
|
@@ -52,6 +52,8 @@ export function DocsLayout({
|
|
|
52
52
|
logoInvertedUrl: propLogoInvertedUrl,
|
|
53
53
|
githubUrl: propGithubUrl,
|
|
54
54
|
navLinks: propNavLinks,
|
|
55
|
+
header,
|
|
56
|
+
headerHeight = 64,
|
|
55
57
|
footer,
|
|
56
58
|
toc,
|
|
57
59
|
}: DocsLayoutProps) {
|
|
@@ -86,88 +88,102 @@ export function DocsLayout({
|
|
|
86
88
|
<Head title={title} />
|
|
87
89
|
|
|
88
90
|
{/* Fixed navigation */}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<ThemeToggle size="sm" />
|
|
91
|
+
{(typeof header === 'function'
|
|
92
|
+
? header({ mobileMenuOpen, toggleMobileMenu: () => setMobileMenuOpen(!mobileMenuOpen) })
|
|
93
|
+
: header) || (
|
|
94
|
+
<nav className="fixed w-full z-50 bg-white/95 dark:bg-[#0f0f0f]/95 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800 transition-colors">
|
|
95
|
+
<div className="px-4 lg:px-10">
|
|
96
|
+
<div className="flex justify-between h-16 items-center">
|
|
97
|
+
<div className="flex items-center gap-2">
|
|
98
|
+
<MobileMenuButton onClick={() => setMobileMenuOpen(!mobileMenuOpen)} isOpen={mobileMenuOpen} />
|
|
99
|
+
{headerLogo ? (
|
|
100
|
+
<Link href="/" className="flex items-center">
|
|
101
|
+
{headerLogo}
|
|
102
|
+
</Link>
|
|
103
|
+
) : (
|
|
104
|
+
<Link href="/" className="font-bold text-lg text-gray-900 dark:text-white">
|
|
105
|
+
Docs
|
|
106
|
+
</Link>
|
|
107
|
+
)}
|
|
107
108
|
</div>
|
|
109
|
+
<div className="flex items-center gap-6">
|
|
110
|
+
<div className="-mr-2">
|
|
111
|
+
<ThemeToggle size="sm" />
|
|
112
|
+
</div>
|
|
108
113
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
114
|
+
{navLinks.map((link) => (
|
|
115
|
+
<Link
|
|
116
|
+
key={link.href}
|
|
117
|
+
href={link.href}
|
|
118
|
+
className="hidden sm:block text-gray-700 dark:text-gray-300 font-medium hover:text-primary-600 dark:hover:text-primary-400 transition-colors"
|
|
119
|
+
>
|
|
120
|
+
{link.label}
|
|
121
|
+
</Link>
|
|
122
|
+
))}
|
|
123
|
+
{githubUrl && (
|
|
124
|
+
<a
|
|
125
|
+
href={githubUrl}
|
|
126
|
+
target="_blank"
|
|
127
|
+
rel="noopener noreferrer"
|
|
128
|
+
className="text-gray-700 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400 transition-colors"
|
|
129
|
+
>
|
|
130
|
+
<GitHubIcon />
|
|
131
|
+
</a>
|
|
132
|
+
)}
|
|
133
|
+
</div>
|
|
128
134
|
</div>
|
|
129
135
|
</div>
|
|
130
|
-
</
|
|
131
|
-
|
|
136
|
+
</nav>
|
|
137
|
+
)}
|
|
132
138
|
|
|
133
139
|
{/* Mobile sidebar */}
|
|
134
140
|
{mobileMenuOpen && (
|
|
135
141
|
<div className="fixed inset-0 z-40 lg:hidden">
|
|
136
142
|
<div className="fixed inset-0 bg-black/50 dark:bg-black/70" onClick={() => setMobileMenuOpen(false)} />
|
|
137
|
-
<div
|
|
143
|
+
<div
|
|
144
|
+
className="fixed inset-y-0 left-0 w-72 overflow-y-auto bg-white dark:bg-[#0f0f0f] px-4 py-6 border-r border-gray-200 dark:border-gray-800 transition-colors"
|
|
145
|
+
style={{ paddingTop: headerHeight + 16 }}
|
|
146
|
+
>
|
|
138
147
|
<Sidebar nav={nav} currentPath={currentPath} docSets={docSets} currentDocSet={currentDocSet} />
|
|
139
148
|
</div>
|
|
140
149
|
</div>
|
|
141
150
|
)}
|
|
142
151
|
|
|
143
152
|
{/* Main content area */}
|
|
144
|
-
<div className="bg-white dark:bg-[#0f0f0f]
|
|
153
|
+
<div className="bg-white dark:bg-[#0f0f0f] w-full flex-1 transition-colors" style={{ paddingTop: headerHeight }}>
|
|
145
154
|
<div className="flex">
|
|
146
155
|
{/* Desktop sidebar - fixed width */}
|
|
147
|
-
<aside
|
|
148
|
-
|
|
156
|
+
<aside
|
|
157
|
+
className="hidden lg:block w-[24rem] shrink-0 border-r border-gray-200 dark:border-gray-800 transition-colors"
|
|
158
|
+
style={{ minHeight: `calc(100vh - ${headerHeight}px)` }}
|
|
159
|
+
>
|
|
160
|
+
<nav
|
|
161
|
+
className="sticky px-4 lg:px-10 py-6 overflow-y-auto"
|
|
162
|
+
style={{ top: headerHeight, maxHeight: `calc(100vh - ${headerHeight}px)` }}
|
|
163
|
+
>
|
|
149
164
|
<Sidebar nav={nav} currentPath={currentPath} docSets={docSets} currentDocSet={currentDocSet} />
|
|
150
165
|
</nav>
|
|
151
166
|
</aside>
|
|
152
167
|
|
|
153
168
|
{/* Right section: content + TOC + footer (not under left sidebar) */}
|
|
154
169
|
<div className="flex-1 min-w-0 flex flex-col">
|
|
155
|
-
<div className="flex
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
170
|
+
<div className="flex-1 p-4 lg:px-10 lg:py-6">
|
|
171
|
+
<div className="flex gap-5">
|
|
172
|
+
{/* Main content */}
|
|
173
|
+
<main className="min-w-0 w-full max-w-4xl">
|
|
174
|
+
<article className="prose prose-lg max-w-none prose-headings:font-bold prose-headings:tracking-tight prose-h1:text-3xl prose-h1:mb-4 prose-h2:text-2xl prose-h2:mt-10 first:prose-h2:mt-0 prose-h3:text-xl prose-a:text-primary-600 dark:prose-a:text-primary-400 prose-a:no-underline hover:prose-a:underline prose-code:bg-gray-100 dark:prose-code:bg-gray-800 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded prose-code:before:content-none prose-code:after:content-none dark:prose-headings:text-white dark:prose-strong:text-white dark:text-gray-300">
|
|
175
|
+
{children}
|
|
176
|
+
</article>
|
|
177
|
+
</main>
|
|
162
178
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
</
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
{/* Table of Contents - desktop only */}
|
|
180
|
+
{toc && toc.length > 0 && (
|
|
181
|
+
<aside className="hidden xl:block w-56 shrink-0 transition-colors">
|
|
182
|
+
<TableOfContents items={toc} className="sticky overflow-y-auto"
|
|
183
|
+
style={{ top: headerHeight + 24, maxHeight: `calc(100vh - ${headerHeight + 24}px)` }} />
|
|
184
|
+
</aside>
|
|
185
|
+
)}
|
|
186
|
+
</div>
|
|
171
187
|
</div>
|
|
172
188
|
|
|
173
189
|
{/* Footer - spans from after sidebar to right edge */}
|
|
@@ -19,19 +19,19 @@ export function Sidebar({ nav, currentPath, className, docSets, currentDocSet }:
|
|
|
19
19
|
<div className="space-y-8">
|
|
20
20
|
{nav.map((section) => (
|
|
21
21
|
<div key={section.title}>
|
|
22
|
-
<h3 className="mb-3 text-
|
|
22
|
+
<h3 className="mb-3 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400">
|
|
23
23
|
{section.title}
|
|
24
24
|
</h3>
|
|
25
|
-
<ul className="space-y-
|
|
25
|
+
<ul className="space-y-1.5 border-l-2 border-gray-200 dark:border-gray-700">
|
|
26
26
|
{section.items.map((item) => (
|
|
27
27
|
<li key={item.href}>
|
|
28
28
|
<Link
|
|
29
29
|
href={item.href}
|
|
30
30
|
className={cn(
|
|
31
|
-
'block border-l-2 py-
|
|
31
|
+
'block border-l-2 py-1 pl-4 text-[17px] leading-snug transition-colors -ml-0.5',
|
|
32
32
|
currentPath === item.href
|
|
33
33
|
? 'border-primary-500 text-gray-900 dark:text-white font-bold'
|
|
34
|
-
: 'border-transparent text-gray-600 dark:text-gray-300 hover:border-
|
|
34
|
+
: 'border-transparent text-gray-600 dark:text-gray-300 hover:border-primary-300 dark:hover:border-primary-400 hover:text-gray-900 dark:hover:text-white'
|
|
35
35
|
)}
|
|
36
36
|
>
|
|
37
37
|
{item.title}
|
|
@@ -5,7 +5,7 @@ import type { TableOfContentsProps } from '../types'
|
|
|
5
5
|
* Table of contents component with scroll spy functionality.
|
|
6
6
|
* Displays "ON THIS PAGE" sidebar with heading links.
|
|
7
7
|
*/
|
|
8
|
-
export function TableOfContents({ items, className = '' }: TableOfContentsProps) {
|
|
8
|
+
export function TableOfContents({ items, className = '', ...props }: TableOfContentsProps) {
|
|
9
9
|
const [activeId, setActiveId] = useState<string>(() => {
|
|
10
10
|
// Initialize with hash from URL if present
|
|
11
11
|
if (typeof window !== 'undefined' && window.location.hash) {
|
|
@@ -149,11 +149,11 @@ export function TableOfContents({ items, className = '' }: TableOfContentsProps)
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
return (
|
|
152
|
-
<nav className={className}>
|
|
153
|
-
<h3 className="mb-3 text-
|
|
152
|
+
<nav className={className} {...props}>
|
|
153
|
+
<h3 className="mb-3 text-sm font-mono uppercase tracking-widest text-gray-500 dark:text-gray-400">
|
|
154
154
|
On this page
|
|
155
155
|
</h3>
|
|
156
|
-
<ul className="space-y-1 border-l-2 border-gray-200 dark:border-gray-700">
|
|
156
|
+
<ul className="space-y-1.5 border-l-2 border-gray-200 dark:border-gray-700">
|
|
157
157
|
{items.map((item) => {
|
|
158
158
|
const isActive = activeId === item.id
|
|
159
159
|
const indent = item.level === 3 ? 'pl-6' : 'pl-4'
|
|
@@ -163,10 +163,10 @@ export function TableOfContents({ items, className = '' }: TableOfContentsProps)
|
|
|
163
163
|
<a
|
|
164
164
|
href={`#${item.id}`}
|
|
165
165
|
onClick={(e) => handleClick(e, item.id)}
|
|
166
|
-
className={`block border-l-2 py-1
|
|
166
|
+
className={`block border-l-2 py-1 ${indent} -ml-0.5 text-base leading-snug transition-colors ${
|
|
167
167
|
isActive
|
|
168
168
|
? 'border-primary-500 text-gray-900 dark:text-white font-bold'
|
|
169
|
-
: 'border-transparent text-gray-600 dark:text-gray-300 hover:border-
|
|
169
|
+
: 'border-transparent text-gray-600 dark:text-gray-300 hover:border-primary-300 dark:hover:border-primary-400 hover:text-gray-900 dark:hover:text-white'
|
|
170
170
|
}`}
|
|
171
171
|
>
|
|
172
172
|
{item.text}
|
package/src/components/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { CodeBlock, InlineCode } from './CodeBlock'
|
|
2
2
|
export { DocSetSelector } from './DocSetSelector'
|
|
3
|
-
export { DocsLayout } from './DocsLayout'
|
|
3
|
+
export { DocsLayout, MobileMenuButton } from './DocsLayout'
|
|
4
4
|
export { DocsPage } from './DocsPage'
|
|
5
5
|
export { EmojiConfetti } from './EmojiConfetti'
|
|
6
6
|
export { HomePage } from './HomePage'
|
package/src/index.ts
CHANGED
package/src/styles.css
CHANGED
|
@@ -203,7 +203,8 @@
|
|
|
203
203
|
font-style: normal;
|
|
204
204
|
quotes: none;
|
|
205
205
|
background-color: rgb(241 245 249 / 0.8);
|
|
206
|
-
border-left-color:
|
|
206
|
+
border-left-color: var(--color-primary-400);
|
|
207
|
+
--tw-prose-quote-borders: var(--color-primary-400);
|
|
207
208
|
}
|
|
208
209
|
|
|
209
210
|
.prose blockquote p {
|
|
@@ -221,7 +222,8 @@
|
|
|
221
222
|
/* Dark mode blockquote */
|
|
222
223
|
.dark .prose blockquote {
|
|
223
224
|
background-color: rgb(51 65 85 / 0.15);
|
|
224
|
-
border-left-color:
|
|
225
|
+
border-left-color: var(--color-primary-500);
|
|
226
|
+
--tw-prose-quote-borders: var(--color-primary-500);
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
.dark .prose blockquote p {
|
package/src/types.ts
CHANGED
|
@@ -82,6 +82,10 @@ export interface DocsLayoutProps {
|
|
|
82
82
|
githubUrl?: string
|
|
83
83
|
/** Additional navigation links */
|
|
84
84
|
navLinks?: Array<{ label: string; href: string }>
|
|
85
|
+
/** Custom header component (replaces entire header). Can be a ReactNode or a function that receives mobile menu props. */
|
|
86
|
+
header?: ReactNode | ((props: { mobileMenuOpen: boolean; toggleMobileMenu: () => void }) => ReactNode)
|
|
87
|
+
/** Header height in pixels. Used to calculate content offset. Defaults to 64 (h-16). */
|
|
88
|
+
headerHeight?: number
|
|
85
89
|
/** Custom footer component */
|
|
86
90
|
footer?: ReactNode
|
|
87
91
|
/** Table of contents items for the current page */
|
|
@@ -92,6 +96,7 @@ export interface DocsLayoutProps {
|
|
|
92
96
|
export interface TableOfContentsProps {
|
|
93
97
|
items: TOCItem[]
|
|
94
98
|
className?: string
|
|
99
|
+
style: any
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
/** Props for Sidebar component */
|