@farming-labs/theme 0.0.2-beta.4

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.
Files changed (41) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +7 -0
  2. package/dist/ai-search-dialog.d.mts +37 -0
  3. package/dist/ai-search-dialog.mjs +937 -0
  4. package/dist/darksharp/index.d.mts +97 -0
  5. package/dist/darksharp/index.mjs +111 -0
  6. package/dist/default/index.d.mts +97 -0
  7. package/dist/default/index.mjs +110 -0
  8. package/dist/docs-ai-features.d.mts +23 -0
  9. package/dist/docs-ai-features.mjs +81 -0
  10. package/dist/docs-api.d.mts +68 -0
  11. package/dist/docs-api.mjs +204 -0
  12. package/dist/docs-layout.d.mts +33 -0
  13. package/dist/docs-layout.mjs +331 -0
  14. package/dist/docs-page-client.d.mts +46 -0
  15. package/dist/docs-page-client.mjs +128 -0
  16. package/dist/index.d.mts +11 -0
  17. package/dist/index.mjs +12 -0
  18. package/dist/mdx.d.mts +38 -0
  19. package/dist/mdx.mjs +27 -0
  20. package/dist/page-actions.d.mts +21 -0
  21. package/dist/page-actions.mjs +155 -0
  22. package/dist/pixel-border/index.d.mts +87 -0
  23. package/dist/pixel-border/index.mjs +95 -0
  24. package/dist/provider.d.mts +14 -0
  25. package/dist/provider.mjs +29 -0
  26. package/dist/search.d.mts +34 -0
  27. package/dist/search.mjs +36 -0
  28. package/dist/serialize-icon.d.mts +4 -0
  29. package/dist/serialize-icon.mjs +16 -0
  30. package/dist/theme.d.mts +2 -0
  31. package/dist/theme.mjs +3 -0
  32. package/package.json +90 -0
  33. package/styles/ai.css +894 -0
  34. package/styles/base.css +298 -0
  35. package/styles/darksharp.css +433 -0
  36. package/styles/default.css +88 -0
  37. package/styles/fumadocs.css +2 -0
  38. package/styles/pixel-border.css +671 -0
  39. package/styles/presets/base.css +14 -0
  40. package/styles/presets/black.css +14 -0
  41. package/styles/presets/neutral.css +14 -0
