@agentaily/design-system 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +58 -7
- package/README.md +10 -6
- package/dist/components/ai/Confirmation.js +58 -22
- package/dist/components/ai/Confirmation.js.map +1 -1
- package/dist/components/ai/Queue.d.ts +23 -0
- package/dist/components/ai/Queue.js +52 -1
- package/dist/components/ai/Queue.js.map +1 -1
- package/dist/components/ai/ToolCall.js +69 -30
- package/dist/components/ai/ToolCall.js.map +1 -1
- package/dist/components/auth/AccountControl.d.ts +23 -0
- package/dist/components/auth/AccountControl.js +47 -0
- package/dist/components/auth/AccountControl.js.map +1 -0
- package/dist/components/auth/AuthDialog.d.ts +39 -0
- package/dist/components/auth/AuthDialog.js +327 -0
- package/dist/components/auth/AuthDialog.js.map +1 -0
- package/dist/components/auth/SignInPage.d.ts +48 -0
- package/dist/components/auth/SignInPage.js +217 -0
- package/dist/components/auth/SignInPage.js.map +1 -0
- package/dist/components/chat/CodeBlock.js +3 -2
- package/dist/components/chat/CodeBlock.js.map +1 -1
- package/dist/components/chat/ConversationThread.d.ts +67 -0
- package/dist/components/chat/ConversationThread.js +129 -0
- package/dist/components/chat/ConversationThread.js.map +1 -0
- package/dist/components/code/Artifact.js +44 -9
- package/dist/components/code/Artifact.js.map +1 -1
- package/dist/components/code/JSXPreview.js +19 -12
- package/dist/components/code/JSXPreview.js.map +1 -1
- package/dist/components/code/Snippet.js +2 -2
- package/dist/components/code/Snippet.js.map +1 -1
- package/dist/components/code/Terminal.js +24 -10
- package/dist/components/code/Terminal.js.map +1 -1
- package/dist/components/code/WebPreview.js +44 -10
- package/dist/components/code/WebPreview.js.map +1 -1
- package/dist/components/display/Skeleton.js +17 -4
- package/dist/components/display/Skeleton.js.map +1 -1
- package/dist/components/display/StatusPill.d.ts +12 -0
- package/dist/components/display/StatusPill.js +17 -0
- package/dist/components/display/StatusPill.js.map +1 -0
- package/dist/components/inputs/Form.d.ts +164 -0
- package/dist/components/inputs/Form.js +484 -0
- package/dist/components/inputs/Form.js.map +1 -0
- package/dist/components/inputs/Input.d.ts +2 -0
- package/dist/components/inputs/Input.js +14 -10
- package/dist/components/inputs/Input.js.map +1 -1
- package/dist/components/inputs/SecretField.d.ts +21 -0
- package/dist/components/inputs/SecretField.js +70 -0
- package/dist/components/inputs/SecretField.js.map +1 -0
- package/dist/components/layout/AppShell.d.ts +30 -0
- package/dist/components/layout/AppShell.js +117 -0
- package/dist/components/layout/AppShell.js.map +1 -0
- package/dist/components/layout/DesignerShell.d.ts +39 -0
- package/dist/components/layout/DesignerShell.js +146 -0
- package/dist/components/layout/DesignerShell.js.map +1 -0
- package/dist/components/layout/DocsLayout.d.ts +24 -0
- package/dist/components/layout/DocsLayout.js +113 -0
- package/dist/components/layout/DocsLayout.js.map +1 -0
- package/dist/components/layout/SettingsPage.d.ts +31 -0
- package/dist/components/layout/SettingsPage.js +92 -0
- package/dist/components/layout/SettingsPage.js.map +1 -0
- package/dist/components/review/MarkupLayer.d.ts +20 -0
- package/dist/components/review/MarkupLayer.js +237 -0
- package/dist/components/review/MarkupLayer.js.map +1 -0
- package/dist/components/settings/HelpSteps.d.ts +20 -0
- package/dist/components/settings/HelpSteps.js +40 -0
- package/dist/components/settings/HelpSteps.js.map +1 -0
- package/dist/components/settings/IntegrationSettings.d.ts +15 -0
- package/dist/components/settings/IntegrationSettings.js +630 -0
- package/dist/components/settings/IntegrationSettings.js.map +1 -0
- package/dist/components/settings/TestRow.d.ts +21 -0
- package/dist/components/settings/TestRow.js +66 -0
- package/dist/components/settings/TestRow.js.map +1 -0
- package/dist/components/utilities/BrandMark.d.ts +17 -0
- package/dist/components/utilities/BrandMark.js +43 -0
- package/dist/components/utilities/BrandMark.js.map +1 -0
- package/dist/components/utilities/Icon.d.ts +28 -0
- package/dist/components/utilities/Icon.js +196 -0
- package/dist/components/utilities/Icon.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/dist/styles.css +67 -64
- package/package.json +2 -2
|
@@ -4,8 +4,8 @@ const AX_JSXPREVIEW_CSS = `
|
|
|
4
4
|
.ax-jsxpreview { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--border-default); border-radius: var(--radius-3); overflow: hidden; }
|
|
5
5
|
.ax-jsxpreview--stacked { grid-template-columns: 1fr; }
|
|
6
6
|
.ax-jsxpreview__pane { min-width: 0; }
|
|
7
|
-
.ax-jsxpreview__pane--code { border-right: 1px solid var(--border-default); background: var(--bg-
|
|
8
|
-
[data-theme="
|
|
7
|
+
.ax-jsxpreview__pane--code { border-right: 1px solid var(--border-default); background: var(--bg-1); }
|
|
8
|
+
[data-theme="dark"] .ax-jsxpreview__pane--code { background: var(--bg-0); }
|
|
9
9
|
.ax-jsxpreview--stacked .ax-jsxpreview__pane--code { border-right: none; border-bottom: 1px solid var(--border-default); }
|
|
10
10
|
.ax-jsxpreview__label { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-faint); padding: 8px 12px; border-bottom: 1px solid var(--border-default); }
|
|
11
11
|
.ax-jsxpreview__pre { margin: 0; padding: 12px; font-family: var(--font-mono); font-size: var(--text-xs); line-height: 1.6; color: var(--text-body); white-space: pre; overflow-x: auto; }
|
|
@@ -18,16 +18,23 @@ if (typeof document !== "undefined" && !document.getElementById("ax-jsxpreview-c
|
|
|
18
18
|
document.head.appendChild(s);
|
|
19
19
|
}
|
|
20
20
|
function JSXPreview({ code, children, stacked = false, className = "", ...rest }) {
|
|
21
|
-
return /* @__PURE__ */ jsxs(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
return /* @__PURE__ */ jsxs(
|
|
22
|
+
"div",
|
|
23
|
+
{
|
|
24
|
+
className: ["ax-jsxpreview", stacked ? "ax-jsxpreview--stacked" : "", className].filter(Boolean).join(" "),
|
|
25
|
+
...rest,
|
|
26
|
+
children: [
|
|
27
|
+
/* @__PURE__ */ jsxs("div", { className: "ax-jsxpreview__pane ax-jsxpreview__pane--code", children: [
|
|
28
|
+
/* @__PURE__ */ jsx("div", { className: "ax-jsxpreview__label", children: "JSX" }),
|
|
29
|
+
/* @__PURE__ */ jsx("pre", { className: "ax-jsxpreview__pre", children: code })
|
|
30
|
+
] }),
|
|
31
|
+
/* @__PURE__ */ jsxs("div", { className: "ax-jsxpreview__pane", children: [
|
|
32
|
+
/* @__PURE__ */ jsx("div", { className: "ax-jsxpreview__label", children: "Preview" }),
|
|
33
|
+
/* @__PURE__ */ jsx("div", { className: "ax-jsxpreview__render", children })
|
|
34
|
+
] })
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
);
|
|
31
38
|
}
|
|
32
39
|
export {
|
|
33
40
|
JSXPreview
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSXPreview.js","sources":["../../../src/components/code/JSXPreview.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_JSXPREVIEW_CSS = `\n.ax-jsxpreview { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--border-default); border-radius: var(--radius-3); overflow: hidden; }\n.ax-jsxpreview--stacked { grid-template-columns: 1fr; }\n.ax-jsxpreview__pane { min-width: 0; }\n.ax-jsxpreview__pane--code { border-right: 1px solid var(--border-default); background: var(--bg-
|
|
1
|
+
{"version":3,"file":"JSXPreview.js","sources":["../../../src/components/code/JSXPreview.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_JSXPREVIEW_CSS = `\n.ax-jsxpreview { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--border-default); border-radius: var(--radius-3); overflow: hidden; }\n.ax-jsxpreview--stacked { grid-template-columns: 1fr; }\n.ax-jsxpreview__pane { min-width: 0; }\n.ax-jsxpreview__pane--code { border-right: 1px solid var(--border-default); background: var(--bg-1); }\n[data-theme=\"dark\"] .ax-jsxpreview__pane--code { background: var(--bg-0); }\n.ax-jsxpreview--stacked .ax-jsxpreview__pane--code { border-right: none; border-bottom: 1px solid var(--border-default); }\n.ax-jsxpreview__label { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--text-faint); padding: 8px 12px; border-bottom: 1px solid var(--border-default); }\n.ax-jsxpreview__pre { margin: 0; padding: 12px; font-family: var(--font-mono); font-size: var(--text-xs); line-height: 1.6; color: var(--text-body); white-space: pre; overflow-x: auto; }\n.ax-jsxpreview__render { padding: 20px; display: flex; align-items: center; justify-content: center; min-height: 100px; background: var(--surface-card); }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-jsxpreview-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-jsxpreview-css\";\n s.textContent = AX_JSXPREVIEW_CSS;\n document.head.appendChild(s);\n}\n\nexport function JSXPreview({ code, children, stacked = false, className = \"\", ...rest }) {\n return (\n <div\n className={[\"ax-jsxpreview\", stacked ? \"ax-jsxpreview--stacked\" : \"\", className]\n .filter(Boolean)\n .join(\" \")}\n {...rest}\n >\n <div className=\"ax-jsxpreview__pane ax-jsxpreview__pane--code\">\n <div className=\"ax-jsxpreview__label\">JSX</div>\n <pre className=\"ax-jsxpreview__pre\">{code}</pre>\n </div>\n <div className=\"ax-jsxpreview__pane\">\n <div className=\"ax-jsxpreview__label\">Preview</div>\n <div className=\"ax-jsxpreview__render\">{children}</div>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;AAEA,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY1B,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,mBAAmB,GAAG;AACpF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,WAAW,EAAE,MAAM,UAAU,UAAU,OAAO,YAAY,IAAI,GAAG,QAAQ;AACvF,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,CAAC,iBAAiB,UAAU,2BAA2B,IAAI,SAAS,EAC5E,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACV,GAAG;AAAA,MAEJ,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,iDACb,UAAA;AAAA,UAAA,oBAAC,OAAA,EAAI,WAAU,wBAAuB,UAAA,OAAG;AAAA,UACzC,oBAAC,OAAA,EAAI,WAAU,sBAAsB,UAAA,KAAA,CAAK;AAAA,QAAA,GAC5C;AAAA,QACA,qBAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,UAAA,oBAAC,OAAA,EAAI,WAAU,wBAAuB,UAAA,WAAO;AAAA,UAC7C,oBAAC,OAAA,EAAI,WAAU,yBAAyB,SAAA,CAAS;AAAA,QAAA,EAAA,CACnD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
const AX_SNIPPET_CSS = `
|
|
4
|
-
.ax-snippet { display: flex; align-items: center; gap: 8px; background: var(--bg-
|
|
5
|
-
[data-theme="
|
|
4
|
+
.ax-snippet { display: flex; align-items: center; gap: 8px; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-2); padding: 6px 6px 6px 12px; font-family: var(--font-mono); }
|
|
5
|
+
[data-theme="dark"] .ax-snippet { background: var(--bg-0); }
|
|
6
6
|
.ax-snippet__prompt { color: var(--text-faint); user-select: none; }
|
|
7
7
|
.ax-snippet__code { flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap; font-size: var(--text-sm); color: var(--text-body); }
|
|
8
8
|
.ax-snippet__copy { appearance: none; background: none; border: 1px solid var(--border-default); cursor: pointer; color: var(--text-faint); font-family: var(--font-mono); font-size: 11px; padding: 4px 8px; border-radius: var(--radius-1); flex: none; transition: color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snippet.js","sources":["../../../src/components/code/Snippet.jsx"],"sourcesContent":["import React, { useState } from \"react\";\n\nconst AX_SNIPPET_CSS = `\n.ax-snippet { display: flex; align-items: center; gap: 8px; background: var(--bg-
|
|
1
|
+
{"version":3,"file":"Snippet.js","sources":["../../../src/components/code/Snippet.jsx"],"sourcesContent":["import React, { useState } from \"react\";\n\nconst AX_SNIPPET_CSS = `\n.ax-snippet { display: flex; align-items: center; gap: 8px; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-2); padding: 6px 6px 6px 12px; font-family: var(--font-mono); }\n[data-theme=\"dark\"] .ax-snippet { background: var(--bg-0); }\n.ax-snippet__prompt { color: var(--text-faint); user-select: none; }\n.ax-snippet__code { flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap; font-size: var(--text-sm); color: var(--text-body); }\n.ax-snippet__copy { appearance: none; background: none; border: 1px solid var(--border-default); cursor: pointer; color: var(--text-faint); font-family: var(--font-mono); font-size: 11px; padding: 4px 8px; border-radius: var(--radius-1); flex: none; transition: color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out); }\n.ax-snippet__copy:hover { color: var(--text-body); border-color: var(--border-strong); }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-snippet-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-snippet-css\";\n s.textContent = AX_SNIPPET_CSS;\n document.head.appendChild(s);\n}\n\nexport function Snippet({ code = \"\", prompt = \"$\", className = \"\", ...rest }) {\n const [copied, setCopied] = useState(false);\n const copy = () => {\n try {\n navigator.clipboard && navigator.clipboard.writeText(code);\n } catch (e) {}\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n return (\n <div className={[\"ax-snippet\", className].filter(Boolean).join(\" \")} {...rest}>\n {prompt ? <span className=\"ax-snippet__prompt\">{prompt}</span> : null}\n <code className=\"ax-snippet__code\">{code}</code>\n <button className=\"ax-snippet__copy\" onClick={copy}>\n {copied ? \"✓\" : \"copy\"}\n </button>\n </div>\n );\n}\n"],"names":[],"mappings":";;AAEA,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASvB,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,gBAAgB,GAAG;AACjF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,QAAQ,EAAE,OAAO,IAAI,SAAS,KAAK,YAAY,IAAI,GAAG,QAAQ;AAC5E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,gBAAU,aAAa,UAAU,UAAU,UAAU,IAAI;AAAA,IAC3D,SAAS,GAAG;AAAA,IAAC;AACb,cAAU,IAAI;AACd,eAAW,MAAM,UAAU,KAAK,GAAG,IAAI;AAAA,EACzC;AACA,SACE,qBAAC,OAAA,EAAI,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACtE,UAAA;AAAA,IAAA,SAAS,oBAAC,QAAA,EAAK,WAAU,sBAAsB,kBAAO,IAAU;AAAA,IACjE,oBAAC,QAAA,EAAK,WAAU,oBAAoB,UAAA,MAAK;AAAA,IACzC,oBAAC,YAAO,WAAU,oBAAmB,SAAS,MAC3C,UAAA,SAAS,MAAM,OAAA,CAClB;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
const AX_TERMINAL_CSS = `
|
|
4
|
-
.ax-terminal { border: 1px solid var(--border-strong); border-radius: var(--radius-3); overflow: hidden; background:
|
|
5
|
-
|
|
6
|
-
.ax-terminal__bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--bg-1); border-bottom: 1px solid var(--border-default); }
|
|
7
|
-
[data-theme="light"] .ax-terminal__bar { background: #18181B; border-color: rgba(255,255,255,0.1); }
|
|
4
|
+
.ax-terminal { border: 1px solid var(--border-strong); border-radius: var(--radius-3); overflow: hidden; background: #0A0A0B; font-family: var(--font-mono); }
|
|
5
|
+
.ax-terminal__bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #18181B; border-bottom: 1px solid rgba(255,255,255,0.1); }
|
|
8
6
|
.ax-terminal__dots { display: flex; gap: 6px; }
|
|
9
7
|
.ax-terminal__dot { width: 9px; height: 9px; border-radius: var(--radius-1); background: rgba(255,255,255,0.18); }
|
|
10
8
|
.ax-terminal__title { font-size: 11px; color: #A1A1AA; letter-spacing: 0.04em; flex: 1; text-align: center; }
|
|
@@ -26,10 +24,19 @@ if (typeof document !== "undefined" && !document.getElementById("ax-terminal-css
|
|
|
26
24
|
s.textContent = AX_TERMINAL_CSS;
|
|
27
25
|
document.head.appendChild(s);
|
|
28
26
|
}
|
|
29
|
-
function Terminal({
|
|
27
|
+
function Terminal({
|
|
28
|
+
title = "bash",
|
|
29
|
+
lines = [],
|
|
30
|
+
prompt = "$",
|
|
31
|
+
cursor = false,
|
|
32
|
+
className = "",
|
|
33
|
+
...rest
|
|
34
|
+
}) {
|
|
30
35
|
const [copied, setCopied] = useState(false);
|
|
31
36
|
const copy = () => {
|
|
32
|
-
const text = lines.map(
|
|
37
|
+
const text = lines.map(
|
|
38
|
+
(l) => typeof l === "string" ? l : l.type === "command" ? prompt + " " + l.text : l.text
|
|
39
|
+
).join("\n");
|
|
33
40
|
try {
|
|
34
41
|
navigator.clipboard && navigator.clipboard.writeText(text);
|
|
35
42
|
} catch (e) {
|
|
@@ -60,10 +67,17 @@ function Terminal({ title = "bash", lines = [], prompt = "$", cursor = false, cl
|
|
|
60
67
|
cursor && isLast ? /* @__PURE__ */ jsx("span", { className: "ax-terminal__cursor" }) : null
|
|
61
68
|
] }, i);
|
|
62
69
|
}
|
|
63
|
-
return /* @__PURE__ */ jsxs(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
return /* @__PURE__ */ jsxs(
|
|
71
|
+
"div",
|
|
72
|
+
{
|
|
73
|
+
className: "ax-terminal__line ax-terminal__" + (line.type === "error" ? "err" : "out"),
|
|
74
|
+
children: [
|
|
75
|
+
line.text,
|
|
76
|
+
cursor && isLast ? /* @__PURE__ */ jsx("span", { className: "ax-terminal__cursor" }) : null
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
i
|
|
80
|
+
);
|
|
67
81
|
}) })
|
|
68
82
|
] });
|
|
69
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Terminal.js","sources":["../../../src/components/code/Terminal.jsx"],"sourcesContent":["import React, { useState } from \"react\";\n\nconst AX_TERMINAL_CSS = `\n.ax-terminal { border: 1px solid var(--border-strong); border-radius: var(--radius-3); overflow: hidden; background:
|
|
1
|
+
{"version":3,"file":"Terminal.js","sources":["../../../src/components/code/Terminal.jsx"],"sourcesContent":["import React, { useState } from \"react\";\n\nconst AX_TERMINAL_CSS = `\n.ax-terminal { border: 1px solid var(--border-strong); border-radius: var(--radius-3); overflow: hidden; background: #0A0A0B; font-family: var(--font-mono); }\n.ax-terminal__bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #18181B; border-bottom: 1px solid rgba(255,255,255,0.1); }\n.ax-terminal__dots { display: flex; gap: 6px; }\n.ax-terminal__dot { width: 9px; height: 9px; border-radius: var(--radius-1); background: rgba(255,255,255,0.18); }\n.ax-terminal__title { font-size: 11px; color: #A1A1AA; letter-spacing: 0.04em; flex: 1; text-align: center; }\n.ax-terminal__copy { appearance: none; background: none; border: none; cursor: pointer; color: #63636B; font-size: 11px; padding: 2px 6px; border-radius: var(--radius-1); }\n.ax-terminal__copy:hover { color: #F4F4F5; }\n.ax-terminal__body { padding: 14px 16px; overflow-x: auto; font-size: var(--text-sm); line-height: 1.7; }\n.ax-terminal__line { white-space: pre; color: #E4E4E7; }\n.ax-terminal__prompt { color: #3ECF8E; user-select: none; }\n.ax-terminal__cmd { color: #F4F4F5; }\n.ax-terminal__out { color: #A1A1AA; }\n.ax-terminal__err { color: #E5484D; }\n.ax-terminal__cursor { display: inline-block; width: 0.5em; height: 1em; background: #3ECF8E; vertical-align: text-bottom; animation: ax-term-blink 1.1s steps(1) infinite; }\n@keyframes ax-term-blink { 50% { opacity: 0; } }\n@media (prefers-reduced-motion: reduce) { .ax-terminal__cursor { animation: none; } }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-terminal-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-terminal-css\";\n s.textContent = AX_TERMINAL_CSS;\n document.head.appendChild(s);\n}\n\nexport function Terminal({\n title = \"bash\",\n lines = [],\n prompt = \"$\",\n cursor = false,\n className = \"\",\n ...rest\n}) {\n const [copied, setCopied] = useState(false);\n const copy = () => {\n const text = lines\n .map((l) =>\n typeof l === \"string\" ? l : l.type === \"command\" ? prompt + \" \" + l.text : l.text,\n )\n .join(\"\\n\");\n try {\n navigator.clipboard && navigator.clipboard.writeText(text);\n } catch (e) {}\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n return (\n <div className={[\"ax-terminal\", className].filter(Boolean).join(\" \")} {...rest}>\n <div className=\"ax-terminal__bar\">\n <span className=\"ax-terminal__dots\">\n <span className=\"ax-terminal__dot\"></span>\n <span className=\"ax-terminal__dot\"></span>\n <span className=\"ax-terminal__dot\"></span>\n </span>\n <span className=\"ax-terminal__title\">{title}</span>\n <button className=\"ax-terminal__copy\" onClick={copy}>\n {copied ? \"copied ✓\" : \"copy\"}\n </button>\n </div>\n <div className=\"ax-terminal__body\">\n {lines.map((l, i) => {\n const line = typeof l === \"string\" ? { type: \"command\", text: l } : l;\n const isLast = i === lines.length - 1;\n if (line.type === \"command\") {\n return (\n <div className=\"ax-terminal__line\" key={i}>\n <span className=\"ax-terminal__prompt\">{prompt} </span>\n <span className=\"ax-terminal__cmd\">{line.text}</span>\n {cursor && isLast ? <span className=\"ax-terminal__cursor\"></span> : null}\n </div>\n );\n }\n return (\n <div\n className={\n \"ax-terminal__line ax-terminal__\" + (line.type === \"error\" ? \"err\" : \"out\")\n }\n key={i}\n >\n {line.text}\n {cursor && isLast ? <span className=\"ax-terminal__cursor\"></span> : null}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;AAEA,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBxB,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,iBAAiB,GAAG;AAClF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,SAAS;AAAA,EACvB,QAAQ;AAAA,EACR,QAAQ,CAAA;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,GAAG;AACL,GAAG;AACD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,OAAO,MAAM;AACjB,UAAM,OAAO,MACV;AAAA,MAAI,CAAC,MACJ,OAAO,MAAM,WAAW,IAAI,EAAE,SAAS,YAAY,SAAS,MAAM,EAAE,OAAO,EAAE;AAAA,IAAA,EAE9E,KAAK,IAAI;AACZ,QAAI;AACF,gBAAU,aAAa,UAAU,UAAU,UAAU,IAAI;AAAA,IAC3D,SAAS,GAAG;AAAA,IAAC;AACb,cAAU,IAAI;AACd,eAAW,MAAM,UAAU,KAAK,GAAG,IAAI;AAAA,EACzC;AACA,SACE,qBAAC,OAAA,EAAI,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MACxE,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,MAAA,qBAAC,QAAA,EAAK,WAAU,qBACd,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,QACnC,oBAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,QACnC,oBAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,MAAA,GACrC;AAAA,MACA,oBAAC,QAAA,EAAK,WAAU,sBAAsB,UAAA,OAAM;AAAA,MAC5C,oBAAC,YAAO,WAAU,qBAAoB,SAAS,MAC5C,UAAA,SAAS,aAAa,OAAA,CACzB;AAAA,IAAA,GACF;AAAA,IACA,oBAAC,SAAI,WAAU,qBACZ,gBAAM,IAAI,CAAC,GAAG,MAAM;AACnB,YAAM,OAAO,OAAO,MAAM,WAAW,EAAE,MAAM,WAAW,MAAM,EAAA,IAAM;AACpE,YAAM,SAAS,MAAM,MAAM,SAAS;AACpC,UAAI,KAAK,SAAS,WAAW;AAC3B,eACE,qBAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,UAAA,qBAAC,QAAA,EAAK,WAAU,uBAAuB,UAAA;AAAA,YAAA;AAAA,YAAO;AAAA,UAAA,GAAC;AAAA,UAC/C,oBAAC,QAAA,EAAK,WAAU,oBAAoB,eAAK,MAAK;AAAA,UAC7C,UAAU,SAAS,oBAAC,QAAA,EAAK,WAAU,uBAAsB,IAAU;AAAA,QAAA,EAAA,GAH9B,CAIxC;AAAA,MAEJ;AACA,aACE;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WACE,qCAAqC,KAAK,SAAS,UAAU,QAAQ;AAAA,UAItE,UAAA;AAAA,YAAA,KAAK;AAAA,YACL,UAAU,SAAS,oBAAC,QAAA,EAAK,WAAU,uBAAsB,IAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAH/D;AAAA,MAAA;AAAA,IAMX,CAAC,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -5,14 +5,14 @@ const AX_WEBPREVIEW_CSS = `
|
|
|
5
5
|
.ax-webpreview__bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border-default); }
|
|
6
6
|
.ax-webpreview__nav { display: flex; gap: 4px; }
|
|
7
7
|
.ax-webpreview__navbtn { width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; color: var(--text-faint); border-radius: var(--radius-1); }
|
|
8
|
-
.ax-webpreview__url { flex: 1; display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; background: var(--bg-
|
|
9
|
-
[data-theme="
|
|
8
|
+
.ax-webpreview__url { flex: 1; display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-1); font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); overflow: hidden; }
|
|
9
|
+
[data-theme="dark"] .ax-webpreview__url { background: var(--bg-0); }
|
|
10
10
|
.ax-webpreview__lock { color: var(--ok); flex: none; }
|
|
11
11
|
.ax-webpreview__urltext { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
12
12
|
.ax-webpreview__refresh { appearance: none; background: none; border: none; cursor: pointer; color: var(--text-faint); padding: 4px; border-radius: var(--radius-1); flex: none; }
|
|
13
13
|
.ax-webpreview__refresh:hover { color: var(--text-body); }
|
|
14
|
-
.ax-webpreview__viewport { background:
|
|
15
|
-
[data-theme="
|
|
14
|
+
.ax-webpreview__viewport { background: #fff; min-height: 160px; }
|
|
15
|
+
[data-theme="dark"] .ax-webpreview__viewport { background: var(--bg-0); }
|
|
16
16
|
.ax-webpreview__viewport iframe { width: 100%; height: 100%; min-height: 160px; border: none; display: block; }
|
|
17
17
|
`;
|
|
18
18
|
if (typeof document !== "undefined" && !document.getElementById("ax-webpreview-css")) {
|
|
@@ -21,12 +21,46 @@ if (typeof document !== "undefined" && !document.getElementById("ax-webpreview-c
|
|
|
21
21
|
s.textContent = AX_WEBPREVIEW_CSS;
|
|
22
22
|
document.head.appendChild(s);
|
|
23
23
|
}
|
|
24
|
-
const Lock = /* @__PURE__ */ jsxs(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
const Lock = /* @__PURE__ */ jsxs(
|
|
25
|
+
"svg",
|
|
26
|
+
{
|
|
27
|
+
width: "11",
|
|
28
|
+
height: "11",
|
|
29
|
+
viewBox: "0 0 24 24",
|
|
30
|
+
fill: "none",
|
|
31
|
+
stroke: "currentColor",
|
|
32
|
+
strokeWidth: "2.4",
|
|
33
|
+
strokeLinecap: "round",
|
|
34
|
+
strokeLinejoin: "round",
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2" }),
|
|
37
|
+
/* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
const Refresh = /* @__PURE__ */ jsx(
|
|
42
|
+
"svg",
|
|
43
|
+
{
|
|
44
|
+
width: "13",
|
|
45
|
+
height: "13",
|
|
46
|
+
viewBox: "0 0 24 24",
|
|
47
|
+
fill: "none",
|
|
48
|
+
stroke: "currentColor",
|
|
49
|
+
strokeWidth: "2",
|
|
50
|
+
strokeLinecap: "round",
|
|
51
|
+
strokeLinejoin: "round",
|
|
52
|
+
children: /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8M21 3v5h-5" })
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
function WebPreview({
|
|
56
|
+
url = "localhost:3000",
|
|
57
|
+
height = 200,
|
|
58
|
+
src,
|
|
59
|
+
srcDoc,
|
|
60
|
+
children,
|
|
61
|
+
className = "",
|
|
62
|
+
...rest
|
|
63
|
+
}) {
|
|
30
64
|
return /* @__PURE__ */ jsxs("div", { className: ["ax-webpreview", className].filter(Boolean).join(" "), ...rest, children: [
|
|
31
65
|
/* @__PURE__ */ jsxs("div", { className: "ax-webpreview__bar", children: [
|
|
32
66
|
/* @__PURE__ */ jsxs("span", { className: "ax-webpreview__nav", children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebPreview.js","sources":["../../../src/components/code/WebPreview.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_WEBPREVIEW_CSS = `\n.ax-webpreview { border: 1px solid var(--border-strong); border-radius: var(--radius-3); overflow: hidden; background: var(--surface-card); }\n.ax-webpreview__bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border-default); }\n.ax-webpreview__nav { display: flex; gap: 4px; }\n.ax-webpreview__navbtn { width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; color: var(--text-faint); border-radius: var(--radius-1); }\n.ax-webpreview__url { flex: 1; display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; background: var(--bg-
|
|
1
|
+
{"version":3,"file":"WebPreview.js","sources":["../../../src/components/code/WebPreview.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_WEBPREVIEW_CSS = `\n.ax-webpreview { border: 1px solid var(--border-strong); border-radius: var(--radius-3); overflow: hidden; background: var(--surface-card); }\n.ax-webpreview__bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border-default); }\n.ax-webpreview__nav { display: flex; gap: 4px; }\n.ax-webpreview__navbtn { width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; color: var(--text-faint); border-radius: var(--radius-1); }\n.ax-webpreview__url { flex: 1; display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; background: var(--bg-1); border: 1px solid var(--border-default); border-radius: var(--radius-1); font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); overflow: hidden; }\n[data-theme=\"dark\"] .ax-webpreview__url { background: var(--bg-0); }\n.ax-webpreview__lock { color: var(--ok); flex: none; }\n.ax-webpreview__urltext { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ax-webpreview__refresh { appearance: none; background: none; border: none; cursor: pointer; color: var(--text-faint); padding: 4px; border-radius: var(--radius-1); flex: none; }\n.ax-webpreview__refresh:hover { color: var(--text-body); }\n.ax-webpreview__viewport { background: #fff; min-height: 160px; }\n[data-theme=\"dark\"] .ax-webpreview__viewport { background: var(--bg-0); }\n.ax-webpreview__viewport iframe { width: 100%; height: 100%; min-height: 160px; border: none; display: block; }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-webpreview-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-webpreview-css\";\n s.textContent = AX_WEBPREVIEW_CSS;\n document.head.appendChild(s);\n}\n\nconst Lock = (\n <svg\n width=\"11\"\n height=\"11\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\"></rect>\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>\n </svg>\n);\nconst Refresh = (\n <svg\n width=\"13\"\n height=\"13\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8M21 3v5h-5\"></path>\n </svg>\n);\n\nexport function WebPreview({\n url = \"localhost:3000\",\n height = 200,\n src,\n srcDoc,\n children,\n className = \"\",\n ...rest\n}) {\n return (\n <div className={[\"ax-webpreview\", className].filter(Boolean).join(\" \")} {...rest}>\n <div className=\"ax-webpreview__bar\">\n <span className=\"ax-webpreview__nav\">\n <span className=\"ax-webpreview__navbtn\">‹</span>\n <span className=\"ax-webpreview__navbtn\">›</span>\n </span>\n <span className=\"ax-webpreview__url\">\n <span className=\"ax-webpreview__lock\">{Lock}</span>\n <span className=\"ax-webpreview__urltext\">{url}</span>\n </span>\n <button className=\"ax-webpreview__refresh\">{Refresh}</button>\n </div>\n <div className=\"ax-webpreview__viewport\" style={{ height }}>\n {children ? (\n children\n ) : (\n <iframe src={src} srcDoc={srcDoc} title={url} sandbox=\"allow-scripts\"></iframe>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;AAEA,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgB1B,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,mBAAmB,GAAG;AACpF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEA,MAAM,OACJ;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IAEf,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAK,GAAE,KAAI,GAAE,MAAK,OAAM,MAAK,QAAO,MAAK,IAAG,IAAA,CAAI;AAAA,MACjD,oBAAC,QAAA,EAAK,GAAE,2BAAA,CAA2B;AAAA,IAAA;AAAA,EAAA;AACrC;AAEF,MAAM,UACJ;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IAEf,UAAA,oBAAC,QAAA,EAAK,GAAE,+DAAA,CAA+D;AAAA,EAAA;AACzE;AAGK,SAAS,WAAW;AAAA,EACzB,MAAM;AAAA,EACN,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,GAAG;AACL,GAAG;AACD,SACE,qBAAC,OAAA,EAAI,WAAW,CAAC,iBAAiB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,MAC1E,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,MAAA,qBAAC,QAAA,EAAK,WAAU,sBACd,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,yBAAwB,UAAA,KAAC;AAAA,QACzC,oBAAC,QAAA,EAAK,WAAU,yBAAwB,UAAA,IAAA,CAAC;AAAA,MAAA,GAC3C;AAAA,MACA,qBAAC,QAAA,EAAK,WAAU,sBACd,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,uBAAuB,UAAA,MAAK;AAAA,QAC5C,oBAAC,QAAA,EAAK,WAAU,0BAA0B,UAAA,IAAA,CAAI;AAAA,MAAA,GAChD;AAAA,MACA,oBAAC,UAAA,EAAO,WAAU,0BAA0B,UAAA,QAAA,CAAQ;AAAA,IAAA,GACtD;AAAA,wBACC,OAAA,EAAI,WAAU,2BAA0B,OAAO,EAAE,UAC/C,UAAA,WACC,WAEA,oBAAC,YAAO,KAAU,QAAgB,OAAO,KAAK,SAAQ,iBAAgB,EAAA,CAE1E;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -7,11 +7,11 @@ const AX_SKELETON_CSS = `
|
|
|
7
7
|
}
|
|
8
8
|
.ax-skeleton::after {
|
|
9
9
|
content: ""; position: absolute; inset: 0;
|
|
10
|
-
background: linear-gradient(90deg, transparent,
|
|
10
|
+
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent);
|
|
11
11
|
transform: translateX(-100%);
|
|
12
12
|
animation: ax-shimmer 1.4s var(--ease-out) infinite;
|
|
13
13
|
}
|
|
14
|
-
[data-theme="
|
|
14
|
+
[data-theme="dark"] .ax-skeleton::after { background: linear-gradient(90deg, transparent, var(--bg-3), transparent); }
|
|
15
15
|
.ax-skeleton--text { height: 0.7em; margin: 0.2em 0; }
|
|
16
16
|
.ax-skeleton--circle { border-radius: var(--radius-2); }
|
|
17
17
|
@keyframes ax-shimmer { 100% { transform: translateX(100%); } }
|
|
@@ -23,7 +23,15 @@ if (typeof document !== "undefined" && !document.getElementById("ax-skeleton-css
|
|
|
23
23
|
s.textContent = AX_SKELETON_CSS;
|
|
24
24
|
document.head.appendChild(s);
|
|
25
25
|
}
|
|
26
|
-
function Skeleton({
|
|
26
|
+
function Skeleton({
|
|
27
|
+
variant = "block",
|
|
28
|
+
width,
|
|
29
|
+
height,
|
|
30
|
+
lines = 1,
|
|
31
|
+
className = "",
|
|
32
|
+
style = {},
|
|
33
|
+
...rest
|
|
34
|
+
}) {
|
|
27
35
|
if (variant === "text" && lines > 1) {
|
|
28
36
|
return /* @__PURE__ */ jsx("div", { className, ...rest, children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx(
|
|
29
37
|
"span",
|
|
@@ -34,7 +42,12 @@ function Skeleton({ variant = "block", width, height, lines = 1, className = "",
|
|
|
34
42
|
i
|
|
35
43
|
)) });
|
|
36
44
|
}
|
|
37
|
-
const cls = [
|
|
45
|
+
const cls = [
|
|
46
|
+
"ax-skeleton",
|
|
47
|
+
variant === "text" ? "ax-skeleton--text" : "",
|
|
48
|
+
variant === "circle" ? "ax-skeleton--circle" : "",
|
|
49
|
+
className
|
|
50
|
+
].filter(Boolean).join(" ");
|
|
38
51
|
return /* @__PURE__ */ jsx("span", { className: cls, style: { width, height, ...style }, ...rest });
|
|
39
52
|
}
|
|
40
53
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Skeleton.js","sources":["../../../src/components/display/Skeleton.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_SKELETON_CSS = `\n.ax-skeleton {\n display: block; background: var(--surface-raised);\n border-radius: var(--radius-1); position: relative; overflow: hidden;\n}\n.ax-skeleton::after {\n content: \"\"; position: absolute; inset: 0;\n background: linear-gradient(90deg, transparent,
|
|
1
|
+
{"version":3,"file":"Skeleton.js","sources":["../../../src/components/display/Skeleton.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_SKELETON_CSS = `\n.ax-skeleton {\n display: block; background: var(--surface-raised);\n border-radius: var(--radius-1); position: relative; overflow: hidden;\n}\n.ax-skeleton::after {\n content: \"\"; position: absolute; inset: 0;\n background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent);\n transform: translateX(-100%);\n animation: ax-shimmer 1.4s var(--ease-out) infinite;\n}\n[data-theme=\"dark\"] .ax-skeleton::after { background: linear-gradient(90deg, transparent, var(--bg-3), transparent); }\n.ax-skeleton--text { height: 0.7em; margin: 0.2em 0; }\n.ax-skeleton--circle { border-radius: var(--radius-2); }\n@keyframes ax-shimmer { 100% { transform: translateX(100%); } }\n@media (prefers-reduced-motion: reduce) { .ax-skeleton::after { animation: none; } }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-skeleton-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-skeleton-css\";\n s.textContent = AX_SKELETON_CSS;\n document.head.appendChild(s);\n}\n\nexport function Skeleton({\n variant = \"block\",\n width,\n height,\n lines = 1,\n className = \"\",\n style = {},\n ...rest\n}) {\n if (variant === \"text\" && lines > 1) {\n return (\n <div className={className} {...rest}>\n {Array.from({ length: lines }).map((_, i) => (\n <span\n key={i}\n className=\"ax-skeleton ax-skeleton--text\"\n style={{ width: i === lines - 1 ? \"60%\" : \"100%\" }}\n ></span>\n ))}\n </div>\n );\n }\n const cls = [\n \"ax-skeleton\",\n variant === \"text\" ? \"ax-skeleton--text\" : \"\",\n variant === \"circle\" ? \"ax-skeleton--circle\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n return <span className={cls} style={{ width, height, ...style }} {...rest}></span>;\n}\n"],"names":[],"mappings":";;AAEA,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBxB,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,iBAAiB,GAAG;AAClF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,QAAQ,CAAA;AAAA,EACR,GAAG;AACL,GAAG;AACD,MAAI,YAAY,UAAU,QAAQ,GAAG;AACnC,WACE,oBAAC,OAAA,EAAI,WAAuB,GAAG,MAC5B,UAAA,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,IAAI,CAAC,GAAG,MACrC;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,MAAM,QAAQ,IAAI,QAAQ,OAAA;AAAA,MAAO;AAAA,MAF5C;AAAA,IAAA,CAIR,GACH;AAAA,EAEJ;AACA,QAAM,MAAM;AAAA,IACV;AAAA,IACA,YAAY,SAAS,sBAAsB;AAAA,IAC3C,YAAY,WAAW,wBAAwB;AAAA,IAC/C;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AACX,SAAO,oBAAC,QAAA,EAAK,WAAW,KAAK,OAAO,EAAE,OAAO,QAAQ,GAAG,SAAU,GAAG,KAAA,CAAM;AAC7E;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection/health status chip built on Badge. Maps a status string to the
|
|
3
|
+
* right variant + dot + label. idle→neutral, testing→neutral·dot, ok→ok·dot,
|
|
4
|
+
* error→danger·dot.
|
|
5
|
+
*/
|
|
6
|
+
export interface StatusPillProps {
|
|
7
|
+
/** @default "idle" */
|
|
8
|
+
status?: "idle" | "testing" | "ok" | "error";
|
|
9
|
+
/** Override the per-state label text. */
|
|
10
|
+
labels?: Partial<Record<"idle" | "testing" | "ok" | "error", string>>;
|
|
11
|
+
}
|
|
12
|
+
export declare function StatusPill(props: StatusPillProps): JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import { Badge } from "./Badge.js";
|
|
4
|
+
function StatusPill({ status = "idle", labels = {}, ...rest }) {
|
|
5
|
+
const L = { idle: "未连接", testing: "测试中", ok: "已连接", error: "连接失败", ...labels };
|
|
6
|
+
if (status === "ok")
|
|
7
|
+
return /* @__PURE__ */ jsx(Badge, { variant: "ok", dot: true, ...rest, children: L.ok });
|
|
8
|
+
if (status === "error")
|
|
9
|
+
return /* @__PURE__ */ jsx(Badge, { variant: "danger", dot: true, ...rest, children: L.error });
|
|
10
|
+
if (status === "testing")
|
|
11
|
+
return /* @__PURE__ */ jsx(Badge, { variant: "neutral", dot: true, ...rest, children: L.testing });
|
|
12
|
+
return /* @__PURE__ */ jsx(Badge, { variant: "neutral", ...rest, children: L.idle });
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
StatusPill
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=StatusPill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusPill.js","sources":["../../../src/components/display/StatusPill.jsx"],"sourcesContent":["import React from \"react\";\nimport { Badge } from \"./Badge.jsx\";\n\n// StatusPill — connection/health status mapped onto the DS Badge.\n// Four states: idle (未连接) · testing (测试中) · ok (已连接) · error (连接失败).\n// Labels are overridable for non-connection uses.\nexport function StatusPill({ status = \"idle\", labels = {}, ...rest }) {\n const L = { idle: \"未连接\", testing: \"测试中\", ok: \"已连接\", error: \"连接失败\", ...labels };\n if (status === \"ok\")\n return (\n <Badge variant=\"ok\" dot {...rest}>\n {L.ok}\n </Badge>\n );\n if (status === \"error\")\n return (\n <Badge variant=\"danger\" dot {...rest}>\n {L.error}\n </Badge>\n );\n if (status === \"testing\")\n return (\n <Badge variant=\"neutral\" dot {...rest}>\n {L.testing}\n </Badge>\n );\n return (\n <Badge variant=\"neutral\" {...rest}>\n {L.idle}\n </Badge>\n );\n}\n"],"names":[],"mappings":";;;AAMO,SAAS,WAAW,EAAE,SAAS,QAAQ,SAAS,CAAA,GAAI,GAAG,QAAQ;AACpE,QAAM,IAAI,EAAE,MAAM,OAAO,SAAS,OAAO,IAAI,OAAO,OAAO,QAAQ,GAAG,OAAA;AACtE,MAAI,WAAW;AACb,WACE,oBAAC,SAAM,SAAQ,MAAK,KAAG,MAAE,GAAG,MACzB,UAAA,EAAE,GAAA,CACL;AAEJ,MAAI,WAAW;AACb,WACE,oBAAC,SAAM,SAAQ,UAAS,KAAG,MAAE,GAAG,MAC7B,UAAA,EAAE,MAAA,CACL;AAEJ,MAAI,WAAW;AACb,WACE,oBAAC,SAAM,SAAQ,WAAU,KAAG,MAAE,GAAG,MAC9B,UAAA,EAAE,QAAA,CACL;AAEJ,6BACG,OAAA,EAAM,SAAQ,WAAW,GAAG,MAC1B,YAAE,MACL;AAEJ;"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
/** Structural <form> wrapper. Pure layout — pass form.handleSubmit as onSubmit. */
|
|
4
|
+
export interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
|
|
5
|
+
/** Vertical rhythm between children. @default "normal" */
|
|
6
|
+
gap?: "tight" | "normal" | "loose";
|
|
7
|
+
onSubmit?: (e: React.FormEvent<HTMLFormElement>) => void;
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Footer row for submit/cancel buttons. */
|
|
12
|
+
export interface FormActionsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
13
|
+
/** Horizontal alignment of the buttons. @default "end" */
|
|
14
|
+
align?: "start" | "end" | "between";
|
|
15
|
+
/** Draw a separator line above the row. @default false */
|
|
16
|
+
bordered?: boolean;
|
|
17
|
+
/** Stretch buttons to fill the row equally. @default false */
|
|
18
|
+
full?: boolean;
|
|
19
|
+
children?: React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** A `{ value, message }` pair, or the bare value (message falls back to a default). */
|
|
23
|
+
export type Rule<T> = T | { value: T; message: string };
|
|
24
|
+
|
|
25
|
+
/** Built-in per-field validation rules, RHF-aligned. Pass as the 2nd arg to register/field. */
|
|
26
|
+
export interface FieldRules<V = Record<string, any>> {
|
|
27
|
+
/** Non-empty (and, for checkboxes, checked). String = custom message. */
|
|
28
|
+
required?: boolean | string;
|
|
29
|
+
minLength?: Rule<number>;
|
|
30
|
+
maxLength?: Rule<number>;
|
|
31
|
+
min?: Rule<number>;
|
|
32
|
+
max?: Rule<number>;
|
|
33
|
+
pattern?: RegExp | { value: RegExp; message: string };
|
|
34
|
+
/** Custom validator(s). Return `true` (ok), a string (error message), or `false`. May be async. */
|
|
35
|
+
validate?:
|
|
36
|
+
| ((value: any, values: V) => boolean | string | Promise<boolean | string>)
|
|
37
|
+
| Record<string, (value: any, values: V) => boolean | string | Promise<boolean | string>>;
|
|
38
|
+
/** Set "checkbox" so register/field bind `checked` instead of `value`. */
|
|
39
|
+
type?: "checkbox";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface RegisterReturn {
|
|
43
|
+
name: string;
|
|
44
|
+
value?: any;
|
|
45
|
+
checked?: boolean;
|
|
46
|
+
onChange: (e: any) => void;
|
|
47
|
+
onBlur: () => void;
|
|
48
|
+
}
|
|
49
|
+
export interface FieldReturn extends RegisterReturn {
|
|
50
|
+
/** Current error for this field (only set once it has been validated). */
|
|
51
|
+
error?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface FormState<V> {
|
|
55
|
+
errors: Record<string, string>;
|
|
56
|
+
touched: Record<string, boolean>;
|
|
57
|
+
dirtyFields: Record<string, boolean>;
|
|
58
|
+
isDirty: boolean;
|
|
59
|
+
/** True when the last validation run produced no errors. */
|
|
60
|
+
isValid: boolean;
|
|
61
|
+
isValidating: boolean;
|
|
62
|
+
isSubmitting: boolean;
|
|
63
|
+
isSubmitted: boolean;
|
|
64
|
+
isSubmitSuccessful: boolean;
|
|
65
|
+
submitCount: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface FormBag<V = Record<string, any>> extends FormState<V> {
|
|
69
|
+
values: V;
|
|
70
|
+
/** Alias of isSubmitted, kept for back-compat. */
|
|
71
|
+
submitted: boolean;
|
|
72
|
+
formState: FormState<V>;
|
|
73
|
+
|
|
74
|
+
/** RHF-compatible binding: `<input {...form.register("email", { required: true })} />`. */
|
|
75
|
+
register: (name: string, rules?: FieldRules<V>) => RegisterReturn;
|
|
76
|
+
/** Like register but also injects `error` for DS controls: `<Input {...form.field("email")} />`. */
|
|
77
|
+
field: (name: string, rules?: FieldRules<V>) => FieldReturn;
|
|
78
|
+
|
|
79
|
+
setValue: (
|
|
80
|
+
name: string,
|
|
81
|
+
value: any,
|
|
82
|
+
opts?: { shouldValidate?: boolean; shouldTouch?: boolean; shouldDirty?: boolean },
|
|
83
|
+
) => void;
|
|
84
|
+
setValues: (values: V | ((prev: V) => V)) => void;
|
|
85
|
+
getValues: (name?: string) => any;
|
|
86
|
+
/** Read field value(s) reactively (re-renders on change). */
|
|
87
|
+
watch: (name?: string) => any;
|
|
88
|
+
/** Set a field error manually (e.g. a server-side error). */
|
|
89
|
+
setError: (name: string, message: string) => void;
|
|
90
|
+
clearErrors: (name?: string) => void;
|
|
91
|
+
/** Imperatively validate the form or one field. Resolves to validity. */
|
|
92
|
+
trigger: (name?: string) => Promise<boolean>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Two call styles:
|
|
96
|
+
* - `onSubmit={form.handleSubmit}` (uses config.onSubmit) — works as a direct event/onClick handler.
|
|
97
|
+
* - `onSubmit={form.handleSubmit(onValid, onInvalid?)}` — RHF style, returns a handler.
|
|
98
|
+
* Always preventDefaults, validates, marks all fields touched, focuses the first error.
|
|
99
|
+
*/
|
|
100
|
+
handleSubmit: {
|
|
101
|
+
(e?: React.FormEvent | React.MouseEvent): void;
|
|
102
|
+
(
|
|
103
|
+
onValid: (values: V) => void | Promise<any>,
|
|
104
|
+
onInvalid?: (errors: Record<string, string>) => void,
|
|
105
|
+
): (e?: React.SyntheticEvent) => void;
|
|
106
|
+
};
|
|
107
|
+
reset: (
|
|
108
|
+
next?: V,
|
|
109
|
+
opts?: {
|
|
110
|
+
keepErrors?: boolean;
|
|
111
|
+
keepTouched?: boolean;
|
|
112
|
+
keepDirty?: boolean;
|
|
113
|
+
keepIsSubmitted?: boolean;
|
|
114
|
+
keepDefaultValues?: boolean;
|
|
115
|
+
},
|
|
116
|
+
) => void;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface UseFormConfig<V = Record<string, any>> {
|
|
120
|
+
initialValues?: V;
|
|
121
|
+
/** Alias of initialValues (RHF naming). */
|
|
122
|
+
defaultValues?: V;
|
|
123
|
+
/** Schema-style validator: `(values) => ({ field: message })`. Sync or async. Composes with per-field rules. */
|
|
124
|
+
validate?: (values: V) => Record<string, string> | Promise<Record<string, string>> | undefined;
|
|
125
|
+
/** When validation first fires. @default "onSubmit" */
|
|
126
|
+
mode?: "onSubmit" | "onBlur" | "onChange" | "onTouched" | "all";
|
|
127
|
+
/** When to re-validate after the first submit. @default "onChange" */
|
|
128
|
+
reValidateMode?: "onChange" | "onBlur";
|
|
129
|
+
/** Called with values on a clean submit. May return a promise → toggles isSubmitting. */
|
|
130
|
+
onSubmit?: (values: V) => void | Promise<any>;
|
|
131
|
+
/** Called with the errors map when submit is attempted while invalid. */
|
|
132
|
+
onInvalid?: (errors: Record<string, string>) => void;
|
|
133
|
+
/** Focus the first errored `[name]` control on a failed submit. @default true */
|
|
134
|
+
shouldFocusError?: boolean;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface UseFieldArrayConfig<V = Record<string, any>> {
|
|
138
|
+
form: FormBag<V>;
|
|
139
|
+
/** Name of the array field on the form's values. */
|
|
140
|
+
name: string;
|
|
141
|
+
}
|
|
142
|
+
export interface FieldArrayReturn<T = any> {
|
|
143
|
+
/** Current rows, each with a stable `id`. */
|
|
144
|
+
fields: Array<T & { id: number }>;
|
|
145
|
+
append: (item: T) => void;
|
|
146
|
+
prepend: (item: T) => void;
|
|
147
|
+
remove: (index: number) => void;
|
|
148
|
+
insert: (index: number, item: T) => void;
|
|
149
|
+
move: (from: number, to: number) => void;
|
|
150
|
+
replace: (items: T[]) => void;
|
|
151
|
+
update: (index: number, item: T) => void;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export declare function Form(props: FormProps): JSX.Element;
|
|
155
|
+
export declare namespace Form {
|
|
156
|
+
/** Production controlled form hook — RHF-aligned. Optional; drop it for RHF/TanStack. */
|
|
157
|
+
function useForm<V = Record<string, any>>(config?: UseFormConfig<V>): FormBag<V>;
|
|
158
|
+
/** Dynamic list fields. */
|
|
159
|
+
function useFieldArray<T = any, V = Record<string, any>>(
|
|
160
|
+
config: UseFieldArrayConfig<V>,
|
|
161
|
+
): FieldArrayReturn<T>;
|
|
162
|
+
function Actions(props: FormActionsProps): JSX.Element;
|
|
163
|
+
}
|
|
164
|
+
export declare function FormActions(props: FormActionsProps): JSX.Element;
|