@assistant-ui/docs-theme 0.0.0 → 0.0.2

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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/action-icons.d.ts +5 -0
  4. package/dist/action-icons.d.ts.map +1 -0
  5. package/dist/action-icons.js +52 -0
  6. package/dist/action-icons.js.map +1 -0
  7. package/dist/brand.d.ts +7 -0
  8. package/dist/brand.d.ts.map +1 -0
  9. package/dist/brand.js +37 -0
  10. package/dist/brand.js.map +1 -0
  11. package/dist/config.d.ts +3 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +22 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/header.d.ts +12 -0
  16. package/dist/header.d.ts.map +1 -0
  17. package/dist/header.js +73 -0
  18. package/dist/header.js.map +1 -0
  19. package/dist/index.d.ts +8 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +48 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/navigation.d.ts +23 -0
  24. package/dist/navigation.d.ts.map +1 -0
  25. package/dist/navigation.js +41 -0
  26. package/dist/navigation.js.map +1 -0
  27. package/dist/next.d.ts +29 -0
  28. package/dist/next.d.ts.map +1 -0
  29. package/dist/next.js +63 -0
  30. package/dist/next.js.map +1 -0
  31. package/dist/page-content.d.ts +12 -0
  32. package/dist/page-content.d.ts.map +1 -0
  33. package/dist/page-content.js +274 -0
  34. package/dist/page-content.js.map +1 -0
  35. package/dist/provider.d.ts +2 -0
  36. package/dist/provider.d.ts.map +1 -0
  37. package/dist/provider.js +1 -0
  38. package/package.json +91 -1
  39. package/src/action-icons.tsx +48 -0
  40. package/src/brand.tsx +36 -0
  41. package/src/config.ts +23 -0
  42. package/src/header.test.tsx +41 -0
  43. package/src/header.tsx +94 -0
  44. package/src/index.test.ts +37 -0
  45. package/src/index.ts +38 -0
  46. package/src/layout-hosts.test.tsx +98 -0
  47. package/src/navigation.test.ts +123 -0
  48. package/src/navigation.ts +61 -0
  49. package/src/next.test.tsx +110 -0
  50. package/src/next.tsx +101 -0
  51. package/src/page-content.test.tsx +87 -0
  52. package/src/page-content.tsx +416 -0
  53. package/src/provider.ts +1 -0
  54. package/styles/theme.css +858 -0