@@ -0,0 +1,128 @@
1
+ "use client";
2
+
3
+ import { PageActions } from "./page-actions.mjs";
4
+ import { useEffect, useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { DocsBody, DocsPage, EditOnGitHub } from "fumadocs-ui/layouts/docs/page";
7
+ import { usePathname, useRouter } from "next/navigation";
8
+
9
+ //#region src/docs-page-client.tsx
10
+ /**
11
+ * Path-based breadcrumb that shows only parent / current folder.
12
+ * Skips the entry segment (e.g. "docs"). Parent is clickable.
13
+ */
14
+ function PathBreadcrumb({ pathname, entry }) {
15
+ const router = useRouter();
16
+ const allSegments = pathname.split("/").filter(Boolean);
17
+ const segments = allSegments.filter((s) => s.toLowerCase() !== entry.toLowerCase());
18
+ if (segments.length < 2) return null;
19
+ const parentSegment = segments[segments.length - 2];
20
+ const currentSegment = segments[segments.length - 1];
21
+ const parentLabel = parentSegment.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
22
+ const currentLabel = currentSegment.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
23
+ const parentIndex = allSegments.indexOf(parentSegment);
24
+ const parentUrl = "/" + allSegments.slice(0, parentIndex + 1).join("/");
25
+ return /* @__PURE__ */ jsxs("nav", {
26
+ className: "fd-breadcrumb",
27
+ "aria-label": "Breadcrumb",
28
+ children: [/* @__PURE__ */ jsx("span", {
29
+ className: "fd-breadcrumb-item",
30
+ children: /* @__PURE__ */ jsx("a", {
31
+ href: parentUrl,
32
+ className: "fd-breadcrumb-parent fd-breadcrumb-link",
33
+ onClick: (e) => {
34
+ e.preventDefault();
35
+ router.push(parentUrl);
36
+ },
37
+ children: parentLabel
38
+ })
39
+ }), /* @__PURE__ */ jsxs("span", {
40
+ className: "fd-breadcrumb-item",
41
+ children: [/* @__PURE__ */ jsx("span", {
42
+ className: "fd-breadcrumb-sep",
43
+ children: "/"
44
+ }), /* @__PURE__ */ jsx("span", {
45
+ className: "fd-breadcrumb-current",
46
+ children: currentLabel
47
+ })]
48
+ })]
49
+ });
50
+ }
51
+ /**
52
+ * Client wrapper for DocsPage that auto-detects headings from the DOM,
53
+ * populates the Table of Contents, and renders page action buttons
54
+ * (Copy Markdown, Open in LLM). Re-scans when the route changes.
55
+ */
56
+ /**
57
+ * Build the GitHub URL for the current page's source file.
58
+ *
59
+ * Examples:
60
+ * No directory: https://github.com/user/repo/tree/main/app/docs/cli/page.mdx
61
+ * With directory: https://github.com/farming-labs/docs/tree/main/website/app/docs/cli/page.mdx
62
+ */
63
+ function buildGithubFileUrl(githubUrl, branch, pathname, directory) {
64
+ const segments = pathname.replace(/^\//, "").replace(/\/$/, "");
65
+ return `${githubUrl}/tree/${branch}/${directory ? `${directory}/` : ""}app/${segments}/page.mdx`;
66
+ }
67
+ function DocsPageClient({ tocEnabled, breadcrumbEnabled = true, entry = "docs", copyMarkdown = false, openDocs = false, openDocsProviders, pageActionsPosition = "below-title", githubUrl, githubBranch = "main", githubDirectory, lastModifiedMap, children }) {
68
+ const [toc, setToc] = useState([]);
69
+ const pathname = usePathname();
70
+ useEffect(() => {
71
+ if (!tocEnabled) return;
72
+ const timer = requestAnimationFrame(() => {
73
+ const container = document.getElementById("nd-page");
74
+ if (!container) return;
75
+ const headings = container.querySelectorAll("h2[id], h3[id], h4[id]");
76
+ setToc(Array.from(headings).map((el) => ({
77
+ title: el.textContent?.replace(/^#\s*/, "") || "",
78
+ url: `#${el.id}`,
79
+ depth: parseInt(el.tagName[1], 10)
80
+ })));
81
+ });
82
+ return () => cancelAnimationFrame(timer);
83
+ }, [tocEnabled, pathname]);
84
+ const showActions = copyMarkdown || openDocs;
85
+ const githubFileUrl = githubUrl ? buildGithubFileUrl(githubUrl, githubBranch, pathname, githubDirectory) : void 0;
86
+ const normalizedPath = pathname.replace(/\/$/, "") || "/";
87
+ const lastModified = lastModifiedMap?.[normalizedPath];
88
+ const showFooter = githubFileUrl || lastModified;
89
+ return /* @__PURE__ */ jsxs(DocsPage, {
90
+ toc,
91
+ tableOfContent: { enabled: tocEnabled },
92
+ tableOfContentPopover: { enabled: tocEnabled },
93
+ breadcrumb: { enabled: false },
94
+ children: [
95
+ breadcrumbEnabled && /* @__PURE__ */ jsx(PathBreadcrumb, {
96
+ pathname,
97
+ entry
98
+ }),
99
+ showActions && /* @__PURE__ */ jsx("div", {
100
+ "data-actions-position": pageActionsPosition,
101
+ children: /* @__PURE__ */ jsx(PageActions, {
102
+ copyMarkdown,
103
+ openDocs,
104
+ providers: openDocsProviders
105
+ })
106
+ }),
107
+ /* @__PURE__ */ jsxs(DocsBody, {
108
+ style: {
109
+ display: "flex",
110
+ flexDirection: "column"
111
+ },
112
+ children: [/* @__PURE__ */ jsx("div", {
113
+ style: { flex: 1 },
114
+ children
115
+ }), showFooter && /* @__PURE__ */ jsxs("div", {
116
+ className: "not-prose fd-page-footer",
117
+ children: [githubFileUrl && /* @__PURE__ */ jsx(EditOnGitHub, { href: githubFileUrl }), lastModified && /* @__PURE__ */ jsxs("span", {
118
+ className: "fd-last-updated",
119
+ children: ["Last updated: ", lastModified]
120
+ })]
121
+ })]
122
+ })
123
+ ]
124
+ });
125
+ }
126
+
127
+ //#endregion
128
+ export { DocsPageClient };
@@ -0,0 +1,11 @@
1
+ import { DefaultUIDefaults, fumadocs } from "./default/index.mjs";
2
+ import { createDocsLayout, createDocsMetadata } from "./docs-layout.mjs";
3
+ import { DocsPageClient } from "./docs-page-client.mjs";
4
+ import { RootProvider } from "./provider.mjs";
5
+ import { PageActions } from "./page-actions.mjs";
6
+ import { DocsLayout } from "fumadocs-ui/layouts/docs";
7
+ import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
8
+ import { AIConfig, BreadcrumbConfig, CopyMarkdownConfig, DocsConfig, DocsMetadata, DocsNav, DocsTheme, FontStyle, OGConfig, OpenDocsConfig, OpenDocsProvider, PageActionsConfig, PageFrontmatter, SidebarConfig, ThemeToggleConfig, TypographyConfig, UIConfig, createTheme, deepMerge, defineDocs, extendTheme } from "@farming-labs/docs";
9
+ import { Tab, Tabs } from "fumadocs-ui/components/tabs";
10
+ import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
11
+ export { type AIConfig, type BreadcrumbConfig, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, type CopyMarkdownConfig, DocsBody, type DocsConfig, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageFrontmatter, Pre, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, type TypographyConfig, type UIConfig, createDocsLayout, createDocsMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs };
package/dist/index.mjs ADDED
@@ -0,0 +1,12 @@
1
+ import { PageActions } from "./page-actions.mjs";
2
+ import { DocsPageClient } from "./docs-page-client.mjs";
3
+ import { createDocsLayout, createDocsMetadata } from "./docs-layout.mjs";
4
+ import { RootProvider } from "./provider.mjs";
5
+ import { DefaultUIDefaults, fumadocs } from "./default/index.mjs";
6
+ import { DocsLayout } from "fumadocs-ui/layouts/docs";
7
+ import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
8
+ import { createTheme, deepMerge, defineDocs, extendTheme } from "@farming-labs/docs";
9
+ import { Tab, Tabs } from "fumadocs-ui/components/tabs";
10
+ import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
11
+
12
+ export { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, DocsBody, DocsLayout, DocsPage, DocsPageClient, DefaultUIDefaults as FumadocsUIDefaults, PageActions, Pre, RootProvider, Tab, Tabs, createDocsLayout, createDocsMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs };
package/dist/mdx.d.mts ADDED
@@ -0,0 +1,38 @@
1
+ import * as react from "react";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+ import { Tab, Tabs } from "fumadocs-ui/components/tabs";
4
+ import * as fumadocs_ui_components_codeblock0 from "fumadocs-ui/components/codeblock";
5
+ import defaultMdxComponents from "fumadocs-ui/mdx";
6
+ import * as fumadocs_ui_components_card0 from "fumadocs-ui/components/card";
7
+ import * as fumadocs_ui_components_callout0 from "fumadocs-ui/components/callout";
8
+
9
+ //#region src/mdx.d.ts
10
+ declare const extendedMdxComponents: {
11
+ Tab: typeof Tab;
12
+ Tabs: typeof Tabs;
13
+ CodeBlockTab: typeof fumadocs_ui_components_codeblock0.CodeBlockTab;
14
+ CodeBlockTabs: typeof fumadocs_ui_components_codeblock0.CodeBlockTabs;
15
+ CodeBlockTabsList: typeof fumadocs_ui_components_codeblock0.CodeBlockTabsList;
16
+ CodeBlockTabsTrigger: typeof fumadocs_ui_components_codeblock0.CodeBlockTabsTrigger;
17
+ pre: (props: react.HTMLAttributes<HTMLPreElement>) => react_jsx_runtime0.JSX.Element;
18
+ Card: typeof fumadocs_ui_components_card0.Card;
19
+ Cards: typeof fumadocs_ui_components_card0.Cards;
20
+ a: react.FC<react.AnchorHTMLAttributes<HTMLAnchorElement>>;
21
+ img: (props: react.ImgHTMLAttributes<HTMLImageElement> & {
22
+ sizes?: string;
23
+ }) => react_jsx_runtime0.JSX.Element;
24
+ h1: (props: react.HTMLAttributes<HTMLHeadingElement>) => react_jsx_runtime0.JSX.Element;
25
+ h2: (props: react.HTMLAttributes<HTMLHeadingElement>) => react_jsx_runtime0.JSX.Element;
26
+ h3: (props: react.HTMLAttributes<HTMLHeadingElement>) => react_jsx_runtime0.JSX.Element;
27
+ h4: (props: react.HTMLAttributes<HTMLHeadingElement>) => react_jsx_runtime0.JSX.Element;
28
+ h5: (props: react.HTMLAttributes<HTMLHeadingElement>) => react_jsx_runtime0.JSX.Element;
29
+ h6: (props: react.HTMLAttributes<HTMLHeadingElement>) => react_jsx_runtime0.JSX.Element;
30
+ table: (props: react.TableHTMLAttributes<HTMLTableElement>) => react_jsx_runtime0.JSX.Element;
31
+ Callout: typeof fumadocs_ui_components_callout0.Callout;
32
+ CalloutContainer: typeof fumadocs_ui_components_callout0.CalloutContainer;
33
+ CalloutTitle: typeof fumadocs_ui_components_callout0.CalloutTitle;
34
+ CalloutDescription: typeof fumadocs_ui_components_callout0.CalloutDescription;
35
+ };
36
+ declare function getMDXComponents<T extends Record<string, unknown> = Record<string, unknown>>(overrides?: T): typeof extendedMdxComponents & T;
37
+ //#endregion
38
+ export { Tab, Tabs, defaultMdxComponents, extendedMdxComponents, getMDXComponents };
package/dist/mdx.mjs ADDED
@@ -0,0 +1,27 @@
1
+ import { Tab, Tabs } from "fumadocs-ui/components/tabs";
2
+ import defaultMdxComponents from "fumadocs-ui/mdx";
3
+
4
+ //#region src/mdx.ts
5
+ /**
6
+ * Re-export fumadocs-ui MDX components.
7
+ *
8
+ * Includes all default MDX components (headings, code blocks, callouts, cards)
9
+ * plus Tabs/Tab for tabbed content and InstallTabs for package manager tabs.
10
+ *
11
+ * Usage in mdx-components.tsx:
12
+ * import { getMDXComponents } from "@farming-labs/theme/mdx";
13
+ */
14
+ const extendedMdxComponents = {
15
+ ...defaultMdxComponents,
16
+ Tab,
17
+ Tabs
18
+ };
19
+ function getMDXComponents(overrides) {
20
+ return {
21
+ ...extendedMdxComponents,
22
+ ...overrides
23
+ };
24
+ }
25
+
26
+ //#endregion
27
+ export { Tab, Tabs, defaultMdxComponents, extendedMdxComponents, getMDXComponents };
@@ -0,0 +1,21 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/page-actions.d.ts
4
+ /** Serializable provider — icon is an HTML string, not JSX. */
5
+ interface SerializedProvider {
6
+ name: string;
7
+ iconHtml?: string;
8
+ urlTemplate: string;
9
+ }
10
+ interface PageActionsProps {
11
+ copyMarkdown?: boolean;
12
+ openDocs?: boolean;
13
+ providers?: SerializedProvider[];
14
+ }
15
+ declare function PageActions({
16
+ copyMarkdown,
17
+ openDocs,
18
+ providers
19
+ }: PageActionsProps): react_jsx_runtime0.JSX.Element | null;
20
+ //#endregion
21
+ export { PageActions };
@@ -0,0 +1,155 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { usePathname } from "next/navigation";
6
+
7
+ //#region src/page-actions.tsx
8
+ const CopyIcon = () => /* @__PURE__ */ jsxs("svg", {
9
+ width: "14",
10
+ height: "14",
11
+ viewBox: "0 0 24 24",
12
+ fill: "none",
13
+ stroke: "currentColor",
14
+ strokeWidth: "2",
15
+ strokeLinecap: "round",
16
+ strokeLinejoin: "round",
17
+ children: [/* @__PURE__ */ jsx("rect", {
18
+ x: "9",
19
+ y: "9",
20
+ width: "13",
21
+ height: "13",
22
+ rx: "2",
23
+ ry: "2"
24
+ }), /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })]
25
+ });
26
+ const CheckIcon = () => /* @__PURE__ */ jsx("svg", {
27
+ width: "14",
28
+ height: "14",
29
+ viewBox: "0 0 24 24",
30
+ fill: "none",
31
+ stroke: "currentColor",
32
+ strokeWidth: "2",
33
+ strokeLinecap: "round",
34
+ strokeLinejoin: "round",
35
+ children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
36
+ });
37
+ const ChevronDownIcon = () => /* @__PURE__ */ jsx("svg", {
38
+ width: "12",
39
+ height: "12",
40
+ viewBox: "0 0 24 24",
41
+ fill: "none",
42
+ stroke: "currentColor",
43
+ strokeWidth: "2",
44
+ strokeLinecap: "round",
45
+ strokeLinejoin: "round",
46
+ children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
47
+ });
48
+ const ExternalLinkIcon = () => /* @__PURE__ */ jsxs("svg", {
49
+ width: "12",
50
+ height: "12",
51
+ viewBox: "0 0 24 24",
52
+ fill: "none",
53
+ stroke: "currentColor",
54
+ strokeWidth: "2",
55
+ strokeLinecap: "round",
56
+ strokeLinejoin: "round",
57
+ children: [
58
+ /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
59
+ /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
60
+ /* @__PURE__ */ jsx("line", {
61
+ x1: "10",
62
+ y1: "14",
63
+ x2: "21",
64
+ y2: "3"
65
+ })
66
+ ]
67
+ });
68
+ const DEFAULT_PROVIDERS = [{
69
+ name: "ChatGPT",
70
+ urlTemplate: "https://chatgpt.com/?hints=search&q=Read+{mdxUrl},+I+want+to+ask+questions+about+it."
71
+ }, {
72
+ name: "Claude",
73
+ urlTemplate: "https://claude.ai/new?q=Read+{mdxUrl},+I+want+to+ask+questions+about+it."
74
+ }];
75
+ function PageActions({ copyMarkdown, openDocs, providers }) {
76
+ const [copied, setCopied] = useState(false);
77
+ const [dropdownOpen, setDropdownOpen] = useState(false);
78
+ const dropdownRef = useRef(null);
79
+ const pathname = usePathname();
80
+ const resolvedProviders = providers ?? DEFAULT_PROVIDERS;
81
+ const handleCopyMarkdown = useCallback(async () => {
82
+ try {
83
+ const article = document.querySelector("article");
84
+ if (article) {
85
+ await navigator.clipboard.writeText(article.innerText || "");
86
+ setCopied(true);
87
+ setTimeout(() => setCopied(false), 2e3);
88
+ }
89
+ } catch {}
90
+ }, []);
91
+ const handleOpen = useCallback((template) => {
92
+ const pageUrl = window.location.href;
93
+ const mdxUrl = `${window.location.origin}${pathname}.mdx`;
94
+ const url = template.replace(/\{url\}/g, encodeURIComponent(pageUrl)).replace(/\{mdxUrl\}/g, encodeURIComponent(mdxUrl));
95
+ window.open(url, "_blank", "noopener,noreferrer");
96
+ setDropdownOpen(false);
97
+ }, [pathname]);
98
+ useEffect(() => {
99
+ if (!dropdownOpen) return;
100
+ function handleClick(e) {
101
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) setDropdownOpen(false);
102
+ }
103
+ document.addEventListener("mousedown", handleClick);
104
+ return () => document.removeEventListener("mousedown", handleClick);
105
+ }, [dropdownOpen]);
106
+ useEffect(() => {
107
+ setDropdownOpen(false);
108
+ setCopied(false);
109
+ }, [pathname]);
110
+ if (!copyMarkdown && !openDocs) return null;
111
+ return /* @__PURE__ */ jsxs("div", {
112
+ className: "fd-page-actions",
113
+ "data-page-actions": true,
114
+ children: [copyMarkdown && /* @__PURE__ */ jsxs("button", {
115
+ type: "button",
116
+ onClick: handleCopyMarkdown,
117
+ className: "fd-page-action-btn",
118
+ "data-copied": copied,
119
+ children: [copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {}), /* @__PURE__ */ jsx("span", { children: copied ? "Copied!" : "Copy Markdown" })]
120
+ }), openDocs && resolvedProviders.length > 0 && /* @__PURE__ */ jsxs("div", {
121
+ ref: dropdownRef,
122
+ className: "fd-page-action-dropdown",
123
+ children: [/* @__PURE__ */ jsxs("button", {
124
+ type: "button",
125
+ onClick: () => setDropdownOpen(!dropdownOpen),
126
+ className: "fd-page-action-btn",
127
+ "aria-expanded": dropdownOpen,
128
+ children: [/* @__PURE__ */ jsx("span", { children: "Open in" }), /* @__PURE__ */ jsx(ChevronDownIcon, {})]
129
+ }), dropdownOpen && /* @__PURE__ */ jsx("div", {
130
+ className: "fd-page-action-menu",
131
+ role: "menu",
132
+ children: resolvedProviders.map((provider) => /* @__PURE__ */ jsxs("button", {
133
+ type: "button",
134
+ role: "menuitem",
135
+ className: "fd-page-action-menu-item",
136
+ onClick: () => handleOpen(provider.urlTemplate),
137
+ children: [
138
+ provider.iconHtml && /* @__PURE__ */ jsx("span", {
139
+ className: "fd-page-action-menu-icon",
140
+ dangerouslySetInnerHTML: { __html: provider.iconHtml }
141
+ }),
142
+ /* @__PURE__ */ jsxs("span", {
143
+ className: "fd-page-action-menu-label",
144
+ children: ["Open in ", provider.name]
145
+ }),
146
+ /* @__PURE__ */ jsx(ExternalLinkIcon, {})
147
+ ]
148
+ }, provider.name))
149
+ })]
150
+ })]
151
+ });
152
+ }
153
+
154
+ //#endregion
155
+ export { PageActions };
@@ -0,0 +1,87 @@
1
+ import { DocsTheme } from "@farming-labs/docs";
2
+
3
+ //#region src/pixel-border/index.d.ts
4
+ /**
5
+ * Pixel-border UI defaults — better-auth inspired, clean dark UI.
6
+ *
7
+ * Theme authors can import and extend:
8
+ * ```ts
9
+ * import { PixelBorderUIDefaults } from "@farming-labs/theme/pixel-border";
10
+ * ```
11
+ */
12
+ declare const PixelBorderUIDefaults: {
13
+ colors: {
14
+ primary: string;
15
+ background: string;
16
+ muted: string;
17
+ border: string;
18
+ };
19
+ typography: {
20
+ font: {
21
+ style: {
22
+ sans: string;
23
+ mono: string;
24
+ };
25
+ h1: {
26
+ size: string;
27
+ weight: number;
28
+ lineHeight: string;
29
+ letterSpacing: string;
30
+ };
31
+ h2: {
32
+ size: string;
33
+ weight: number;
34
+ lineHeight: string;
35
+ letterSpacing: string;
36
+ };
37
+ h3: {
38
+ size: string;
39
+ weight: number;
40
+ lineHeight: string;
41
+ };
42
+ h4: {
43
+ size: string;
44
+ weight: number;
45
+ lineHeight: string;
46
+ };
47
+ body: {
48
+ size: string;
49
+ weight: number;
50
+ lineHeight: string;
51
+ };
52
+ small: {
53
+ size: string;
54
+ weight: number;
55
+ lineHeight: string;
56
+ };
57
+ };
58
+ };
59
+ layout: {
60
+ contentWidth: number;
61
+ sidebarWidth: number;
62
+ toc: {
63
+ enabled: boolean;
64
+ depth: number;
65
+ };
66
+ header: {
67
+ height: number;
68
+ sticky: boolean;
69
+ };
70
+ };
71
+ components: {};
72
+ };
73
+ /**
74
+ * Pixel-border theme preset factory.
75
+ *
76
+ * Built with `createTheme` — the same helper theme authors use.
77
+ * Inspired by better-auth.com — clean dark UI with visible borders.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { pixelBorder } from "@farming-labs/theme/pixel-border";
82
+ * export default defineDocs({ theme: pixelBorder() });
83
+ * ```
84
+ */
85
+ declare const pixelBorder: (overrides?: Partial<DocsTheme>) => DocsTheme;
86
+ //#endregion
87
+ export { PixelBorderUIDefaults, pixelBorder };
@@ -0,0 +1,95 @@
1
+ import { createTheme } from "@farming-labs/docs";
2
+
3
+ //#region src/pixel-border/index.ts
4
+ /**
5
+ * @farming-labs/theme/pixel-border
6
+ *
7
+ * Inspired by better-auth.com — clean dark UI with visible rounded borders,
8
+ * pixel-perfect spacing, and a refined sidebar.
9
+ */
10
+ /**
11
+ * Pixel-border UI defaults — better-auth inspired, clean dark UI.
12
+ *
13
+ * Theme authors can import and extend:
14
+ * ```ts
15
+ * import { PixelBorderUIDefaults } from "@farming-labs/theme/pixel-border";
16
+ * ```
17
+ */
18
+ const PixelBorderUIDefaults = {
19
+ colors: {
20
+ primary: "oklch(0.985 0.001 106.423)",
21
+ background: "hsl(0 0% 2%)",
22
+ muted: "hsl(0 0% 55%)",
23
+ border: "hsl(0 0% 15%)"
24
+ },
25
+ typography: { font: {
26
+ style: {
27
+ sans: "var(--font-geist-sans, system-ui, -apple-system, sans-serif)",
28
+ mono: "var(--font-geist-mono, ui-monospace, monospace)"
29
+ },
30
+ h1: {
31
+ size: "2.25rem",
32
+ weight: 700,
33
+ lineHeight: "1.2",
34
+ letterSpacing: "-0.02em"
35
+ },
36
+ h2: {
37
+ size: "1.5rem",
38
+ weight: 600,
39
+ lineHeight: "1.3",
40
+ letterSpacing: "-0.01em"
41
+ },
42
+ h3: {
43
+ size: "1.25rem",
44
+ weight: 600,
45
+ lineHeight: "1.4"
46
+ },
47
+ h4: {
48
+ size: "1.125rem",
49
+ weight: 600,
50
+ lineHeight: "1.4"
51
+ },
52
+ body: {
53
+ size: "1rem",
54
+ weight: 400,
55
+ lineHeight: "1.75"
56
+ },
57
+ small: {
58
+ size: "0.875rem",
59
+ weight: 400,
60
+ lineHeight: "1.5"
61
+ }
62
+ } },
63
+ layout: {
64
+ contentWidth: 860,
65
+ sidebarWidth: 286,
66
+ toc: {
67
+ enabled: true,
68
+ depth: 3
69
+ },
70
+ header: {
71
+ height: 56,
72
+ sticky: true
73
+ }
74
+ },
75
+ components: {}
76
+ };
77
+ /**
78
+ * Pixel-border theme preset factory.
79
+ *
80
+ * Built with `createTheme` — the same helper theme authors use.
81
+ * Inspired by better-auth.com — clean dark UI with visible borders.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { pixelBorder } from "@farming-labs/theme/pixel-border";
86
+ * export default defineDocs({ theme: pixelBorder() });
87
+ * ```
88
+ */
89
+ const pixelBorder = createTheme({
90
+ name: "fumadocs-pixel-border",
91
+ ui: PixelBorderUIDefaults
92
+ });
93
+
94
+ //#endregion
95
+ export { PixelBorderUIDefaults, pixelBorder };
@@ -0,0 +1,14 @@
1
+ import { ComponentPropsWithoutRef } from "react";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
+ import { RootProvider as RootProvider$1 } from "fumadocs-ui/provider/next";
4
+
5
+ //#region src/provider.d.ts
6
+ type FumadocsProviderProps = ComponentPropsWithoutRef<typeof RootProvider$1>;
7
+ interface DocsRootProviderProps extends FumadocsProviderProps {}
8
+ declare function RootProvider({
9
+ children,
10
+ search,
11
+ ...props
12
+ }: DocsRootProviderProps): react_jsx_runtime0.JSX.Element;
13
+ //#endregion
14
+ export { DocsRootProviderProps, RootProvider };
@@ -0,0 +1,29 @@
1
+ "use client";
2
+
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { RootProvider as RootProvider$1 } from "fumadocs-ui/provider/next";
5
+
6
+ //#region src/provider.tsx
7
+ /**
8
+ * RootProvider wrapper — thin layer over fumadocs-ui's RootProvider.
9
+ *
10
+ * Defaults the search API to `/api/docs` (unified handler).
11
+ * AI features are handled automatically by `createDocsLayout`
12
+ * based on the `ai` config in `docs.config.tsx` — no props needed here.
13
+ */
14
+ function RootProvider({ children, search, ...props }) {
15
+ return /* @__PURE__ */ jsx(RootProvider$1, {
16
+ search: {
17
+ ...search,
18
+ options: {
19
+ api: "/api/docs",
20
+ ...search?.options
21
+ }
22
+ },
23
+ ...props,
24
+ children
25
+ });
26
+ }
27
+
28
+ //#endregion
29
+ export { RootProvider };
@@ -0,0 +1,34 @@
1
+ //#region src/search.d.ts
2
+ /**
3
+ * Search API — backward-compatible re-export.
4
+ *
5
+ * New projects should use `createDocsAPI` from `@farming-labs/theme/api`
6
+ * which provides a unified handler for both search (GET) and AI chat (POST).
7
+ *
8
+ * This module is kept for backward compatibility with existing projects
9
+ * that import `createDocsSearchAPI` from `@farming-labs/theme/search`.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // Recommended (new): app/api/docs/route.ts
14
+ * import { createDocsAPI } from "@farming-labs/theme/api";
15
+ * export const { GET, POST } = createDocsAPI();
16
+ *
17
+ * // Legacy: app/api/search/route.ts
18
+ * import { createDocsSearchAPI } from "@farming-labs/theme/search";
19
+ * export const { GET } = createDocsSearchAPI();
20
+ * ```
21
+ */
22
+ /**
23
+ * @deprecated Use `createDocsAPI` from `@farming-labs/theme/api` instead.
24
+ * This function is kept for backward compatibility.
25
+ */
26
+ declare function createDocsSearchAPI(options?: {
27
+ entry?: string;
28
+ language?: string;
29
+ }): {
30
+ GET: (request: Request) => Promise<Response>;
31
+ POST(request: Request): Promise<Response>;
32
+ };
33
+ //#endregion
34
+ export { createDocsSearchAPI };