@farming-labs/theme 0.1.57 → 0.1.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs-layout.mjs +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/mdx.d.mts +7 -1
- package/dist/mdx.mjs +41 -10
- package/dist/prompt-text.mjs +23 -0
- package/dist/prompt.d.mts +53 -0
- package/dist/prompt.mjs +281 -0
- package/dist/tanstack-layout.mjs +1 -1
- package/package.json +2 -2
- package/styles/base.css +175 -5
- package/styles/pixel-border.css +62 -0
package/dist/docs-layout.mjs
CHANGED
|
@@ -587,7 +587,7 @@ function createDocsLayout(config, options) {
|
|
|
587
587
|
const readingTimeWordsPerMinute = readingTimeOptions.wordsPerMinute ?? 220;
|
|
588
588
|
const llmsTxtEnabled = resolveBool(config.llmsTxt);
|
|
589
589
|
const feedbackConfig = resolveFeedbackConfig(config.feedback);
|
|
590
|
-
const openDocsProviders = (typeof pageActions
|
|
590
|
+
const openDocsProviders = (pageActions?.openDocs && typeof pageActions.openDocs === "object" && pageActions.openDocs.providers ? pageActions.openDocs.providers : void 0)?.map((p) => ({
|
|
591
591
|
name: p.name,
|
|
592
592
|
urlTemplate: p.urlTemplate,
|
|
593
593
|
iconHtml: p.icon ? serializeIcon(p.icon) : void 0
|
package/dist/index.d.mts
CHANGED
|
@@ -11,10 +11,11 @@ import { DocsFeedback, DocsFeedbackProps } from "./docs-feedback.mjs";
|
|
|
11
11
|
import { PageActions } from "./page-actions.mjs";
|
|
12
12
|
import { withLangInUrl } from "./i18n.mjs";
|
|
13
13
|
import { HoverLink, HoverLinkProps } from "./hover-link.mjs";
|
|
14
|
+
import { Prompt, PromptProps } from "./prompt.mjs";
|
|
14
15
|
import { Agent } from "./mdx.mjs";
|
|
15
16
|
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
|
16
17
|
import { AIConfig, BreadcrumbConfig, ChangelogConfig, ChangelogFrontmatter, CopyMarkdownConfig, DocsConfig, DocsFeedbackData, DocsFeedbackValue, DocsMetadata, DocsNav, DocsTheme, FeedbackConfig, FontStyle, OGConfig, OpenDocsConfig, OpenDocsProvider, PageActionsConfig, PageFrontmatter, SidebarConfig, ThemeToggleConfig, TypographyConfig, UIConfig, createTheme, deepMerge, defineDocs, extendTheme } from "@farming-labs/docs";
|
|
17
18
|
import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
|
|
18
19
|
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
|
19
20
|
import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
|
|
20
|
-
export { type AIConfig, Agent, type BreadcrumbConfig, type ChangelogConfig, type ChangelogFrontmatter, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CommandGridUIDefaults, ConcreteUIDefaults, type CopyMarkdownConfig, DocsBody, DocsClientHooks, DocsCommandSearch, type DocsConfig, DocsFeedback, type DocsFeedbackData, type DocsFeedbackProps, type DocsFeedbackValue, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FeedbackConfig, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, type HoverLinkProps, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageFrontmatter, Pre, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, type TypographyConfig, type UIConfig, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, withLangInUrl };
|
|
21
|
+
export { type AIConfig, Agent, type BreadcrumbConfig, type ChangelogConfig, type ChangelogFrontmatter, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CommandGridUIDefaults, ConcreteUIDefaults, type CopyMarkdownConfig, DocsBody, DocsClientHooks, DocsCommandSearch, type DocsConfig, DocsFeedback, type DocsFeedbackData, type DocsFeedbackProps, type DocsFeedbackValue, DocsLayout, type DocsMetadata, type DocsNav, DocsPage, DocsPageClient, type DocsTheme, type FeedbackConfig, type FontStyle, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, type HoverLinkProps, type OGConfig, type OpenDocsConfig, type OpenDocsProvider, PageActions, type PageActionsConfig, type PageFrontmatter, Pre, Prompt, type PromptProps, RootProvider, type SidebarConfig, Tab, Tabs, type ThemeToggleConfig, type TypographyConfig, type UIConfig, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, withLangInUrl };
|
package/dist/index.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import { ConcreteUIDefaults, concrete } from "./concrete/index.mjs";
|
|
|
11
11
|
import { HardlineUIDefaults, hardline } from "./hardline/index.mjs";
|
|
12
12
|
import { DocsClientHooks } from "./docs-client-hooks.mjs";
|
|
13
13
|
import { HoverLink } from "./hover-link.mjs";
|
|
14
|
+
import { Prompt } from "./prompt.mjs";
|
|
14
15
|
import { Agent } from "./mdx.mjs";
|
|
15
16
|
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
|
16
17
|
import { createTheme, deepMerge, defineDocs, extendTheme } from "@farming-labs/docs";
|
|
@@ -18,4 +19,4 @@ import { DocsBody, DocsPage } from "fumadocs-ui/layouts/docs/page";
|
|
|
18
19
|
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
|
19
20
|
import { CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, Pre } from "fumadocs-ui/components/codeblock";
|
|
20
21
|
|
|
21
|
-
export { Agent, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CommandGridUIDefaults, ConcreteUIDefaults, DocsBody, DocsClientHooks, DocsCommandSearch, DocsFeedback, DocsLayout, DocsPage, DocsPageClient, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, PageActions, Pre, RootProvider, Tab, Tabs, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, withLangInUrl };
|
|
22
|
+
export { Agent, CodeBlock, CodeBlockTab, CodeBlockTabs, CodeBlockTabsList, CodeBlockTabsTrigger, CommandGridUIDefaults, ConcreteUIDefaults, DocsBody, DocsClientHooks, DocsCommandSearch, DocsFeedback, DocsLayout, DocsPage, DocsPageClient, DefaultUIDefaults as FumadocsUIDefaults, HardlineUIDefaults, HoverLink, PageActions, Pre, Prompt, RootProvider, Tab, Tabs, commandGrid, concrete, createDocsLayout, createDocsMetadata, createPageMetadata, createTheme, deepMerge, defineDocs, extendTheme, fumadocs, hardline, withLangInUrl };
|
package/dist/mdx.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MDXImg } from "./mdx-img.mjs";
|
|
2
2
|
import { HoverLink } from "./hover-link.mjs";
|
|
3
|
+
import { Prompt, PromptIconValue, PromptOpenDocsProvider } from "./prompt.mjs";
|
|
3
4
|
import React from "react";
|
|
4
5
|
import { CodeBlockCopyData, DocsTheme } from "@farming-labs/docs";
|
|
5
6
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
@@ -21,6 +22,7 @@ declare const extendedMdxComponents: {
|
|
|
21
22
|
table: typeof Table;
|
|
22
23
|
Agent: typeof Agent;
|
|
23
24
|
HoverLink: typeof HoverLink;
|
|
25
|
+
Prompt: typeof Prompt;
|
|
24
26
|
Tab: typeof Tab;
|
|
25
27
|
Tabs: typeof Tabs;
|
|
26
28
|
CodeBlockTab: typeof fumadocs_ui_components_codeblock0.CodeBlockTab;
|
|
@@ -47,7 +49,11 @@ interface GetMDXComponentsOptions {
|
|
|
47
49
|
onCopyClick?: (data: CodeBlockCopyData) => void;
|
|
48
50
|
/** Theme config used to apply built-in MDX component defaults from `theme.ui.components`. */
|
|
49
51
|
theme?: DocsTheme;
|
|
52
|
+
/** Shared icon registry from `docs.config.ts[x]`. */
|
|
53
|
+
icons?: Record<string, PromptIconValue>;
|
|
54
|
+
/** Optional site-wide "Open in …" providers used by built-in components such as `Prompt`. */
|
|
55
|
+
openDocsProviders?: PromptOpenDocsProvider[];
|
|
50
56
|
}
|
|
51
57
|
declare function getMDXComponents<T extends Record<string, unknown> = Record<string, unknown>>(overrides?: T, options?: GetMDXComponentsOptions): typeof extendedMdxComponents & T;
|
|
52
58
|
//#endregion
|
|
53
|
-
export { Agent, GetMDXComponentsOptions, HoverLink, Tab, Tabs, defaultMdxComponents, extendedMdxComponents, getMDXComponents };
|
|
59
|
+
export { Agent, GetMDXComponentsOptions, HoverLink, Prompt, Tab, Tabs, defaultMdxComponents, extendedMdxComponents, getMDXComponents };
|
package/dist/mdx.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { MDXImg } from "./mdx-img.mjs";
|
|
2
2
|
import { createPreWithCopyCallback } from "./code-block-copy-wrapper.mjs";
|
|
3
3
|
import { HoverLink } from "./hover-link.mjs";
|
|
4
|
+
import { extractPromptText } from "./prompt-text.mjs";
|
|
5
|
+
import { Prompt } from "./prompt.mjs";
|
|
4
6
|
import React from "react";
|
|
5
7
|
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
|
6
8
|
import defaultMdxComponents from "fumadocs-ui/mdx";
|
|
@@ -36,17 +38,32 @@ const extendedMdxComponents = {
|
|
|
36
38
|
table: Table,
|
|
37
39
|
Agent,
|
|
38
40
|
HoverLink,
|
|
41
|
+
Prompt,
|
|
39
42
|
Tab,
|
|
40
43
|
Tabs
|
|
41
44
|
};
|
|
42
|
-
const mdxComponentDefaults = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const mdxComponentDefaults = {
|
|
46
|
+
HoverLink: {
|
|
47
|
+
linkLabel: "Open page",
|
|
48
|
+
showIndicator: false,
|
|
49
|
+
align: "center",
|
|
50
|
+
side: "bottom",
|
|
51
|
+
sideOffset: 12,
|
|
52
|
+
closeDelay: 90
|
|
53
|
+
},
|
|
54
|
+
Prompt: {
|
|
55
|
+
showTitle: true,
|
|
56
|
+
showDescription: true,
|
|
57
|
+
showPrompt: false,
|
|
58
|
+
actions: ["copy"],
|
|
59
|
+
copyLabel: "Copy prompt",
|
|
60
|
+
copiedLabel: "Copied",
|
|
61
|
+
openLabel: "Open in",
|
|
62
|
+
copyIcon: "copy",
|
|
63
|
+
copiedIcon: "check",
|
|
64
|
+
openIcon: "arrowUpRight"
|
|
65
|
+
}
|
|
66
|
+
};
|
|
50
67
|
function applyBuiltInComponentDefaults(options) {
|
|
51
68
|
const themeComponents = options?.theme?.ui?.components;
|
|
52
69
|
if (!themeComponents) return extendedMdxComponents;
|
|
@@ -57,9 +74,10 @@ function applyBuiltInComponentDefaults(options) {
|
|
|
57
74
|
const Component = components[name];
|
|
58
75
|
if (!Component) continue;
|
|
59
76
|
const builtInDefaults = mdxComponentDefaults[name] ?? {};
|
|
77
|
+
const configuredDefaults = value && typeof value === "object" ? value : {};
|
|
60
78
|
const componentDefaults = typeof value === "function" ? value(builtInDefaults) : {
|
|
61
79
|
...builtInDefaults,
|
|
62
|
-
...
|
|
80
|
+
...configuredDefaults
|
|
63
81
|
};
|
|
64
82
|
if (!componentDefaults || typeof componentDefaults !== "object") continue;
|
|
65
83
|
components[name] = function ThemedComponent(props) {
|
|
@@ -76,6 +94,19 @@ function getMDXComponents(overrides, options) {
|
|
|
76
94
|
...applyBuiltInComponentDefaults(options),
|
|
77
95
|
...overrides
|
|
78
96
|
};
|
|
97
|
+
if (base.Prompt) {
|
|
98
|
+
const DefaultPrompt = base.Prompt;
|
|
99
|
+
base.Prompt = function PromptWithDocsContext(props) {
|
|
100
|
+
const { children, ...rest } = props;
|
|
101
|
+
return React.createElement(DefaultPrompt, {
|
|
102
|
+
iconRegistry: options?.icons,
|
|
103
|
+
openDocsProviders: options?.openDocsProviders,
|
|
104
|
+
prompt: extractPromptText(children),
|
|
105
|
+
...rest,
|
|
106
|
+
children
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
}
|
|
79
110
|
if (options?.onCopyClick) {
|
|
80
111
|
const DefaultPre = base.pre;
|
|
81
112
|
if (DefaultPre) base.pre = createPreWithCopyCallback(DefaultPre, options.onCopyClick);
|
|
@@ -84,4 +115,4 @@ function getMDXComponents(overrides, options) {
|
|
|
84
115
|
}
|
|
85
116
|
|
|
86
117
|
//#endregion
|
|
87
|
-
export { Agent, HoverLink, Tab, Tabs, defaultMdxComponents, extendedMdxComponents, getMDXComponents };
|
|
118
|
+
export { Agent, HoverLink, Prompt, Tab, Tabs, defaultMdxComponents, extendedMdxComponents, getMDXComponents };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/prompt-text.ts
|
|
4
|
+
function extractPromptText(children) {
|
|
5
|
+
function inner(node) {
|
|
6
|
+
if (node == null || typeof node === "boolean") return "";
|
|
7
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
8
|
+
if (Array.isArray(node)) return node.map((child) => inner(child)).join("");
|
|
9
|
+
if (React.isValidElement(node)) {
|
|
10
|
+
const childText = inner(node.props.children);
|
|
11
|
+
if (node.type === "br") return "\n";
|
|
12
|
+
if (node.type === "li") return `- ${childText.trim()}\n`;
|
|
13
|
+
if (node.type === "p") return `${childText.trim()}\n\n`;
|
|
14
|
+
if (node.type === "ul" || node.type === "ol") return `${childText.trim()}\n`;
|
|
15
|
+
return childText;
|
|
16
|
+
}
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
return inner(children).replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n").replace(/[ \t]+\n/g, "\n").trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { extractPromptText };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/prompt.d.ts
|
|
5
|
+
type PromptAction = "copy" | "open";
|
|
6
|
+
type PromptIconValue = React.ReactNode | string;
|
|
7
|
+
interface PromptOpenDocsProvider {
|
|
8
|
+
name: string;
|
|
9
|
+
icon?: PromptIconValue;
|
|
10
|
+
urlTemplate: string;
|
|
11
|
+
promptUrlTemplate?: string;
|
|
12
|
+
}
|
|
13
|
+
interface PromptProps {
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
prompt?: string;
|
|
17
|
+
icon?: string;
|
|
18
|
+
showTitle?: boolean;
|
|
19
|
+
showDescription?: boolean;
|
|
20
|
+
showPrompt?: boolean;
|
|
21
|
+
actions?: PromptAction[] | string[];
|
|
22
|
+
providers?: string[] | string;
|
|
23
|
+
copyLabel?: string;
|
|
24
|
+
copiedLabel?: string;
|
|
25
|
+
openLabel?: string;
|
|
26
|
+
copyIcon?: string | false;
|
|
27
|
+
copiedIcon?: string | false;
|
|
28
|
+
openIcon?: string | false;
|
|
29
|
+
iconRegistry?: Record<string, PromptIconValue>;
|
|
30
|
+
openDocsProviders?: PromptOpenDocsProvider[];
|
|
31
|
+
}
|
|
32
|
+
declare function Prompt({
|
|
33
|
+
title,
|
|
34
|
+
description,
|
|
35
|
+
prompt,
|
|
36
|
+
icon,
|
|
37
|
+
showTitle,
|
|
38
|
+
showDescription,
|
|
39
|
+
showPrompt,
|
|
40
|
+
actions,
|
|
41
|
+
providers,
|
|
42
|
+
copyLabel,
|
|
43
|
+
copiedLabel,
|
|
44
|
+
openLabel,
|
|
45
|
+
copyIcon,
|
|
46
|
+
copiedIcon,
|
|
47
|
+
openIcon,
|
|
48
|
+
iconRegistry,
|
|
49
|
+
openDocsProviders,
|
|
50
|
+
children
|
|
51
|
+
}: React.PropsWithChildren<PromptProps>): react_jsx_runtime0.JSX.Element;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { Prompt, PromptIconValue, PromptOpenDocsProvider, PromptProps };
|
package/dist/prompt.mjs
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { extractPromptText } from "./prompt-text.mjs";
|
|
4
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/prompt.tsx
|
|
8
|
+
const builtInIcons = {
|
|
9
|
+
copy: /* @__PURE__ */ jsxs("svg", {
|
|
10
|
+
width: "14",
|
|
11
|
+
height: "14",
|
|
12
|
+
viewBox: "0 0 24 24",
|
|
13
|
+
fill: "none",
|
|
14
|
+
stroke: "currentColor",
|
|
15
|
+
strokeWidth: "2",
|
|
16
|
+
strokeLinecap: "round",
|
|
17
|
+
strokeLinejoin: "round",
|
|
18
|
+
children: [/* @__PURE__ */ jsx("rect", {
|
|
19
|
+
x: "9",
|
|
20
|
+
y: "9",
|
|
21
|
+
width: "13",
|
|
22
|
+
height: "13",
|
|
23
|
+
rx: "2",
|
|
24
|
+
ry: "2"
|
|
25
|
+
}), /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })]
|
|
26
|
+
}),
|
|
27
|
+
check: /* @__PURE__ */ jsx("svg", {
|
|
28
|
+
width: "14",
|
|
29
|
+
height: "14",
|
|
30
|
+
viewBox: "0 0 24 24",
|
|
31
|
+
fill: "none",
|
|
32
|
+
stroke: "currentColor",
|
|
33
|
+
strokeWidth: "2",
|
|
34
|
+
strokeLinecap: "round",
|
|
35
|
+
strokeLinejoin: "round",
|
|
36
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
37
|
+
}),
|
|
38
|
+
arrowUpRight: /* @__PURE__ */ jsxs("svg", {
|
|
39
|
+
width: "14",
|
|
40
|
+
height: "14",
|
|
41
|
+
viewBox: "0 0 24 24",
|
|
42
|
+
fill: "none",
|
|
43
|
+
stroke: "currentColor",
|
|
44
|
+
strokeWidth: "2",
|
|
45
|
+
strokeLinecap: "round",
|
|
46
|
+
strokeLinejoin: "round",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
|
|
49
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
50
|
+
/* @__PURE__ */ jsx("line", {
|
|
51
|
+
x1: "10",
|
|
52
|
+
y1: "14",
|
|
53
|
+
x2: "21",
|
|
54
|
+
y2: "3"
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
}),
|
|
58
|
+
chevronDown: /* @__PURE__ */ jsx("svg", {
|
|
59
|
+
width: "12",
|
|
60
|
+
height: "12",
|
|
61
|
+
viewBox: "0 0 24 24",
|
|
62
|
+
fill: "none",
|
|
63
|
+
stroke: "currentColor",
|
|
64
|
+
strokeWidth: "2",
|
|
65
|
+
strokeLinecap: "round",
|
|
66
|
+
strokeLinejoin: "round",
|
|
67
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
const defaultPromptProviderTemplates = {
|
|
71
|
+
chatgpt: "https://chatgpt.com/?q={prompt}",
|
|
72
|
+
claude: "https://claude.ai/new?q={prompt}",
|
|
73
|
+
cursor: "https://cursor.com/link/prompt?text={prompt}",
|
|
74
|
+
gemini: "https://gemini.google.com/app?q={prompt}",
|
|
75
|
+
copilot: "https://github.com/copilot?prompt={prompt}"
|
|
76
|
+
};
|
|
77
|
+
function normalizeProviderName(name) {
|
|
78
|
+
return name.trim().toLowerCase();
|
|
79
|
+
}
|
|
80
|
+
function parseStringArray(value) {
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
const normalized = value.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
|
|
83
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
84
|
+
}
|
|
85
|
+
if (typeof value !== "string") return void 0;
|
|
86
|
+
const trimmed = value.trim();
|
|
87
|
+
if (!trimmed) return void 0;
|
|
88
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
89
|
+
const normalized = trimmed.slice(1, -1).split(",").map((entry) => entry.trim().replace(/^['"]|['"]$/g, "")).filter(Boolean);
|
|
90
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
91
|
+
}
|
|
92
|
+
const normalized = trimmed.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
93
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
94
|
+
}
|
|
95
|
+
function resolveProviderChoices(availableProviders, preferredNames) {
|
|
96
|
+
const configuredByName = new Map((availableProviders ?? []).map((provider) => [normalizeProviderName(provider.name), provider]));
|
|
97
|
+
const names = preferredNames && preferredNames.length > 0 ? preferredNames : (availableProviders ?? []).map((provider) => provider.name);
|
|
98
|
+
const seen = /* @__PURE__ */ new Set();
|
|
99
|
+
const resolved = [];
|
|
100
|
+
for (const rawName of names) {
|
|
101
|
+
const name = rawName.trim();
|
|
102
|
+
if (!name) continue;
|
|
103
|
+
const normalized = normalizeProviderName(name);
|
|
104
|
+
if (seen.has(normalized)) continue;
|
|
105
|
+
seen.add(normalized);
|
|
106
|
+
const configured = configuredByName.get(normalized);
|
|
107
|
+
const template = configured?.promptUrlTemplate ?? configured?.urlTemplate ?? defaultPromptProviderTemplates[normalized];
|
|
108
|
+
if (!template) continue;
|
|
109
|
+
resolved.push({
|
|
110
|
+
name: configured?.name ?? name,
|
|
111
|
+
icon: configured?.icon,
|
|
112
|
+
urlTemplate: template
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return resolved;
|
|
116
|
+
}
|
|
117
|
+
function resolveActionIcon(name, iconRegistry) {
|
|
118
|
+
if (name === false) return null;
|
|
119
|
+
if (!name) return null;
|
|
120
|
+
const registryMatch = iconRegistry?.[name];
|
|
121
|
+
if (registryMatch) {
|
|
122
|
+
if (typeof registryMatch !== "string") return registryMatch;
|
|
123
|
+
}
|
|
124
|
+
if (name in builtInIcons) return builtInIcons[name];
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
async function fallbackCopyText(text) {
|
|
128
|
+
if (typeof document === "undefined") return false;
|
|
129
|
+
const textarea = document.createElement("textarea");
|
|
130
|
+
textarea.value = text;
|
|
131
|
+
textarea.setAttribute("readonly", "");
|
|
132
|
+
textarea.style.position = "fixed";
|
|
133
|
+
textarea.style.top = "0";
|
|
134
|
+
textarea.style.left = "0";
|
|
135
|
+
textarea.style.opacity = "0";
|
|
136
|
+
textarea.style.pointerEvents = "none";
|
|
137
|
+
document.body.appendChild(textarea);
|
|
138
|
+
textarea.focus();
|
|
139
|
+
textarea.select();
|
|
140
|
+
let copied = false;
|
|
141
|
+
try {
|
|
142
|
+
copied = document.execCommand("copy");
|
|
143
|
+
} catch {
|
|
144
|
+
copied = false;
|
|
145
|
+
} finally {
|
|
146
|
+
document.body.removeChild(textarea);
|
|
147
|
+
}
|
|
148
|
+
return copied;
|
|
149
|
+
}
|
|
150
|
+
function Prompt({ title, description, prompt, icon, showTitle = true, showDescription = true, showPrompt = false, actions, providers, copyLabel = "Copy prompt", copiedLabel = "Copied", openLabel = "Open in", copyIcon = "copy", copiedIcon = "check", openIcon = "arrowUpRight", iconRegistry, openDocsProviders, children }) {
|
|
151
|
+
const [copied, setCopied] = useState(false);
|
|
152
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
153
|
+
const dropdownRef = useRef(null);
|
|
154
|
+
const promptText = useMemo(() => typeof prompt === "string" && prompt.trim() ? prompt.trim() : extractPromptText(children), [prompt, children]);
|
|
155
|
+
const promptIconValue = icon && iconRegistry?.[icon] ? iconRegistry[icon] : void 0;
|
|
156
|
+
const promptIcon = promptIconValue && typeof promptIconValue !== "string" ? promptIconValue : null;
|
|
157
|
+
const resolvedActions = useMemo(() => parseStringArray(actions) ?? ["copy"], [actions]);
|
|
158
|
+
const resolvedProviders = useMemo(() => resolveProviderChoices(openDocsProviders, parseStringArray(providers)), [openDocsProviders, providers]);
|
|
159
|
+
const handleCopy = useCallback(async () => {
|
|
160
|
+
if (!promptText) return;
|
|
161
|
+
try {
|
|
162
|
+
if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) await navigator.clipboard.writeText(promptText);
|
|
163
|
+
else if (!await fallbackCopyText(promptText)) return;
|
|
164
|
+
setCopied(true);
|
|
165
|
+
window.setTimeout(() => setCopied(false), 2e3);
|
|
166
|
+
} catch {
|
|
167
|
+
if (!await fallbackCopyText(promptText)) return;
|
|
168
|
+
setCopied(true);
|
|
169
|
+
window.setTimeout(() => setCopied(false), 2e3);
|
|
170
|
+
}
|
|
171
|
+
}, [promptText]);
|
|
172
|
+
const handleOpen = useCallback((provider) => {
|
|
173
|
+
if (!promptText) return;
|
|
174
|
+
const targetUrl = provider.urlTemplate.replace(/\{prompt\}/g, encodeURIComponent(promptText));
|
|
175
|
+
window.open(targetUrl, "_blank", "noopener,noreferrer");
|
|
176
|
+
setMenuOpen(false);
|
|
177
|
+
}, [promptText]);
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
if (!menuOpen) return;
|
|
180
|
+
function handleOutsideClick(event) {
|
|
181
|
+
if (!dropdownRef.current) return;
|
|
182
|
+
if (!dropdownRef.current.contains(event.target)) setMenuOpen(false);
|
|
183
|
+
}
|
|
184
|
+
document.addEventListener("mousedown", handleOutsideClick);
|
|
185
|
+
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
186
|
+
}, [menuOpen]);
|
|
187
|
+
const showCopy = resolvedActions.includes("copy");
|
|
188
|
+
const showOpen = resolvedActions.includes("open") && resolvedProviders.length > 0;
|
|
189
|
+
const singleProvider = showOpen && resolvedProviders.length === 1 ? resolvedProviders[0] : null;
|
|
190
|
+
const visibleTitle = showTitle ? title : void 0;
|
|
191
|
+
const visibleDescription = showDescription ? description : void 0;
|
|
192
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
193
|
+
className: "fd-prompt",
|
|
194
|
+
"data-prompt-card": true,
|
|
195
|
+
children: [
|
|
196
|
+
(promptIcon || visibleTitle || visibleDescription) && /* @__PURE__ */ jsxs("div", {
|
|
197
|
+
className: "fd-prompt-header",
|
|
198
|
+
children: [promptIcon ? /* @__PURE__ */ jsx("span", {
|
|
199
|
+
className: "fd-prompt-icon",
|
|
200
|
+
children: promptIcon
|
|
201
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
202
|
+
className: "fd-prompt-copy",
|
|
203
|
+
children: [visibleTitle && /* @__PURE__ */ jsx("p", {
|
|
204
|
+
className: "fd-prompt-title",
|
|
205
|
+
children: visibleTitle
|
|
206
|
+
}), visibleDescription && /* @__PURE__ */ jsx("p", {
|
|
207
|
+
className: "fd-prompt-description",
|
|
208
|
+
children: visibleDescription
|
|
209
|
+
})]
|
|
210
|
+
})]
|
|
211
|
+
}),
|
|
212
|
+
showPrompt && promptText && /* @__PURE__ */ jsx("div", {
|
|
213
|
+
className: "fd-prompt-body",
|
|
214
|
+
children: /* @__PURE__ */ jsx("pre", {
|
|
215
|
+
className: "fd-prompt-code",
|
|
216
|
+
children: promptText
|
|
217
|
+
})
|
|
218
|
+
}),
|
|
219
|
+
(showCopy || showOpen) && /* @__PURE__ */ jsxs("div", {
|
|
220
|
+
className: "fd-prompt-actions",
|
|
221
|
+
children: [
|
|
222
|
+
showCopy && /* @__PURE__ */ jsxs("button", {
|
|
223
|
+
type: "button",
|
|
224
|
+
className: "fd-prompt-action-btn",
|
|
225
|
+
"data-copied": copied,
|
|
226
|
+
onClick: handleCopy,
|
|
227
|
+
children: [copied ? resolveActionIcon(copiedIcon, iconRegistry) : resolveActionIcon(copyIcon, iconRegistry), /* @__PURE__ */ jsx("span", { children: copied ? copiedLabel : copyLabel })]
|
|
228
|
+
}),
|
|
229
|
+
singleProvider ? /* @__PURE__ */ jsxs("button", {
|
|
230
|
+
type: "button",
|
|
231
|
+
className: "fd-prompt-action-btn",
|
|
232
|
+
onClick: () => handleOpen(singleProvider),
|
|
233
|
+
children: [resolveActionIcon(openIcon, iconRegistry), /* @__PURE__ */ jsxs("span", { children: [
|
|
234
|
+
openLabel,
|
|
235
|
+
" ",
|
|
236
|
+
singleProvider.name
|
|
237
|
+
] })]
|
|
238
|
+
}) : null,
|
|
239
|
+
!singleProvider && showOpen ? /* @__PURE__ */ jsxs("div", {
|
|
240
|
+
ref: dropdownRef,
|
|
241
|
+
className: "fd-prompt-dropdown",
|
|
242
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
243
|
+
type: "button",
|
|
244
|
+
className: "fd-prompt-action-btn",
|
|
245
|
+
"aria-expanded": menuOpen,
|
|
246
|
+
onClick: () => setMenuOpen((current) => !current),
|
|
247
|
+
children: [
|
|
248
|
+
resolveActionIcon(openIcon, iconRegistry),
|
|
249
|
+
/* @__PURE__ */ jsx("span", { children: openLabel }),
|
|
250
|
+
builtInIcons.chevronDown
|
|
251
|
+
]
|
|
252
|
+
}), menuOpen && /* @__PURE__ */ jsx("div", {
|
|
253
|
+
className: "fd-prompt-menu",
|
|
254
|
+
role: "menu",
|
|
255
|
+
children: resolvedProviders.map((provider) => /* @__PURE__ */ jsxs("button", {
|
|
256
|
+
type: "button",
|
|
257
|
+
role: "menuitem",
|
|
258
|
+
className: "fd-prompt-menu-item",
|
|
259
|
+
onClick: () => handleOpen(provider),
|
|
260
|
+
children: [provider.icon && typeof provider.icon !== "string" ? /* @__PURE__ */ jsx("span", {
|
|
261
|
+
className: "fd-prompt-menu-icon",
|
|
262
|
+
children: provider.icon
|
|
263
|
+
}) : null, /* @__PURE__ */ jsxs("span", {
|
|
264
|
+
className: "fd-prompt-menu-label",
|
|
265
|
+
children: [
|
|
266
|
+
openLabel,
|
|
267
|
+
" ",
|
|
268
|
+
provider.name
|
|
269
|
+
]
|
|
270
|
+
})]
|
|
271
|
+
}, provider.name))
|
|
272
|
+
})]
|
|
273
|
+
}) : null
|
|
274
|
+
]
|
|
275
|
+
})
|
|
276
|
+
]
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
//#endregion
|
|
281
|
+
export { Prompt };
|
package/dist/tanstack-layout.mjs
CHANGED
|
@@ -238,7 +238,7 @@ function TanstackDocsLayout({ config, tree, locale, description, readingTime, la
|
|
|
238
238
|
const llmsTxtEnabled = resolveBool(config.llmsTxt);
|
|
239
239
|
const feedbackConfig = resolveFeedbackConfig(config.feedback);
|
|
240
240
|
const staticExport = !!config.staticExport;
|
|
241
|
-
const openDocsProviders = (typeof pageActions
|
|
241
|
+
const openDocsProviders = (pageActions?.openDocs && typeof pageActions.openDocs === "object" && pageActions.openDocs.providers ? pageActions.openDocs.providers : void 0)?.map((provider) => ({
|
|
242
242
|
name: provider.name,
|
|
243
243
|
urlTemplate: provider.urlTemplate
|
|
244
244
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/theme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.59",
|
|
4
4
|
"description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"tsdown": "^0.20.3",
|
|
134
134
|
"typescript": "^5.9.3",
|
|
135
135
|
"vitest": "^3.2.4",
|
|
136
|
-
"@farming-labs/docs": "0.1.
|
|
136
|
+
"@farming-labs/docs": "0.1.59"
|
|
137
137
|
},
|
|
138
138
|
"peerDependencies": {
|
|
139
139
|
"@farming-labs/docs": ">=0.0.1",
|
package/styles/base.css
CHANGED
|
@@ -422,12 +422,12 @@ figure.shiki:has(figcaption) figcaption {
|
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
-
.fd-page-action-menu-item
|
|
425
|
+
.fd-page-action-menu-item,
|
|
426
|
+
.fd-prompt-menu-item {
|
|
426
427
|
display: flex;
|
|
427
428
|
align-items: center;
|
|
428
429
|
gap: 0.5rem;
|
|
429
430
|
width: 100%;
|
|
430
|
-
padding: 0.2rem 0.625rem;
|
|
431
431
|
font-size: 0.8125rem;
|
|
432
432
|
font-weight: 400;
|
|
433
433
|
color: var(--color-fd-popover-foreground);
|
|
@@ -441,9 +441,8 @@ figure.shiki:has(figcaption) figcaption {
|
|
|
441
441
|
color 0.1s;
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
.fd-page-action-menu-item
|
|
445
|
-
|
|
446
|
-
color: var(--color-fd-accent-foreground);
|
|
444
|
+
.fd-page-action-menu-item {
|
|
445
|
+
padding: 0.2rem 0.625rem;
|
|
447
446
|
}
|
|
448
447
|
|
|
449
448
|
.fd-page-action-menu-icon {
|
|
@@ -464,6 +463,177 @@ figure.shiki:has(figcaption) figcaption {
|
|
|
464
463
|
flex: 1;
|
|
465
464
|
}
|
|
466
465
|
|
|
466
|
+
/* ─── Prompt Cards ─────────────────────────────────────────────────── */
|
|
467
|
+
|
|
468
|
+
.fd-prompt {
|
|
469
|
+
display: flex;
|
|
470
|
+
flex-direction: column;
|
|
471
|
+
gap: 0.875rem;
|
|
472
|
+
margin: 1.25rem 0;
|
|
473
|
+
padding: 1rem;
|
|
474
|
+
border: 1px solid var(--color-fd-border);
|
|
475
|
+
border-radius: 0.75rem;
|
|
476
|
+
background: color-mix(in srgb, var(--color-fd-card) 78%, transparent);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.fd-prompt-header {
|
|
480
|
+
display: flex;
|
|
481
|
+
align-items: flex-start;
|
|
482
|
+
gap: 0.75rem;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.fd-prompt-icon,
|
|
486
|
+
.fd-prompt-action-icon,
|
|
487
|
+
.fd-prompt-menu-icon {
|
|
488
|
+
display: inline-flex;
|
|
489
|
+
align-items: center;
|
|
490
|
+
justify-content: center;
|
|
491
|
+
flex-shrink: 0;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.fd-prompt-icon {
|
|
495
|
+
width: 1.75rem;
|
|
496
|
+
height: 1.75rem;
|
|
497
|
+
border-radius: 0.5rem;
|
|
498
|
+
border: 1px solid color-mix(in srgb, var(--color-fd-border) 80%, transparent);
|
|
499
|
+
background: color-mix(in srgb, var(--color-fd-background) 55%, transparent);
|
|
500
|
+
color: var(--color-fd-foreground);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.fd-prompt-icon svg,
|
|
504
|
+
.fd-prompt-action-icon svg,
|
|
505
|
+
.fd-prompt-menu-icon svg {
|
|
506
|
+
width: 1rem;
|
|
507
|
+
height: 1rem;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
.fd-prompt-copy {
|
|
511
|
+
min-width: 0;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.fd-prompt-title {
|
|
515
|
+
margin: 0;
|
|
516
|
+
color: var(--color-fd-foreground);
|
|
517
|
+
font-size: 0.9375rem;
|
|
518
|
+
font-weight: 600;
|
|
519
|
+
line-height: 1.35;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.fd-prompt-description {
|
|
523
|
+
margin: 0.25rem 0 0;
|
|
524
|
+
color: var(--color-fd-muted-foreground);
|
|
525
|
+
font-size: 0.875rem;
|
|
526
|
+
line-height: 1.55;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.fd-prompt-body {
|
|
530
|
+
margin: 0;
|
|
531
|
+
padding: 0.875rem 1rem;
|
|
532
|
+
border-radius: 0.625rem;
|
|
533
|
+
border: 1px solid color-mix(in srgb, var(--color-fd-border) 82%, transparent);
|
|
534
|
+
background: color-mix(in srgb, var(--color-fd-background) 45%, transparent);
|
|
535
|
+
overflow-x: auto;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.fd-prompt-body > pre.fd-prompt-code {
|
|
539
|
+
margin: 0;
|
|
540
|
+
padding: 0 !important;
|
|
541
|
+
border: 0 !important;
|
|
542
|
+
border-radius: 0 !important;
|
|
543
|
+
background: transparent !important;
|
|
544
|
+
box-shadow: none !important;
|
|
545
|
+
color: var(--color-fd-foreground);
|
|
546
|
+
font-size: 0.875rem;
|
|
547
|
+
line-height: 1.65;
|
|
548
|
+
white-space: pre-wrap;
|
|
549
|
+
word-break: break-word;
|
|
550
|
+
font-family: var(
|
|
551
|
+
--fd-font-mono,
|
|
552
|
+
ui-monospace,
|
|
553
|
+
"SF Mono",
|
|
554
|
+
SFMono-Regular,
|
|
555
|
+
Menlo,
|
|
556
|
+
Consolas,
|
|
557
|
+
monospace
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
.fd-prompt-actions {
|
|
562
|
+
display: flex;
|
|
563
|
+
flex-wrap: wrap;
|
|
564
|
+
gap: 0.5rem;
|
|
565
|
+
align-items: center;
|
|
566
|
+
justify-content: flex-end;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.fd-prompt-action-btn {
|
|
570
|
+
display: inline-flex;
|
|
571
|
+
align-items: center;
|
|
572
|
+
gap: 0.4375rem;
|
|
573
|
+
min-height: 2rem;
|
|
574
|
+
padding: 0.375rem 0.75rem;
|
|
575
|
+
border: 1px solid var(--color-fd-border);
|
|
576
|
+
border-radius: 0.375rem;
|
|
577
|
+
background: var(--color-fd-secondary);
|
|
578
|
+
color: var(--color-fd-muted-foreground);
|
|
579
|
+
font-size: 0.8125rem;
|
|
580
|
+
font-weight: 500;
|
|
581
|
+
line-height: 1;
|
|
582
|
+
cursor: pointer;
|
|
583
|
+
transition:
|
|
584
|
+
color 0.15s,
|
|
585
|
+
background 0.15s,
|
|
586
|
+
border-color 0.15s;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.fd-prompt-action-btn:hover {
|
|
590
|
+
color: var(--color-fd-accent-foreground);
|
|
591
|
+
background: var(--color-fd-accent);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.fd-prompt-action-btn[data-copied="true"] {
|
|
595
|
+
color: var(--color-fd-foreground);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.fd-prompt-action-icon-copied[hidden] {
|
|
599
|
+
display: none;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.fd-prompt-dropdown {
|
|
603
|
+
position: relative;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.fd-prompt-menu {
|
|
607
|
+
position: absolute;
|
|
608
|
+
top: calc(100% + 0.375rem);
|
|
609
|
+
right: 0;
|
|
610
|
+
z-index: 50;
|
|
611
|
+
min-width: 220px;
|
|
612
|
+
padding: 0.375rem;
|
|
613
|
+
background: var(--color-fd-popover);
|
|
614
|
+
border: 1px solid var(--color-fd-border);
|
|
615
|
+
border-radius: 0.5rem;
|
|
616
|
+
box-shadow: 0 4px 24px hsl(0 0% 0% / 0.15);
|
|
617
|
+
display: flex;
|
|
618
|
+
flex-direction: column;
|
|
619
|
+
gap: 0.125rem;
|
|
620
|
+
animation: fd-page-actions-fade-in 0.12s ease-out;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
.fd-prompt-menu-item {
|
|
624
|
+
padding: 0.25rem 0.625rem;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.fd-page-action-menu-item:hover,
|
|
628
|
+
.fd-prompt-menu-item:hover {
|
|
629
|
+
background: var(--color-fd-accent);
|
|
630
|
+
color: var(--color-fd-accent-foreground);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.fd-prompt-menu-label {
|
|
634
|
+
flex: 1;
|
|
635
|
+
}
|
|
636
|
+
|
|
467
637
|
/* ─── Docs Feedback ────────────────────────────────────────────────── */
|
|
468
638
|
|
|
469
639
|
.fd-feedback {
|
package/styles/pixel-border.css
CHANGED
|
@@ -529,6 +529,68 @@ hr {
|
|
|
529
529
|
font-family: var(--fd-font-mono, var(--font-geist-mono, ui-monospace, monospace)) !important;
|
|
530
530
|
}
|
|
531
531
|
|
|
532
|
+
/* ─── Prompt (pixel-border overrides) ────────────────────────────── */
|
|
533
|
+
|
|
534
|
+
.fd-prompt {
|
|
535
|
+
border-radius: 0 !important;
|
|
536
|
+
border: 1px solid var(--color-fd-border, #262626) !important;
|
|
537
|
+
background: var(--color-fd-card, var(--color-fd-background)) !important;
|
|
538
|
+
box-shadow: 4px 4px 0 0 var(--color-fd-border, #262626) !important;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.fd-prompt-body {
|
|
542
|
+
border-radius: 0 !important;
|
|
543
|
+
border-top: 1px solid var(--color-fd-border, #262626) !important;
|
|
544
|
+
background: var(--color-fd-background, #0c0c0c) !important;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.fd-prompt-action-btn {
|
|
548
|
+
border-radius: 0 !important;
|
|
549
|
+
font-size: 0.75rem !important;
|
|
550
|
+
letter-spacing: 0.03em !important;
|
|
551
|
+
text-transform: uppercase !important;
|
|
552
|
+
box-shadow: 2px 2px 0 0 var(--color-fd-border, #262626) !important;
|
|
553
|
+
font-family: var(--fd-font-mono, var(--font-geist-mono, ui-monospace, monospace)) !important;
|
|
554
|
+
background: var(--color-fd-background, #0c0c0c) !important;
|
|
555
|
+
color: var(--color-fd-foreground, inherit) !important;
|
|
556
|
+
border: 1px solid var(--color-fd-border, #262626) !important;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
.fd-prompt-action-btn:hover {
|
|
560
|
+
background: var(--color-fd-muted, var(--color-fd-accent)) !important;
|
|
561
|
+
color: var(--color-fd-foreground, inherit) !important;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.fd-prompt-menu {
|
|
565
|
+
border-radius: 0 !important;
|
|
566
|
+
box-shadow:
|
|
567
|
+
4px 4px 0 0 var(--color-fd-border, #262626),
|
|
568
|
+
0 4px 24px hsl(0 0% 0% / 0.5) !important;
|
|
569
|
+
background: var(--color-fd-popover, var(--color-fd-background)) !important;
|
|
570
|
+
border: 2px solid var(--color-fd-border, #262626) !important;
|
|
571
|
+
padding: 0.375rem !important;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.fd-prompt-menu-item {
|
|
575
|
+
border-radius: 0 !important;
|
|
576
|
+
font-size: 0.8rem !important;
|
|
577
|
+
letter-spacing: 0.03em !important;
|
|
578
|
+
text-transform: uppercase !important;
|
|
579
|
+
color: var(--color-fd-popover-foreground, var(--color-fd-foreground)) !important;
|
|
580
|
+
font-family: var(--fd-font-mono, var(--font-geist-mono, ui-monospace, monospace)) !important;
|
|
581
|
+
background: transparent !important;
|
|
582
|
+
border-top: 1px solid var(--color-fd-border, #262626) !important;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
.fd-prompt-menu-item:first-child {
|
|
586
|
+
border-top: none !important;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.fd-prompt-menu-item:hover {
|
|
590
|
+
background: var(--color-fd-muted, var(--color-fd-accent)) !important;
|
|
591
|
+
color: var(--color-fd-foreground, inherit) !important;
|
|
592
|
+
}
|
|
593
|
+
|
|
532
594
|
/* model selector */
|
|
533
595
|
.fd-ai-model-select-row {
|
|
534
596
|
display: flex;
|