package/dist/next.js ADDED
@@ -0,0 +1,63 @@
1
+ import { withThemeDefaults } from "./config.js";
2
+ import { DocsHeader } from "./header.js";
3
+ import { DocsPageContent } from "./page-content.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { cloneElement } from "react";
6
+ import { createDocsLayout as createDocsLayout$1, createDocsMetadata as createDocsMetadata$1 } from "@farming-labs/theme";
7
+ // src/next.tsx
8
+ const createDocsMetadata = (config) => createDocsMetadata$1(config);
9
+ const createDocsLayout = (config, options) => {
10
+ const normalized = withThemeDefaults(config);
11
+ const DocsLayout = createDocsLayout$1({
12
+ ...normalized,
13
+ theme: {
14
+ ...normalized.theme,
15
+ name: "shadcn"
16
+ }
17
+ }, options.locale ? { locale: options.locale } : void 0);
18
+ const docsUrl = config.docsPath ?? `/${config.entry ?? "docs"}`;
19
+ const localizedDocsUrl = options.locale ? `${docsUrl}?lang=${encodeURIComponent(options.locale)}` : docsUrl;
20
+ const Layout = ({ children }) => {
21
+ const layout = DocsLayout({ children: /* @__PURE__ */ jsx(DocsPageContent, {
22
+ name: options.name,
23
+ github: config.github,
24
+ editUrl: options.editUrl,
25
+ mcpUrl: options.mcpUrl,
26
+ footer: options.footer,
27
+ children
28
+ }) });
29
+ const layoutProps = options.layoutProps;
30
+ const themedLayout = layoutProps ? cloneElement(layout, {
31
+ ...layoutProps,
32
+ sidebar: layoutProps.sidebar ? {
33
+ ...layout.props.sidebar,
34
+ ...layoutProps.sidebar
35
+ } : layout.props.sidebar
36
+ }) : layout;
37
+ return /* @__PURE__ */ jsxs("div", {
38
+ className: "aui-docs",
39
+ "data-docs-theme": "assistant-ui",
40
+ children: [
41
+ /* @__PURE__ */ jsx("a", {
42
+ className: "aui-docs-skip-link",
43
+ href: "#nd-page",
44
+ children: "Skip to content"
45
+ }),
46
+ /* @__PURE__ */ jsx(DocsHeader, {
47
+ brand: config.nav?.title ?? options.name,
48
+ brandSlot: options.brand,
49
+ homeUrl: options.homeUrl ?? (config.nav?.url && config.nav.url !== docsUrl ? config.nav.url : localizedDocsUrl),
50
+ docsUrl: localizedDocsUrl,
51
+ name: options.name,
52
+ links: options.links,
53
+ themeToggle: config.themeToggle !== false && (typeof config.themeToggle !== "object" || config.themeToggle.enabled !== false)
54
+ }),
55
+ themedLayout
56
+ ]
57
+ });
58
+ };
59
+ return Layout;
60
+ };
61
+ export { createDocsLayout, createDocsMetadata };
62
+
63
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","names":["createFrameworkDocsMetadata","createFrameworkDocsLayout"],"sources":["../src/next.tsx"],"sourcesContent":["import { cloneElement, type ReactNode } from \"react\";\nimport type { DocsLayoutProps } from \"fumadocs-ui/layouts/docs\";\nimport type { DocsConfig } from \"@farming-labs/docs\";\nimport {\n createDocsLayout as createFrameworkDocsLayout,\n createDocsMetadata as createFrameworkDocsMetadata,\n} from \"@farming-labs/theme\";\nimport { withThemeDefaults } from \"./config\";\nimport { DocsHeader } from \"./header\";\nimport { DocsPageContent } from \"./page-content\";\n\nexport const createDocsMetadata = (config: DocsConfig) =>\n createFrameworkDocsMetadata(config);\n\nexport const createDocsLayout = (\n config: DocsConfig,\n options: createDocsLayout.Options,\n) => {\n const normalized = withThemeDefaults(config);\n const DocsLayout = createFrameworkDocsLayout(\n {\n ...normalized,\n // Farming Labs 0.2 uses the base preset name to label Introduction folders.\n theme: { ...normalized.theme, name: \"shadcn\" },\n },\n options.locale ? { locale: options.locale } : undefined,\n );\n const docsUrl = config.docsPath ?? `/${config.entry ?? \"docs\"}`;\n const localizedDocsUrl = options.locale\n ? `${docsUrl}?lang=${encodeURIComponent(options.locale)}`\n : docsUrl;\n const Layout = ({ children }: { children: ReactNode }) => {\n const layout = DocsLayout({\n children: (\n <DocsPageContent\n name={options.name}\n github={config.github}\n editUrl={options.editUrl}\n mcpUrl={options.mcpUrl}\n footer={options.footer}\n >\n {children}\n </DocsPageContent>\n ),\n });\n const layoutProps = options.layoutProps;\n const themedLayout = layoutProps\n ? cloneElement(layout, {\n ...layoutProps,\n sidebar: layoutProps.sidebar\n ? { ...layout.props.sidebar, ...layoutProps.sidebar }\n : layout.props.sidebar,\n })\n : layout;\n return (\n <div className=\"aui-docs\" data-docs-theme=\"assistant-ui\">\n <a className=\"aui-docs-skip-link\" href=\"#nd-page\">\n Skip to content\n </a>\n <DocsHeader\n brand={(config.nav?.title as ReactNode) ?? options.name}\n brandSlot={options.brand}\n homeUrl={\n options.homeUrl ??\n (config.nav?.url && config.nav.url !== docsUrl\n ? config.nav.url\n : localizedDocsUrl)\n }\n docsUrl={localizedDocsUrl}\n name={options.name}\n links={options.links}\n themeToggle={\n config.themeToggle !== false &&\n (typeof config.themeToggle !== \"object\" ||\n config.themeToggle.enabled !== false)\n }\n />\n {themedLayout}\n </div>\n );\n };\n return Layout;\n};\n\nexport namespace createDocsLayout {\n export interface Options {\n name: string;\n /** Active locale from the site's Farming Labs i18n configuration. */\n locale?: string;\n /** Custom header branding, including interactive project switchers. */\n brand?: ReactNode;\n /** Framework layout overrides for custom page trees and sidebar slots. */\n layoutProps?: Partial<Omit<DocsLayoutProps, \"children\">>;\n homeUrl?: string;\n links?: readonly { label: string; href: string; external?: boolean }[];\n footer?: ReactNode;\n mcpUrl?: string;\n /** Override the repository edit link. `{path}` expands to the current page URL path. */\n editUrl?: string;\n }\n}\n"],"mappings":";;;;;;;AAWA,MAAa,sBAAsB,WACjCA,qBAA4B,MAAM;AAEpC,MAAa,oBACX,QACA,YACG;CACH,MAAM,aAAa,kBAAkB,MAAM;CAC3C,MAAM,aAAaC,mBACjB;EACE,GAAG;EAEH,OAAO;GAAE,GAAG,WAAW;GAAO,MAAM;EAAS;CAC/C,GACA,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,KAAA,CAChD;CACA,MAAM,UAAU,OAAO,YAAY,IAAI,OAAO,SAAS;CACvD,MAAM,mBAAmB,QAAQ,SAC7B,GAAG,QAAQ,QAAQ,mBAAmB,QAAQ,MAAM,MACpD;CACJ,MAAM,UAAU,EAAE,eAAwC;EACxD,MAAM,SAAS,WAAW,EACxB,UACE,oBAAC,iBAAD;GACE,MAAM,QAAQ;GACd,QAAQ,OAAO;GACf,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;GAEf;EACc,CAAA,EAErB,CAAC;EACD,MAAM,cAAc,QAAQ;EAC5B,MAAM,eAAe,cACjB,aAAa,QAAQ;GACnB,GAAG;GACH,SAAS,YAAY,UACjB;IAAE,GAAG,OAAO,MAAM;IAAS,GAAG,YAAY;GAAQ,IAClD,OAAO,MAAM;EACnB,CAAC,IACD;EACJ,OACE,qBAAC,OAAD;GAAK,WAAU;GAAW,mBAAgB;GAA1C,UAAA;IACE,oBAAC,KAAD;KAAG,WAAU;KAAqB,MAAK;KAAW,UAAA;IAE/C,CAAA;IACH,oBAAC,YAAD;KACE,OAAQ,OAAO,KAAK,SAAuB,QAAQ;KACnD,WAAW,QAAQ;KACnB,SACE,QAAQ,YACP,OAAO,KAAK,OAAO,OAAO,IAAI,QAAQ,UACnC,OAAO,IAAI,MACX;KAEN,SAAS;KACT,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,aACE,OAAO,gBAAgB,UACtB,OAAO,OAAO,gBAAgB,YAC7B,OAAO,YAAY,YAAY;IAEpC,CAAA;IACA;GACE;;CAET;CACA,OAAO;AACT"}
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from "react";
2
+ import { getEditUrl } from "./navigation.js";
3
+ import type { createDocsLayout } from "./next.js";
4
+ export declare const DocsPageContent: ({ children, name, github, editUrl, mcpUrl, footer, }: {
5
+ children: ReactNode;
6
+ name: string;
7
+ github: getEditUrl.Options | undefined;
8
+ editUrl: string | undefined;
9
+ mcpUrl: string | undefined;
10
+ footer: createDocsLayout.Options["footer"];
11
+ }) => import("react").JSX.Element;
12
+ //# sourceMappingURL=page-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-content.d.ts","sourceRoot":"","sources":["../src/page-content.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAmBf,OAAO,EAAE,UAAU,EAAoB,wBAAqB;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAe;AAqT/C,eAAO,MAAM,eAAe,GAAI,sDAO7B;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC;IACvC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5C,gCAgEA,CAAC"}
@@ -0,0 +1,274 @@
1
+ "use client";
2
+ import { ClaudeIcon, McpIcon, OpenAIIcon } from "./action-icons.js";
3
+ import { getEditUrl, getPageNeighbors } from "./navigation.js";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import Link from "next/link";
6
+ import { Check, ChevronLeft, ChevronRight, CircleAlert, Copy, FileText, MoreHorizontal, Pencil } from "lucide-react";
7
+ import { useEffect, useRef, useState, useSyncExternalStore } from "react";
8
+ import { createPortal } from "react-dom";
9
+ import { usePathname } from "next/navigation";
10
+ import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
11
+ import { useTreeContext } from "fumadocs-ui/contexts/tree";
12
+ import { useTOCItems } from "fumadocs-ui/components/toc";
13
+ // src/page-content.tsx
14
+ const documentSubscribers = /* @__PURE__ */ new Set();
15
+ let documentObserver;
16
+ const subscribeToDocument = (onChange) => {
17
+ documentSubscribers.add(onChange);
18
+ if (!documentObserver) {
19
+ documentObserver = new MutationObserver(() => {
20
+ for (const subscriber of documentSubscribers) subscriber();
21
+ });
22
+ documentObserver.observe(document.body, {
23
+ childList: true,
24
+ subtree: true
25
+ });
26
+ }
27
+ return () => {
28
+ documentSubscribers.delete(onChange);
29
+ if (documentSubscribers.size === 0) {
30
+ documentObserver?.disconnect();
31
+ documentObserver = void 0;
32
+ }
33
+ };
34
+ };
35
+ const useDocumentElement = (selector) => useSyncExternalStore(subscribeToDocument, () => selector ? document.querySelector(selector) : null, () => null);
36
+ const subscribeToOrigin = () => () => {};
37
+ const getOrigin = () => window.location.origin;
38
+ const getServerOrigin = () => "";
39
+ const PageActionLabel = ({ title, description }) => /* @__PURE__ */ jsxs("span", {
40
+ className: "aui-docs-action-label",
41
+ children: [/* @__PURE__ */ jsx("span", { children: title }), /* @__PURE__ */ jsx("span", { children: description })]
42
+ });
43
+ const DocsPageControls = ({ previous, next, title, pathname, markdownUrl, siteName, editUrl, mcpUrl }) => {
44
+ const toc = useTOCItems();
45
+ const headerHost = useDocumentElement("#nd-page .fd-generated-page-header");
46
+ const tocHost = useDocumentElement(toc.length > 0 ? "#nd-toc" : null);
47
+ const [message, setMessage] = useState("");
48
+ const [copying, setCopying] = useState(false);
49
+ const origin = useSyncExternalStore(subscribeToOrigin, getOrigin, getServerOrigin);
50
+ const markdown = useRef(null);
51
+ const githubUrl = editUrl?.replaceAll("{path}", pathname);
52
+ const publishedUrl = `${origin}${markdownUrl}`;
53
+ const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(`Read ${publishedUrl} (the ${siteName} documentation page "${title}") so I can ask questions about it.`)}`;
54
+ const loadMarkdown = () => {
55
+ markdown.current ??= fetch(markdownUrl).then((response) => {
56
+ if (!response.ok) throw new Error("Could not load this page");
57
+ return response.text();
58
+ }).catch((error) => {
59
+ markdown.current = null;
60
+ throw error;
61
+ });
62
+ return markdown.current;
63
+ };
64
+ const copy = async (kind) => {
65
+ setCopying(true);
66
+ try {
67
+ const text = kind === "page" ? await loadMarkdown() : new URL(mcpUrl ?? "", window.location.origin).href;
68
+ await navigator.clipboard.writeText(text);
69
+ setMessage(kind === "page" ? "Page copied" : "MCP server URL copied");
70
+ } catch {
71
+ setMessage("Could not copy. Please try again.");
72
+ } finally {
73
+ setCopying(false);
74
+ }
75
+ };
76
+ useEffect(() => {
77
+ if (!message) return;
78
+ const timer = window.setTimeout(() => setMessage(""), 3e3);
79
+ return () => window.clearTimeout(timer);
80
+ }, [message]);
81
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
82
+ headerHost && createPortal(/* @__PURE__ */ jsxs("nav", {
83
+ className: "aui-docs-page-controls not-prose",
84
+ "aria-label": "Page controls",
85
+ children: [
86
+ previous ? /* @__PURE__ */ jsx(Link, {
87
+ href: previous.url,
88
+ className: "aui-docs-pager-button",
89
+ "aria-label": "Previous page",
90
+ title: typeof previous.name === "string" || typeof previous.name === "number" ? `Previous: ${previous.name}` : "Previous page",
91
+ children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
92
+ }) : /* @__PURE__ */ jsx("button", {
93
+ className: "aui-docs-pager-button",
94
+ "aria-label": "Previous page",
95
+ disabled: true,
96
+ children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
97
+ }),
98
+ next ? /* @__PURE__ */ jsx(Link, {
99
+ href: next.url,
100
+ className: "aui-docs-pager-button",
101
+ "aria-label": "Next page",
102
+ title: typeof next.name === "string" || typeof next.name === "number" ? `Next: ${next.name}` : "Next page",
103
+ children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
104
+ }) : /* @__PURE__ */ jsx("button", {
105
+ className: "aui-docs-pager-button",
106
+ "aria-label": "Next page",
107
+ disabled: true,
108
+ children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
109
+ }),
110
+ /* @__PURE__ */ jsxs(DropdownMenu.Root, {
111
+ onOpenChange: (open) => {
112
+ if (open) loadMarkdown().catch(() => {});
113
+ },
114
+ children: [/* @__PURE__ */ jsx(DropdownMenu.Trigger, {
115
+ className: "aui-docs-pager-button",
116
+ "aria-label": "More page actions",
117
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { "aria-hidden": "true" })
118
+ }), /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsxs(DropdownMenu.Content, {
119
+ className: "aui-docs-actions-menu",
120
+ align: "end",
121
+ sideOffset: 4,
122
+ collisionPadding: 16,
123
+ children: [
124
+ /* @__PURE__ */ jsxs(DropdownMenu.Item, {
125
+ className: "aui-docs-actions-menu-item",
126
+ disabled: copying,
127
+ onSelect: () => void copy("page"),
128
+ children: [/* @__PURE__ */ jsx(Copy, { "aria-hidden": "true" }), /* @__PURE__ */ jsx(PageActionLabel, {
129
+ title: copying ? "Copying..." : "Copy page",
130
+ description: "Markdown, ready to paste into an LLM"
131
+ })]
132
+ }),
133
+ /* @__PURE__ */ jsx(DropdownMenu.Item, {
134
+ className: "aui-docs-actions-menu-item",
135
+ asChild: true,
136
+ children: /* @__PURE__ */ jsxs("a", {
137
+ href: markdownUrl,
138
+ target: "_blank",
139
+ rel: "noreferrer noopener",
140
+ children: [/* @__PURE__ */ jsx(FileText, { "aria-hidden": "true" }), /* @__PURE__ */ jsx(PageActionLabel, {
141
+ title: "View as Markdown",
142
+ description: "This page as plain text"
143
+ })]
144
+ })
145
+ }),
146
+ /* @__PURE__ */ jsx(DropdownMenu.Item, {
147
+ className: "aui-docs-actions-menu-item",
148
+ asChild: true,
149
+ children: /* @__PURE__ */ jsxs("a", {
150
+ href: claudeUrl,
151
+ target: "_blank",
152
+ rel: "noreferrer noopener",
153
+ children: [/* @__PURE__ */ jsx(ClaudeIcon, {}), /* @__PURE__ */ jsx(PageActionLabel, {
154
+ title: "Open in Claude",
155
+ description: "Ask Claude about this page"
156
+ })]
157
+ })
158
+ }),
159
+ /* @__PURE__ */ jsx(DropdownMenu.Item, {
160
+ className: "aui-docs-actions-menu-item",
161
+ asChild: true,
162
+ children: /* @__PURE__ */ jsxs("a", {
163
+ href: "https://chatgpt.com/codex/",
164
+ target: "_blank",
165
+ rel: "noreferrer noopener",
166
+ children: [/* @__PURE__ */ jsx(OpenAIIcon, {}), /* @__PURE__ */ jsx(PageActionLabel, {
167
+ title: "Open in Codex",
168
+ description: "Open Codex in ChatGPT"
169
+ })]
170
+ })
171
+ }),
172
+ mcpUrl && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenu.Separator, { className: "aui-docs-actions-menu-separator" }), /* @__PURE__ */ jsxs(DropdownMenu.Item, {
173
+ className: "aui-docs-actions-menu-item",
174
+ onSelect: () => void copy("mcp"),
175
+ children: [/* @__PURE__ */ jsx(McpIcon, {}), /* @__PURE__ */ jsx(PageActionLabel, {
176
+ title: "Copy MCP server URL",
177
+ description: "Use these docs from any MCP client"
178
+ })]
179
+ })] })
180
+ ]
181
+ }) })]
182
+ })
183
+ ]
184
+ }), headerHost),
185
+ tocHost && createPortal(/* @__PURE__ */ jsxs("div", {
186
+ className: "aui-docs-toc-actions not-prose",
187
+ children: [
188
+ /* @__PURE__ */ jsxs("button", {
189
+ type: "button",
190
+ onClick: () => void copy("page"),
191
+ disabled: copying,
192
+ children: [/* @__PURE__ */ jsx(Copy, { "aria-hidden": "true" }), copying ? "Copying..." : "Copy page"]
193
+ }),
194
+ /* @__PURE__ */ jsxs("a", {
195
+ href: markdownUrl,
196
+ target: "_blank",
197
+ rel: "noreferrer noopener",
198
+ children: [/* @__PURE__ */ jsx(FileText, { "aria-hidden": "true" }), "View as Markdown"]
199
+ }),
200
+ githubUrl && /* @__PURE__ */ jsxs("a", {
201
+ href: githubUrl,
202
+ target: "_blank",
203
+ rel: "noreferrer noopener",
204
+ children: [/* @__PURE__ */ jsx(Pencil, { "aria-hidden": "true" }), "Edit on GitHub"]
205
+ })
206
+ ]
207
+ }), tocHost),
208
+ /* @__PURE__ */ jsx("output", {
209
+ className: "aui-docs-action-status",
210
+ "aria-live": "polite",
211
+ children: message && /* @__PURE__ */ jsxs("span", { children: [message.startsWith("Could not") ? /* @__PURE__ */ jsx(CircleAlert, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Check, { "aria-hidden": "true" }), message] })
212
+ })
213
+ ] });
214
+ };
215
+ const DocsPageContent = ({ children, name, github, editUrl, mcpUrl, footer }) => {
216
+ const pathname = usePathname().replace(/\/$/, "");
217
+ const { root } = useTreeContext();
218
+ const { previous, next, current } = getPageNeighbors(root.children, pathname);
219
+ const title = current?.name;
220
+ const markdownUrl = `${pathname}.md${new URL(current?.url ?? pathname, "https://docs.local").search}`;
221
+ return /* @__PURE__ */ jsxs("div", {
222
+ className: "aui-docs-page-content",
223
+ children: [
224
+ /* @__PURE__ */ jsx(DocsPageControls, {
225
+ pathname,
226
+ markdownUrl,
227
+ title: typeof title === "string" ? title : name,
228
+ siteName: name,
229
+ editUrl: editUrl ?? getEditUrl(pathname, github),
230
+ mcpUrl,
231
+ previous,
232
+ next
233
+ }, markdownUrl),
234
+ /* @__PURE__ */ jsx("div", {
235
+ className: "aui-docs-page-body",
236
+ children
237
+ }),
238
+ (previous || next) && /* @__PURE__ */ jsxs("nav", {
239
+ className: "aui-docs-page-navigation not-prose",
240
+ "aria-label": "Page navigation",
241
+ children: [previous ? /* @__PURE__ */ jsxs(Link, {
242
+ href: previous.url,
243
+ rel: "prev",
244
+ children: [/* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" }), /* @__PURE__ */ jsxs("span", { children: [previous.section && /* @__PURE__ */ jsxs("span", {
245
+ className: "aui-docs-page-section",
246
+ children: [
247
+ previous.section,
248
+ " /",
249
+ " "
250
+ ]
251
+ }), previous.name] })]
252
+ }) : /* @__PURE__ */ jsx("span", {}), next ? /* @__PURE__ */ jsxs(Link, {
253
+ href: next.url,
254
+ rel: "next",
255
+ children: [/* @__PURE__ */ jsxs("span", { children: [next.section && /* @__PURE__ */ jsxs("span", {
256
+ className: "aui-docs-page-section",
257
+ children: [
258
+ next.section,
259
+ " /",
260
+ " "
261
+ ]
262
+ }), next.name] }), /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })]
263
+ }) : /* @__PURE__ */ jsx("span", {})]
264
+ }),
265
+ footer && /* @__PURE__ */ jsx("footer", {
266
+ className: "aui-docs-legal-footer not-prose",
267
+ children: footer
268
+ })
269
+ ]
270
+ });
271
+ };
272
+ export { DocsPageContent };
273
+
274
+ //# sourceMappingURL=page-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-content.js","names":[],"sources":["../src/page-content.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type ReactNode,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport Link from \"next/link\";\nimport { usePathname } from \"next/navigation\";\nimport * as DropdownMenu from \"@radix-ui/react-dropdown-menu\";\nimport { useTreeContext } from \"fumadocs-ui/contexts/tree\";\nimport { useTOCItems } from \"fumadocs-ui/components/toc\";\nimport {\n Check,\n CircleAlert,\n ChevronLeft,\n ChevronRight,\n Copy,\n FileText,\n MoreHorizontal,\n Pencil,\n} from \"lucide-react\";\nimport { ClaudeIcon, McpIcon, OpenAIIcon } from \"./action-icons\";\n\nimport { getEditUrl, getPageNeighbors } from \"./navigation\";\nimport type { createDocsLayout } from \"./next\";\n\ntype PageLink = getPageNeighbors.Link;\n\nconst documentSubscribers = new Set<() => void>();\nlet documentObserver: MutationObserver | undefined;\n\nconst subscribeToDocument = (onChange: () => void) => {\n documentSubscribers.add(onChange);\n if (!documentObserver) {\n documentObserver = new MutationObserver(() => {\n for (const subscriber of documentSubscribers) subscriber();\n });\n documentObserver.observe(document.body, { childList: true, subtree: true });\n }\n return () => {\n documentSubscribers.delete(onChange);\n if (documentSubscribers.size === 0) {\n documentObserver?.disconnect();\n documentObserver = undefined;\n }\n };\n};\n\nconst useDocumentElement = (selector: string | null) =>\n useSyncExternalStore(\n subscribeToDocument,\n () => (selector ? document.querySelector<HTMLElement>(selector) : null),\n () => null,\n );\n\nconst subscribeToOrigin = () => () => {};\nconst getOrigin = () => window.location.origin;\nconst getServerOrigin = () => \"\";\n\nconst PageActionLabel = ({\n title,\n description,\n}: {\n title: string;\n description: string;\n}) => (\n <span className=\"aui-docs-action-label\">\n <span>{title}</span>\n <span>{description}</span>\n </span>\n);\n\nconst DocsPageControls = ({\n previous,\n next,\n title,\n pathname,\n markdownUrl,\n siteName,\n editUrl,\n mcpUrl,\n}: {\n previous: PageLink | undefined;\n next: PageLink | undefined;\n title: string;\n pathname: string;\n markdownUrl: string;\n siteName: string;\n editUrl: string | undefined;\n mcpUrl: string | undefined;\n}) => {\n const toc = useTOCItems();\n // The upstream Farming Labs and Fumadocs layouts supply these portal hosts.\n const headerHost = useDocumentElement(\"#nd-page .fd-generated-page-header\");\n const tocHost = useDocumentElement(toc.length > 0 ? \"#nd-toc\" : null);\n const [message, setMessage] = useState(\"\");\n const [copying, setCopying] = useState(false);\n const origin = useSyncExternalStore(\n subscribeToOrigin,\n getOrigin,\n getServerOrigin,\n );\n const markdown = useRef<Promise<string> | null>(null);\n const githubUrl = editUrl?.replaceAll(\"{path}\", pathname);\n const publishedUrl = `${origin}${markdownUrl}`;\n const claudeUrl = `https://claude.ai/new?q=${encodeURIComponent(`Read ${publishedUrl} (the ${siteName} documentation page \"${title}\") so I can ask questions about it.`)}`;\n\n const loadMarkdown = () => {\n markdown.current ??= fetch(markdownUrl)\n .then((response) => {\n if (!response.ok) throw new Error(\"Could not load this page\");\n return response.text();\n })\n .catch((error: unknown) => {\n markdown.current = null;\n throw error;\n });\n return markdown.current;\n };\n\n const copy = async (kind: \"page\" | \"mcp\") => {\n setCopying(true);\n try {\n const text =\n kind === \"page\"\n ? await loadMarkdown()\n : new URL(mcpUrl ?? \"\", window.location.origin).href;\n await navigator.clipboard.writeText(text);\n setMessage(kind === \"page\" ? \"Page copied\" : \"MCP server URL copied\");\n } catch {\n setMessage(\"Could not copy. Please try again.\");\n } finally {\n setCopying(false);\n }\n };\n\n useEffect(() => {\n if (!message) return;\n const timer = window.setTimeout(() => setMessage(\"\"), 3000);\n return () => window.clearTimeout(timer);\n }, [message]);\n\n return (\n <>\n {headerHost &&\n createPortal(\n <nav\n className=\"aui-docs-page-controls not-prose\"\n aria-label=\"Page controls\"\n >\n {previous ? (\n <Link\n href={previous.url}\n className=\"aui-docs-pager-button\"\n aria-label=\"Previous page\"\n title={\n typeof previous.name === \"string\" ||\n typeof previous.name === \"number\"\n ? `Previous: ${previous.name}`\n : \"Previous page\"\n }\n >\n <ChevronLeft aria-hidden=\"true\" />\n </Link>\n ) : (\n <button\n className=\"aui-docs-pager-button\"\n aria-label=\"Previous page\"\n disabled\n >\n <ChevronLeft aria-hidden=\"true\" />\n </button>\n )}\n {next ? (\n <Link\n href={next.url}\n className=\"aui-docs-pager-button\"\n aria-label=\"Next page\"\n title={\n typeof next.name === \"string\" || typeof next.name === \"number\"\n ? `Next: ${next.name}`\n : \"Next page\"\n }\n >\n <ChevronRight aria-hidden=\"true\" />\n </Link>\n ) : (\n <button\n className=\"aui-docs-pager-button\"\n aria-label=\"Next page\"\n disabled\n >\n <ChevronRight aria-hidden=\"true\" />\n </button>\n )}\n <DropdownMenu.Root\n onOpenChange={(open) => {\n if (open) void loadMarkdown().catch(() => {});\n }}\n >\n <DropdownMenu.Trigger\n className=\"aui-docs-pager-button\"\n aria-label=\"More page actions\"\n >\n <MoreHorizontal aria-hidden=\"true\" />\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className=\"aui-docs-actions-menu\"\n align=\"end\"\n sideOffset={4}\n collisionPadding={16}\n >\n <DropdownMenu.Item\n className=\"aui-docs-actions-menu-item\"\n disabled={copying}\n onSelect={() => void copy(\"page\")}\n >\n <Copy aria-hidden=\"true\" />\n <PageActionLabel\n title={copying ? \"Copying...\" : \"Copy page\"}\n description=\"Markdown, ready to paste into an LLM\"\n />\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"aui-docs-actions-menu-item\"\n asChild\n >\n <a\n href={markdownUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n <FileText aria-hidden=\"true\" />\n <PageActionLabel\n title=\"View as Markdown\"\n description=\"This page as plain text\"\n />\n </a>\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"aui-docs-actions-menu-item\"\n asChild\n >\n <a\n href={claudeUrl}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n <ClaudeIcon />\n <PageActionLabel\n title=\"Open in Claude\"\n description=\"Ask Claude about this page\"\n />\n </a>\n </DropdownMenu.Item>\n <DropdownMenu.Item\n className=\"aui-docs-actions-menu-item\"\n asChild\n >\n <a\n href=\"https://chatgpt.com/codex/\"\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n <OpenAIIcon />\n <PageActionLabel\n title=\"Open in Codex\"\n description=\"Open Codex in ChatGPT\"\n />\n </a>\n </DropdownMenu.Item>\n {mcpUrl && (\n <>\n <DropdownMenu.Separator className=\"aui-docs-actions-menu-separator\" />\n <DropdownMenu.Item\n className=\"aui-docs-actions-menu-item\"\n onSelect={() => void copy(\"mcp\")}\n >\n <McpIcon />\n <PageActionLabel\n title=\"Copy MCP server URL\"\n description=\"Use these docs from any MCP client\"\n />\n </DropdownMenu.Item>\n </>\n )}\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n </nav>,\n headerHost,\n )}\n {tocHost &&\n createPortal(\n <div className=\"aui-docs-toc-actions not-prose\">\n <button\n type=\"button\"\n onClick={() => void copy(\"page\")}\n disabled={copying}\n >\n <Copy aria-hidden=\"true\" />\n {copying ? \"Copying...\" : \"Copy page\"}\n </button>\n <a href={markdownUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n <FileText aria-hidden=\"true\" />\n View as Markdown\n </a>\n {githubUrl && (\n <a href={githubUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n <Pencil aria-hidden=\"true\" />\n Edit on GitHub\n </a>\n )}\n </div>,\n tocHost,\n )}\n <output className=\"aui-docs-action-status\" aria-live=\"polite\">\n {message && (\n <span>\n {message.startsWith(\"Could not\") ? (\n <CircleAlert aria-hidden=\"true\" />\n ) : (\n <Check aria-hidden=\"true\" />\n )}\n {message}\n </span>\n )}\n </output>\n </>\n );\n};\n\nexport const DocsPageContent = ({\n children,\n name,\n github,\n editUrl,\n mcpUrl,\n footer,\n}: {\n children: ReactNode;\n name: string;\n github: getEditUrl.Options | undefined;\n editUrl: string | undefined;\n mcpUrl: string | undefined;\n footer: createDocsLayout.Options[\"footer\"];\n}) => {\n const pathname = usePathname().replace(/\\/$/, \"\");\n const { root } = useTreeContext();\n const { previous, next, current } = getPageNeighbors(root.children, pathname);\n const title = current?.name;\n const pageUrl = new URL(current?.url ?? pathname, \"https://docs.local\");\n const markdownUrl = `${pathname}.md${pageUrl.search}`;\n\n return (\n <div className=\"aui-docs-page-content\">\n <DocsPageControls\n key={markdownUrl}\n pathname={pathname}\n markdownUrl={markdownUrl}\n title={typeof title === \"string\" ? title : name}\n siteName={name}\n editUrl={editUrl ?? getEditUrl(pathname, github)}\n mcpUrl={mcpUrl}\n previous={previous}\n next={next}\n />\n <div className=\"aui-docs-page-body\">{children}</div>\n {(previous || next) && (\n <nav\n className=\"aui-docs-page-navigation not-prose\"\n aria-label=\"Page navigation\"\n >\n {previous ? (\n <Link href={previous.url} rel=\"prev\">\n <ChevronLeft aria-hidden=\"true\" />\n <span>\n {previous.section && (\n <span className=\"aui-docs-page-section\">\n {previous.section} /{\" \"}\n </span>\n )}\n {previous.name}\n </span>\n </Link>\n ) : (\n <span />\n )}\n {next ? (\n <Link href={next.url} rel=\"next\">\n <span>\n {next.section && (\n <span className=\"aui-docs-page-section\">\n {next.section} /{\" \"}\n </span>\n )}\n {next.name}\n </span>\n <ChevronRight aria-hidden=\"true\" />\n </Link>\n ) : (\n <span />\n )}\n </nav>\n )}\n {footer && (\n <footer className=\"aui-docs-legal-footer not-prose\">{footer}</footer>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { RootProvider } from "@farming-labs/theme";
2
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export { RootProvider } from "@farming-labs/theme";
package/package.json CHANGED
@@ -1 +1,91 @@
1
- {"name":"@assistant-ui/docs-theme","version":"0.0.0","description":"placeholder","license":"MIT"}
1
+ {
2
+ "name": "@assistant-ui/docs-theme",
3
+ "version": "0.0.2",
4
+ "description": "The assistant-ui documentation theme for Farming Labs Docs",
5
+ "license": "MIT",
6
+ "author": "AgentbaseAI Inc.",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./next": {
16
+ "types": "./dist/next.d.ts",
17
+ "default": "./dist/next.js"
18
+ },
19
+ "./provider": {
20
+ "types": "./dist/provider.d.ts",
21
+ "default": "./dist/provider.js"
22
+ },
23
+ "./styles.css": "./styles/theme.css"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src",
28
+ "styles",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "sideEffects": [
33
+ "**/*.css"
34
+ ],
35
+ "dependencies": {
36
+ "@radix-ui/react-dropdown-menu": "^2.2.1",
37
+ "lucide-react": "^1.61.0"
38
+ },
39
+ "peerDependencies": {
40
+ "@farming-labs/docs": "0.2.127",
41
+ "@farming-labs/theme": "0.2.127",
42
+ "fumadocs-ui": "16.17.1",
43
+ "next": "^16.0.0",
44
+ "next-themes": "^0.4.0",
45
+ "react": "^19.2.0",
46
+ "react-dom": "^19.2.0"
47
+ },
48
+ "devDependencies": {
49
+ "@assistant-ui/x-buildutils": "0.0.32",
50
+ "@farming-labs/docs": "0.2.127",
51
+ "@farming-labs/theme": "0.2.127",
52
+ "@types/node": "^26.6.5",
53
+ "@types/react": "^19.3.0",
54
+ "@types/react-dom": "^19.3.0",
55
+ "@vitest/coverage-v8": "^5.0.5",
56
+ "fumadocs-ui": "16.17.1",
57
+ "jsdom": "^30.1.3",
58
+ "next": "^16.4.3",
59
+ "next-themes": "^0.4.6",
60
+ "react": "^19.3.1",
61
+ "react-dom": "^19.3.1",
62
+ "typescript": "^7.0.2",
63
+ "vitest": "^5.0.5"
64
+ },
65
+ "publishConfig": {
66
+ "access": "public"
67
+ },
68
+ "repository": {
69
+ "type": "git",
70
+ "url": "git+https://github.com/assistant-ui/assistant-ui.git",
71
+ "directory": "packages/docs-theme"
72
+ },
73
+ "private": false,
74
+ "peerDependenciesMeta": {
75
+ "next": {
76
+ "optional": true
77
+ },
78
+ "next-themes": {
79
+ "optional": true
80
+ },
81
+ "react-dom": {
82
+ "optional": true
83
+ }
84
+ },
85
+ "scripts": {
86
+ "build": "aui-build",
87
+ "typecheck": "tsc --noEmit",
88
+ "test": "vitest run",
89
+ "test:coverage": "vitest run --coverage"
90
+ }
91
+ }
@@ -0,0 +1,48 @@
1
+ import type { ComponentProps } from "react";
2
+
3
+ export const ClaudeIcon = (props: ComponentProps<"svg">) => {
4
+ return (
5
+ <svg aria-hidden="true" {...props} viewBox="0 0 24 24" fill="currentColor">
6
+ <path d="m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z" />
7
+ </svg>
8
+ );
9
+ };
10
+
11
+ export const McpIcon = (props: ComponentProps<"svg">) => {
12
+ return (
13
+ <svg aria-hidden="true" {...props} viewBox="0 0 180 180" fill="none">
14
+ <path
15
+ d="M18 84.8528L85.8822 16.9706C95.2548 7.59798 110.451 7.59798 119.823 16.9706C129.196 26.3431 129.196 41.5391 119.823 50.9117L68.5581 102.177"
16
+ stroke="currentColor"
17
+ strokeWidth={12}
18
+ strokeLinecap="round"
19
+ />
20
+ <path
21
+ d="M69.2652 101.47L119.823 50.9117C129.196 41.5391 144.392 41.5391 153.765 50.9117L154.118 51.2652C163.491 60.6378 163.491 75.8338 154.118 85.2063L92.7248 146.6C89.6006 149.724 89.6006 154.789 92.7248 157.913L105.331 170.52"
22
+ stroke="currentColor"
23
+ strokeWidth={12}
24
+ strokeLinecap="round"
25
+ />
26
+ <path
27
+ d="M102.853 33.9411L52.6482 84.1457C43.2756 93.5183 43.2756 108.714 52.6482 118.087C62.0208 127.459 77.2167 127.459 86.5893 118.087L136.794 67.8822"
28
+ stroke="currentColor"
29
+ strokeWidth={12}
30
+ strokeLinecap="round"
31
+ />
32
+ </svg>
33
+ );
34
+ };
35
+
36
+ export const OpenAIIcon = (props: ComponentProps<"svg">) => {
37
+ return (
38
+ <svg
39
+ viewBox="0 0 256 260"
40
+ xmlns="http://www.w3.org/2000/svg"
41
+ fill="currentColor"
42
+ aria-hidden="true"
43
+ {...props}
44
+ >
45
+ <path d="M239.184 106.203a64.716 64.716 0 0 0-5.576-53.103C219.452 28.459 191 15.784 163.213 21.74A65.586 65.586 0 0 0 52.096 45.22a64.716 64.716 0 0 0-43.23 31.36c-14.31 24.602-11.061 55.634 8.033 76.74a64.665 64.665 0 0 0 5.525 53.102c14.174 24.65 42.644 37.324 70.446 31.36a64.72 64.72 0 0 0 48.754 21.744c28.481.025 53.714-18.361 62.414-45.481a64.767 64.767 0 0 0 43.229-31.36c14.137-24.558 10.875-55.423-8.083-76.483Zm-97.56 136.338a48.397 48.397 0 0 1-31.105-11.255l1.535-.87 51.67-29.825a8.595 8.595 0 0 0 4.247-7.367v-72.85l21.845 12.636c.218.111.37.32.409.563v60.367c-.056 26.818-21.783 48.545-48.601 48.601Zm-104.466-44.61a48.345 48.345 0 0 1-5.781-32.589l1.534.921 51.722 29.826a8.339 8.339 0 0 0 8.441 0l63.181-36.425v25.221a.87.87 0 0 1-.358.665l-52.335 30.184c-23.257 13.398-52.97 5.431-66.404-17.803ZM23.549 85.38a48.499 48.499 0 0 1 25.58-21.333v61.39a8.288 8.288 0 0 0 4.195 7.316l62.874 36.272-21.845 12.636a.819.819 0 0 1-.767 0L41.353 151.53c-23.211-13.454-31.171-43.144-17.804-66.405v.256Zm179.466 41.695-63.08-36.63L161.73 77.86a.819.819 0 0 1 .768 0l52.233 30.184a48.6 48.6 0 0 1-7.316 87.635v-61.391a8.544 8.544 0 0 0-4.4-7.213Zm21.742-32.69-1.535-.922-51.619-30.081a8.39 8.39 0 0 0-8.492 0L99.98 99.808V74.587a.716.716 0 0 1 .307-.665l52.233-30.133a48.652 48.652 0 0 1 72.236 50.391v.205ZM88.061 139.097l-21.845-12.585a.87.87 0 0 1-.41-.614V65.685a48.652 48.652 0 0 1 79.757-37.346l-1.535.87-51.67 29.825a8.595 8.595 0 0 0-4.246 7.367l-.051 72.697Zm11.868-25.58 28.138-16.217 28.188 16.218v32.434l-28.086 16.218-28.188-16.218-.052-32.434Z" />
46
+ </svg>
47
+ );
48
+ };
package/src/brand.tsx ADDED
@@ -0,0 +1,36 @@
1
+ export const DocsBrand = ({ name }: DocsBrand.Props) => {
2
+ return (
3
+ <span className="aui-docs-brand">
4
+ <svg
5
+ aria-hidden="true"
6
+ className="aui-docs-brand-logo"
7
+ viewBox="40 40 24 24"
8
+ fill="none"
9
+ >
10
+ <path
11
+ d="M52.5 44C52.5 43.9005 52.4704 43.8042 52.416 43.7227L52.3535 43.6465C52.2597 43.5527 52.1325 43.5 52 43.5H44C43.7284 43.5 43.5 43.7284 43.5 44V51.3789L44.9395 49.9395L45.0498 49.8398C45.3167 49.6212 45.652 49.5 46 49.5H52C52.1326 49.5 52.2597 49.4473 52.3535 49.3535C52.4473 49.2597 52.5 49.1326 52.5 49V44ZM55.5 49C55.5 49.9283 55.131 50.8182 54.4746 51.4746C53.8182 52.131 52.9282 52.5 52 52.5H46.6211L43.0605 56.0605C42.6315 56.4895 41.9863 56.6179 41.4258 56.3857C40.8654 56.1535 40.5 55.6066 40.5 55V44C40.5 42.0716 42.0716 40.5 44 40.5H52C52.9282 40.5 53.8182 40.869 54.4746 41.5254C55.131 42.1818 55.5 43.0718 55.5 44V49Z"
12
+ fill="currentColor"
13
+ />
14
+ <path
15
+ d="M60.5 51C60.5 50.9006 60.4704 50.8042 60.416 50.7227L60.3535 50.6465C60.2597 50.5527 60.1325 50.5 60 50.5H58C57.1716 50.5 56.5 49.8284 56.5 49C56.5 48.1716 57.1716 47.5 58 47.5H60C60.9282 47.5 61.8182 47.869 62.4746 48.5254C63.131 49.1818 63.5 50.0718 63.5 51V62C63.5 62.6066 63.1346 63.1535 62.5742 63.3857C62.0137 63.6179 61.3685 63.4895 60.9395 63.0605L57.3789 59.5H52C51.0718 59.5 50.1818 59.131 49.5254 58.4746C48.869 57.8182 48.5 56.9282 48.5 56V55C48.5 54.1716 49.1716 53.5 50 53.5C50.8284 53.5 51.5 54.1716 51.5 55V56C51.5 56.1326 51.5527 56.2597 51.6465 56.3535C51.7403 56.4473 51.8674 56.5 52 56.5H58C58.3978 56.5 58.7792 56.6581 59.0605 56.9395L60.5 58.3789V51Z"
16
+ fill="currentColor"
17
+ />
18
+ </svg>
19
+ <span className="aui-docs-brand-source">assistant-ui</span>
20
+ {name && (
21
+ <>
22
+ <span aria-hidden="true" className="aui-docs-brand-slash">
23
+ /
24
+ </span>
25
+ <span className="aui-docs-brand-product">{name}</span>
26
+ </>
27
+ )}
28
+ </span>
29
+ );
30
+ };
31
+
32
+ export namespace DocsBrand {
33
+ export interface Props {
34
+ name?: string;
35
+ }
36
+ }
package/src/config.ts ADDED
@@ -0,0 +1,23 @@
1
+ import {
2
+ defineDocs as defineFarmingDocs,
3
+ type DocsConfig,
4
+ } from "@farming-labs/docs";
5
+ import { assistantUi } from "./index";
6
+
7
+ export const withThemeDefaults = (options: DocsConfig): DocsConfig =>
8
+ defineFarmingDocs({
9
+ ...options,
10
+ theme: options.theme ?? assistantUi(),
11
+ sidebar:
12
+ options.sidebar === false
13
+ ? false
14
+ : {
15
+ collapsible: false,
16
+ flat: true,
17
+ folderIndexBehavior: "link",
18
+ ...(typeof options.sidebar === "object" ? options.sidebar : {}),
19
+ },
20
+ breadcrumb: options.breadcrumb ?? { enabled: false },
21
+ lastUpdated: options.lastUpdated ?? false,
22
+ pageActions: { copyMarkdown: false, openDocs: false },
23
+ });