@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.
Files changed (82) hide show
  1. package/DESIGN.md +58 -7
  2. package/README.md +10 -6
  3. package/dist/components/ai/Confirmation.js +58 -22
  4. package/dist/components/ai/Confirmation.js.map +1 -1
  5. package/dist/components/ai/Queue.d.ts +23 -0
  6. package/dist/components/ai/Queue.js +52 -1
  7. package/dist/components/ai/Queue.js.map +1 -1
  8. package/dist/components/ai/ToolCall.js +69 -30
  9. package/dist/components/ai/ToolCall.js.map +1 -1
  10. package/dist/components/auth/AccountControl.d.ts +23 -0
  11. package/dist/components/auth/AccountControl.js +47 -0
  12. package/dist/components/auth/AccountControl.js.map +1 -0
  13. package/dist/components/auth/AuthDialog.d.ts +39 -0
  14. package/dist/components/auth/AuthDialog.js +327 -0
  15. package/dist/components/auth/AuthDialog.js.map +1 -0
  16. package/dist/components/auth/SignInPage.d.ts +48 -0
  17. package/dist/components/auth/SignInPage.js +217 -0
  18. package/dist/components/auth/SignInPage.js.map +1 -0
  19. package/dist/components/chat/CodeBlock.js +3 -2
  20. package/dist/components/chat/CodeBlock.js.map +1 -1
  21. package/dist/components/chat/ConversationThread.d.ts +67 -0
  22. package/dist/components/chat/ConversationThread.js +129 -0
  23. package/dist/components/chat/ConversationThread.js.map +1 -0
  24. package/dist/components/code/Artifact.js +44 -9
  25. package/dist/components/code/Artifact.js.map +1 -1
  26. package/dist/components/code/JSXPreview.js +19 -12
  27. package/dist/components/code/JSXPreview.js.map +1 -1
  28. package/dist/components/code/Snippet.js +2 -2
  29. package/dist/components/code/Snippet.js.map +1 -1
  30. package/dist/components/code/Terminal.js +24 -10
  31. package/dist/components/code/Terminal.js.map +1 -1
  32. package/dist/components/code/WebPreview.js +44 -10
  33. package/dist/components/code/WebPreview.js.map +1 -1
  34. package/dist/components/display/Skeleton.js +17 -4
  35. package/dist/components/display/Skeleton.js.map +1 -1
  36. package/dist/components/display/StatusPill.d.ts +12 -0
  37. package/dist/components/display/StatusPill.js +17 -0
  38. package/dist/components/display/StatusPill.js.map +1 -0
  39. package/dist/components/inputs/Form.d.ts +164 -0
  40. package/dist/components/inputs/Form.js +484 -0
  41. package/dist/components/inputs/Form.js.map +1 -0
  42. package/dist/components/inputs/Input.d.ts +2 -0
  43. package/dist/components/inputs/Input.js +14 -10
  44. package/dist/components/inputs/Input.js.map +1 -1
  45. package/dist/components/inputs/SecretField.d.ts +21 -0
  46. package/dist/components/inputs/SecretField.js +70 -0
  47. package/dist/components/inputs/SecretField.js.map +1 -0
  48. package/dist/components/layout/AppShell.d.ts +30 -0
  49. package/dist/components/layout/AppShell.js +117 -0
  50. package/dist/components/layout/AppShell.js.map +1 -0
  51. package/dist/components/layout/DesignerShell.d.ts +39 -0
  52. package/dist/components/layout/DesignerShell.js +146 -0
  53. package/dist/components/layout/DesignerShell.js.map +1 -0
  54. package/dist/components/layout/DocsLayout.d.ts +24 -0
  55. package/dist/components/layout/DocsLayout.js +113 -0
  56. package/dist/components/layout/DocsLayout.js.map +1 -0
  57. package/dist/components/layout/SettingsPage.d.ts +31 -0
  58. package/dist/components/layout/SettingsPage.js +92 -0
  59. package/dist/components/layout/SettingsPage.js.map +1 -0
  60. package/dist/components/review/MarkupLayer.d.ts +20 -0
  61. package/dist/components/review/MarkupLayer.js +237 -0
  62. package/dist/components/review/MarkupLayer.js.map +1 -0
  63. package/dist/components/settings/HelpSteps.d.ts +20 -0
  64. package/dist/components/settings/HelpSteps.js +40 -0
  65. package/dist/components/settings/HelpSteps.js.map +1 -0
  66. package/dist/components/settings/IntegrationSettings.d.ts +15 -0
  67. package/dist/components/settings/IntegrationSettings.js +630 -0
  68. package/dist/components/settings/IntegrationSettings.js.map +1 -0
  69. package/dist/components/settings/TestRow.d.ts +21 -0
  70. package/dist/components/settings/TestRow.js +66 -0
  71. package/dist/components/settings/TestRow.js.map +1 -0
  72. package/dist/components/utilities/BrandMark.d.ts +17 -0
  73. package/dist/components/utilities/BrandMark.js +43 -0
  74. package/dist/components/utilities/BrandMark.js.map +1 -0
  75. package/dist/components/utilities/Icon.d.ts +28 -0
  76. package/dist/components/utilities/Icon.js +196 -0
  77. package/dist/components/utilities/Icon.js.map +1 -0
  78. package/dist/index.d.ts +23 -0
  79. package/dist/index.js +35 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/styles.css +67 -64
  82. package/package.json +2 -2
@@ -0,0 +1,70 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Icon } from "../utilities/Icon.js";
4
+ const AX_SECRETFIELD_CSS = `
5
+ .s-field__label { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
6
+ .s-field__hint { font-size: var(--text-xs); color: var(--text-faint); margin: 6px 0 0; line-height: var(--leading-snug); }
7
+ .s-field__hint--err { color: var(--danger); }
8
+ .s-secret { position: relative; }
9
+ .s-secret .ax-input { padding-right: 42px; font-family: var(--font-mono); letter-spacing: 0.02em; }
10
+ .s-secret__eye { position: absolute; right: 6px; bottom: 6px; width: 24px; height: 24px; padding: 0;
11
+ display: flex; align-items: center; justify-content: center; border: none; background: none; cursor: pointer;
12
+ color: var(--text-faint); border-radius: var(--radius-1); transition: color var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out); }
13
+ .s-secret__eye:hover { color: var(--text-body); background: var(--surface-raised); }
14
+ `;
15
+ if (typeof document !== "undefined" && !document.getElementById("ax-secretfield-css")) {
16
+ const s = document.createElement("style");
17
+ s.id = "ax-secretfield-css";
18
+ s.textContent = AX_SECRETFIELD_CSS;
19
+ document.head.appendChild(s);
20
+ }
21
+ function SecretField({
22
+ label,
23
+ value,
24
+ onChange,
25
+ placeholder,
26
+ hint,
27
+ error,
28
+ mono = true,
29
+ autoComplete = "off",
30
+ ...rest
31
+ }) {
32
+ const [show, setShow] = useState(false);
33
+ const inputId = "secret-" + String(label || "").replace(/\s+/g, "-").toLowerCase();
34
+ return /* @__PURE__ */ jsxs("div", { ...rest, children: [
35
+ label ? /* @__PURE__ */ jsx("label", { className: "s-field__label ax-label", htmlFor: inputId, children: label }) : null,
36
+ /* @__PURE__ */ jsxs("div", { className: "s-secret", children: [
37
+ /* @__PURE__ */ jsx(
38
+ "input",
39
+ {
40
+ id: inputId,
41
+ type: show ? "text" : "password",
42
+ className: "ax-input" + (mono ? " ax-input--mono" : "") + (error ? " ax-input--error" : ""),
43
+ value,
44
+ placeholder,
45
+ autoComplete,
46
+ spellCheck: "false",
47
+ onChange: (e) => onChange && onChange(e.target.value)
48
+ }
49
+ ),
50
+ /* @__PURE__ */ jsx(
51
+ "button",
52
+ {
53
+ type: "button",
54
+ className: "s-secret__eye",
55
+ onClick: () => setShow((v) => !v),
56
+ onMouseDown: (e) => e.preventDefault(),
57
+ "aria-label": show ? "隐藏" : "显示",
58
+ title: show ? "隐藏" : "显示",
59
+ tabIndex: -1,
60
+ children: /* @__PURE__ */ jsx(Icon, { name: show ? "eyeOff" : "eye", size: 15 })
61
+ }
62
+ )
63
+ ] }),
64
+ error ? /* @__PURE__ */ jsx("p", { className: "s-field__hint s-field__hint--err", children: error }) : hint ? /* @__PURE__ */ jsx("p", { className: "s-field__hint", children: hint }) : null
65
+ ] });
66
+ }
67
+ export {
68
+ SecretField
69
+ };
70
+ //# sourceMappingURL=SecretField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecretField.js","sources":["../../../src/components/inputs/SecretField.jsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { Icon } from \"../utilities/Icon.jsx\";\n\n// SecretField — masked credential input with show/hide and an optional\n// \"never exposed\" hint line. Builds on the bundle's .ax-input. Owns the\n// shared field-level chrome (.s-secret / .s-field__label / .s-field__hint)\n// used across the settings surfaces.\nconst AX_SECRETFIELD_CSS = `\n.s-field__label { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.s-field__hint { font-size: var(--text-xs); color: var(--text-faint); margin: 6px 0 0; line-height: var(--leading-snug); }\n.s-field__hint--err { color: var(--danger); }\n.s-secret { position: relative; }\n.s-secret .ax-input { padding-right: 42px; font-family: var(--font-mono); letter-spacing: 0.02em; }\n.s-secret__eye { position: absolute; right: 6px; bottom: 6px; width: 24px; height: 24px; padding: 0;\n display: flex; align-items: center; justify-content: center; border: none; background: none; cursor: pointer;\n color: var(--text-faint); border-radius: var(--radius-1); transition: color var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out); }\n.s-secret__eye:hover { color: var(--text-body); background: var(--surface-raised); }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-secretfield-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-secretfield-css\";\n s.textContent = AX_SECRETFIELD_CSS;\n document.head.appendChild(s);\n}\n\nexport function SecretField({\n label,\n value,\n onChange,\n placeholder,\n hint,\n error,\n mono = true,\n autoComplete = \"off\",\n ...rest\n}) {\n const [show, setShow] = useState(false);\n const inputId =\n \"secret-\" +\n String(label || \"\")\n .replace(/\\s+/g, \"-\")\n .toLowerCase();\n return (\n <div {...rest}>\n {label ? (\n <label className=\"s-field__label ax-label\" htmlFor={inputId}>\n {label}\n </label>\n ) : null}\n <div className=\"s-secret\">\n <input\n id={inputId}\n type={show ? \"text\" : \"password\"}\n className={\n \"ax-input\" + (mono ? \" ax-input--mono\" : \"\") + (error ? \" ax-input--error\" : \"\")\n }\n value={value}\n placeholder={placeholder}\n autoComplete={autoComplete}\n spellCheck=\"false\"\n onChange={(e) => onChange && onChange(e.target.value)}\n />\n <button\n type=\"button\"\n className=\"s-secret__eye\"\n onClick={() => setShow((v) => !v)}\n onMouseDown={(e) => e.preventDefault()}\n aria-label={show ? \"隐藏\" : \"显示\"}\n title={show ? \"隐藏\" : \"显示\"}\n tabIndex={-1}\n >\n <Icon name={show ? \"eyeOff\" : \"eye\"} size={15} />\n </button>\n </div>\n {error ? (\n <p className=\"s-field__hint s-field__hint--err\">{error}</p>\n ) : hint ? (\n <p className=\"s-field__hint\">{hint}</p>\n ) : null}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AAOA,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY3B,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,oBAAoB,GAAG;AACrF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf,GAAG;AACL,GAAG;AACD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,UACJ,YACA,OAAO,SAAS,EAAE,EACf,QAAQ,QAAQ,GAAG,EACnB,YAAA;AACL,SACE,qBAAC,OAAA,EAAK,GAAG,MACN,UAAA;AAAA,IAAA,4BACE,SAAA,EAAM,WAAU,2BAA0B,SAAS,SACjD,iBACH,IACE;AAAA,IACJ,qBAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAI;AAAA,UACJ,MAAM,OAAO,SAAS;AAAA,UACtB,WACE,cAAc,OAAO,oBAAoB,OAAO,QAAQ,qBAAqB;AAAA,UAE/E;AAAA,UACA;AAAA,UACA;AAAA,UACA,YAAW;AAAA,UACX,UAAU,CAAC,MAAM,YAAY,SAAS,EAAE,OAAO,KAAK;AAAA,QAAA;AAAA,MAAA;AAAA,MAEtD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,UAChC,aAAa,CAAC,MAAM,EAAE,eAAA;AAAA,UACtB,cAAY,OAAO,OAAO;AAAA,UAC1B,OAAO,OAAO,OAAO;AAAA,UACrB,UAAU;AAAA,UAEV,8BAAC,MAAA,EAAK,MAAM,OAAO,WAAW,OAAO,MAAM,GAAA,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IACjD,GACF;AAAA,IACC,QACC,oBAAC,KAAA,EAAE,WAAU,oCAAoC,UAAA,MAAA,CAAM,IACrD,OACF,oBAAC,KAAA,EAAE,WAAU,iBAAiB,gBAAK,IACjC;AAAA,EAAA,GACN;AAEJ;"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The standard product frame: fixed sidebar (brand · nav · account) + main
3
+ * column (topbar · scrolling content). Every region is a slot. Nav is
4
+ * controlled via activeId/onNavigate, or self-manages if you omit them.
5
+ */
6
+ export interface AppShellNavItem {
7
+ id: string;
8
+ label: string;
9
+ /** Leading icon node (e.g. <Icon name="layout" size={16} />). */
10
+ icon?: React.ReactNode;
11
+ }
12
+ export interface AppShellProps {
13
+ /** Sidebar brand lockup. @default <BrandMark wordmark blink={false} /> */
14
+ brand?: React.ReactNode;
15
+ nav?: AppShellNavItem[];
16
+ /** Mono label above the nav. @default "Navigate" */
17
+ navLabel?: string;
18
+ /** Controlled active nav id; omit to let the shell manage it. */
19
+ activeId?: string;
20
+ onNavigate?: (id: string) => void;
21
+ /** Sidebar footer slot — typically <AccountControl /> or an account chip. */
22
+ account?: React.ReactNode;
23
+ /** Left side of the topbar (breadcrumb / title). */
24
+ crumb?: React.ReactNode;
25
+ /** Right side of the topbar (search, primary action, etc.). */
26
+ actions?: React.ReactNode;
27
+ /** Main content. */
28
+ children?: React.ReactNode;
29
+ }
30
+ export declare function AppShell(props: AppShellProps): JSX.Element;
@@ -0,0 +1,117 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import React, { useState } from "react";
3
+ import { BrandMark } from "../utilities/BrandMark.js";
4
+ import { Icon } from "../utilities/Icon.js";
5
+ const AX_APPSHELL_CSS = `
6
+ .ax-appshell { display: grid; grid-template-columns: 240px 1fr; height: 100%; background: var(--surface-page); overflow: hidden; }
7
+ .ax-appshell__sb { display: flex; flex-direction: column; background: var(--surface-panel); border-right: 1px solid var(--border-default); min-height: 0; }
8
+ .ax-appshell__brand { display: flex; align-items: center; gap: 9px; padding: 18px 18px 14px; }
9
+ .ax-appshell__group { padding: 10px 12px 4px; }
10
+ .ax-appshell__nav { display: flex; flex-direction: column; gap: 2px; padding: 0 10px; }
11
+ .ax-appshell__item { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: var(--radius-2);
12
+ color: var(--text-muted); cursor: pointer; font-size: var(--text-sm); border: none; background: none; text-align: left;
13
+ font-family: inherit; transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
14
+ .ax-appshell__item:hover { background: var(--bg-3); color: var(--text-body); }
15
+ .ax-appshell__item[data-on="true"] { background: var(--accent); color: var(--accent-fg); }
16
+ .ax-appshell__foot { margin-top: auto; padding: 12px; border-top: 1px solid var(--border-default); }
17
+ .ax-appshell__main { display: flex; flex-direction: column; overflow: hidden; min-width: 0; }
18
+ .ax-appshell__top { display: flex; align-items: center; gap: 12px; height: 56px; flex: none; padding: 0 22px; border-bottom: 1px solid var(--border-default); }
19
+ .ax-appshell__crumb { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-muted); }
20
+ .ax-appshell__crumb b { color: var(--text-body); font-weight: var(--weight-medium); }
21
+ .ax-appshell__sp { flex: 1; }
22
+ .ax-appshell__body { flex: 1; padding: 22px; overflow-y: auto; }
23
+ .ax-appshell__burger { display: none; }
24
+ .ax-appshell__scrim { display: none; }
25
+ @media (max-width: 860px) {
26
+ .ax-appshell { grid-template-columns: 1fr; }
27
+ .ax-appshell__sb { position: fixed; top: 0; left: 0; bottom: 0; width: 264px; z-index: 40;
28
+ transform: translateX(-100%); transition: transform var(--dur-2) var(--ease-out); box-shadow: var(--shadow-3); }
29
+ .ax-appshell__sb[data-open="true"] { transform: none; }
30
+ .ax-appshell__scrim { display: block; position: fixed; inset: 0; z-index: 39; background: var(--bg-overlay);
31
+ opacity: 0; pointer-events: none; transition: opacity var(--dur-2) var(--ease-out); }
32
+ .ax-appshell__scrim[data-open="true"] { opacity: 1; pointer-events: auto; }
33
+ .ax-appshell__burger { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
34
+ flex: none; margin-left: -6px; border: 1px solid var(--border-default); border-radius: var(--radius-2);
35
+ background: none; color: var(--text-muted); cursor: pointer; }
36
+ .ax-appshell__burger:hover { color: var(--text-body); border-color: var(--border-strong); }
37
+ .ax-appshell__top { padding: 0 16px; }
38
+ .ax-appshell__body { padding: 18px 16px; }
39
+ }
40
+ `;
41
+ if (typeof document !== "undefined" && !document.getElementById("ax-appshell-css")) {
42
+ const s = document.createElement("style");
43
+ s.id = "ax-appshell-css";
44
+ s.textContent = AX_APPSHELL_CSS;
45
+ document.head.appendChild(s);
46
+ }
47
+ function AppShell({
48
+ brand,
49
+ nav = [],
50
+ navLabel = "Navigate",
51
+ activeId,
52
+ onNavigate,
53
+ account,
54
+ crumb,
55
+ actions,
56
+ children
57
+ }) {
58
+ const [internal, setInternal] = useState(nav[0] && nav[0].id);
59
+ const [menuOpen, setMenuOpen] = useState(false);
60
+ const active = activeId !== void 0 ? activeId : internal;
61
+ const go = (id) => {
62
+ if (onNavigate) onNavigate(id);
63
+ else setInternal(id);
64
+ setMenuOpen(false);
65
+ };
66
+ return /* @__PURE__ */ jsxs("div", { className: "ax-appshell", children: [
67
+ /* @__PURE__ */ jsx(
68
+ "div",
69
+ {
70
+ className: "ax-appshell__scrim",
71
+ "data-open": menuOpen,
72
+ onClick: () => setMenuOpen(false)
73
+ }
74
+ ),
75
+ /* @__PURE__ */ jsxs("aside", { className: "ax-appshell__sb", "data-open": menuOpen, children: [
76
+ /* @__PURE__ */ jsx("div", { className: "ax-appshell__brand", children: brand || /* @__PURE__ */ jsx(BrandMark, { size: 20, wordmark: true, blink: false }) }),
77
+ nav.length ? /* @__PURE__ */ jsxs(React.Fragment, { children: [
78
+ /* @__PURE__ */ jsx("div", { className: "ax-appshell__group", children: /* @__PURE__ */ jsx("span", { className: "ax-label", children: navLabel }) }),
79
+ /* @__PURE__ */ jsx("nav", { className: "ax-appshell__nav", children: nav.map((n) => /* @__PURE__ */ jsxs(
80
+ "button",
81
+ {
82
+ className: "ax-appshell__item",
83
+ "data-on": active === n.id,
84
+ onClick: () => go(n.id),
85
+ children: [
86
+ n.icon || null,
87
+ n.label
88
+ ]
89
+ },
90
+ n.id
91
+ )) })
92
+ ] }) : null,
93
+ account ? /* @__PURE__ */ jsx("div", { className: "ax-appshell__foot", children: account }) : null
94
+ ] }),
95
+ /* @__PURE__ */ jsxs("main", { className: "ax-appshell__main", children: [
96
+ /* @__PURE__ */ jsxs("header", { className: "ax-appshell__top", children: [
97
+ /* @__PURE__ */ jsx(
98
+ "button",
99
+ {
100
+ className: "ax-appshell__burger",
101
+ "aria-label": "Menu",
102
+ onClick: () => setMenuOpen(true),
103
+ children: /* @__PURE__ */ jsx(Icon, { name: "menu", size: 17 })
104
+ }
105
+ ),
106
+ crumb ? /* @__PURE__ */ jsx("span", { className: "ax-appshell__crumb", children: crumb }) : null,
107
+ /* @__PURE__ */ jsx("span", { className: "ax-appshell__sp" }),
108
+ actions
109
+ ] }),
110
+ /* @__PURE__ */ jsx("div", { className: "ax-appshell__body", children })
111
+ ] })
112
+ ] });
113
+ }
114
+ export {
115
+ AppShell
116
+ };
117
+ //# sourceMappingURL=AppShell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppShell.js","sources":["../../../src/components/layout/AppShell.jsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { BrandMark } from \"../utilities/BrandMark.jsx\";\nimport { Icon } from \"../utilities/Icon.jsx\";\n\n// AppShell — the standard product frame: fixed sidebar (brand · nav · account)\n// + main column (topbar · content). All regions are slots; nav can be\n// controlled or self-managed. Content goes in `children`.\nconst AX_APPSHELL_CSS = `\n.ax-appshell { display: grid; grid-template-columns: 240px 1fr; height: 100%; background: var(--surface-page); overflow: hidden; }\n.ax-appshell__sb { display: flex; flex-direction: column; background: var(--surface-panel); border-right: 1px solid var(--border-default); min-height: 0; }\n.ax-appshell__brand { display: flex; align-items: center; gap: 9px; padding: 18px 18px 14px; }\n.ax-appshell__group { padding: 10px 12px 4px; }\n.ax-appshell__nav { display: flex; flex-direction: column; gap: 2px; padding: 0 10px; }\n.ax-appshell__item { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: var(--radius-2);\n color: var(--text-muted); cursor: pointer; font-size: var(--text-sm); border: none; background: none; text-align: left;\n font-family: inherit; transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }\n.ax-appshell__item:hover { background: var(--bg-3); color: var(--text-body); }\n.ax-appshell__item[data-on=\"true\"] { background: var(--accent); color: var(--accent-fg); }\n.ax-appshell__foot { margin-top: auto; padding: 12px; border-top: 1px solid var(--border-default); }\n.ax-appshell__main { display: flex; flex-direction: column; overflow: hidden; min-width: 0; }\n.ax-appshell__top { display: flex; align-items: center; gap: 12px; height: 56px; flex: none; padding: 0 22px; border-bottom: 1px solid var(--border-default); }\n.ax-appshell__crumb { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--text-muted); }\n.ax-appshell__crumb b { color: var(--text-body); font-weight: var(--weight-medium); }\n.ax-appshell__sp { flex: 1; }\n.ax-appshell__body { flex: 1; padding: 22px; overflow-y: auto; }\n.ax-appshell__burger { display: none; }\n.ax-appshell__scrim { display: none; }\n@media (max-width: 860px) {\n .ax-appshell { grid-template-columns: 1fr; }\n .ax-appshell__sb { position: fixed; top: 0; left: 0; bottom: 0; width: 264px; z-index: 40;\n transform: translateX(-100%); transition: transform var(--dur-2) var(--ease-out); box-shadow: var(--shadow-3); }\n .ax-appshell__sb[data-open=\"true\"] { transform: none; }\n .ax-appshell__scrim { display: block; position: fixed; inset: 0; z-index: 39; background: var(--bg-overlay);\n opacity: 0; pointer-events: none; transition: opacity var(--dur-2) var(--ease-out); }\n .ax-appshell__scrim[data-open=\"true\"] { opacity: 1; pointer-events: auto; }\n .ax-appshell__burger { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;\n flex: none; margin-left: -6px; border: 1px solid var(--border-default); border-radius: var(--radius-2);\n background: none; color: var(--text-muted); cursor: pointer; }\n .ax-appshell__burger:hover { color: var(--text-body); border-color: var(--border-strong); }\n .ax-appshell__top { padding: 0 16px; }\n .ax-appshell__body { padding: 18px 16px; }\n}\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-appshell-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-appshell-css\";\n s.textContent = AX_APPSHELL_CSS;\n document.head.appendChild(s);\n}\n\nexport function AppShell({\n brand,\n nav = [],\n navLabel = \"Navigate\",\n activeId,\n onNavigate,\n account,\n crumb,\n actions,\n children,\n}) {\n const [internal, setInternal] = useState(nav[0] && nav[0].id);\n const [menuOpen, setMenuOpen] = useState(false);\n const active = activeId !== undefined ? activeId : internal;\n const go = (id) => {\n if (onNavigate) onNavigate(id);\n else setInternal(id);\n setMenuOpen(false);\n };\n\n return (\n <div className=\"ax-appshell\">\n <div\n className=\"ax-appshell__scrim\"\n data-open={menuOpen}\n onClick={() => setMenuOpen(false)}\n ></div>\n <aside className=\"ax-appshell__sb\" data-open={menuOpen}>\n <div className=\"ax-appshell__brand\">\n {brand || <BrandMark size={20} wordmark blink={false} />}\n </div>\n {nav.length ? (\n <React.Fragment>\n <div className=\"ax-appshell__group\">\n <span className=\"ax-label\">{navLabel}</span>\n </div>\n <nav className=\"ax-appshell__nav\">\n {nav.map((n) => (\n <button\n key={n.id}\n className=\"ax-appshell__item\"\n data-on={active === n.id}\n onClick={() => go(n.id)}\n >\n {n.icon || null}\n {n.label}\n </button>\n ))}\n </nav>\n </React.Fragment>\n ) : null}\n {account ? <div className=\"ax-appshell__foot\">{account}</div> : null}\n </aside>\n\n <main className=\"ax-appshell__main\">\n <header className=\"ax-appshell__top\">\n <button\n className=\"ax-appshell__burger\"\n aria-label=\"Menu\"\n onClick={() => setMenuOpen(true)}\n >\n <Icon name=\"menu\" size={17} />\n </button>\n {crumb ? <span className=\"ax-appshell__crumb\">{crumb}</span> : null}\n <span className=\"ax-appshell__sp\"></span>\n {actions}\n </header>\n <div className=\"ax-appshell__body\">{children}</div>\n </main>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;AAOA,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqCxB,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;AAAA,EACA,MAAM,CAAA;AAAA,EACN,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAG;AACD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,EAAE;AAC5D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,SAAS,aAAa,SAAY,WAAW;AACnD,QAAM,KAAK,CAAC,OAAO;AACjB,QAAI,uBAAuB,EAAE;AAAA,qBACZ,EAAE;AACnB,gBAAY,KAAK;AAAA,EACnB;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,aAAW;AAAA,QACX,SAAS,MAAM,YAAY,KAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAElC,qBAAC,SAAA,EAAM,WAAU,mBAAkB,aAAW,UAC5C,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,sBACZ,UAAA,SAAS,oBAAC,WAAA,EAAU,MAAM,IAAI,UAAQ,MAAC,OAAO,MAAA,CAAO,GACxD;AAAA,MACC,IAAI,SACH,qBAAC,MAAM,UAAN,EACC,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,sBACb,UAAA,oBAAC,UAAK,WAAU,YAAY,oBAAS,EAAA,CACvC;AAAA,4BACC,OAAA,EAAI,WAAU,oBACZ,UAAA,IAAI,IAAI,CAAC,MACR;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAU;AAAA,YACV,WAAS,WAAW,EAAE;AAAA,YACtB,SAAS,MAAM,GAAG,EAAE,EAAE;AAAA,YAErB,UAAA;AAAA,cAAA,EAAE,QAAQ;AAAA,cACV,EAAE;AAAA,YAAA;AAAA,UAAA;AAAA,UANE,EAAE;AAAA,QAAA,CAQV,EAAA,CACH;AAAA,MAAA,EAAA,CACF,IACE;AAAA,MACH,UAAU,oBAAC,OAAA,EAAI,WAAU,qBAAqB,mBAAQ,IAAS;AAAA,IAAA,GAClE;AAAA,IAEA,qBAAC,QAAA,EAAK,WAAU,qBACd,UAAA;AAAA,MAAA,qBAAC,UAAA,EAAO,WAAU,oBAChB,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,cAAW;AAAA,YACX,SAAS,MAAM,YAAY,IAAI;AAAA,YAE/B,UAAA,oBAAC,MAAA,EAAK,MAAK,QAAO,MAAM,GAAA,CAAI;AAAA,UAAA;AAAA,QAAA;AAAA,QAE7B,QAAQ,oBAAC,QAAA,EAAK,WAAU,sBAAsB,iBAAM,IAAU;AAAA,QAC/D,oBAAC,QAAA,EAAK,WAAU,kBAAA,CAAkB;AAAA,QACjC;AAAA,MAAA,GACH;AAAA,MACA,oBAAC,OAAA,EAAI,WAAU,qBAAqB,SAAA,CAAS;AAAA,IAAA,EAAA,CAC/C;AAAA,EAAA,GACF;AAEJ;"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Two-pane AI-designer frame: a chat column + a live preview, separated by a
3
+ * draggable divider, collapsing to one pane with a segmented switcher on phones.
4
+ * Pure frame — pass `chat` / `preview` / top-bar slots and mount your own
5
+ * overlays (AuthDialog, IntegrationSettings, MarkupLayer) as siblings. The
6
+ * preview pane is position:relative so a MarkupLayer can fill it.
7
+ */
8
+ export interface DesignerShellProps {
9
+ /** Top-bar brand lockup. @default <BrandMark wordmark blink={false} /> */
10
+ brand?: React.ReactNode;
11
+ /** Breadcrumb after the brand. @default "设计器" */
12
+ crumb?: React.ReactNode;
13
+ /** Centered top-bar title slot. */
14
+ title?: React.ReactNode;
15
+ /** Top-bar actions (before the account control). */
16
+ actions?: React.ReactNode;
17
+ /** Account control, pinned to the far right (auto-separated from actions). */
18
+ account?: React.ReactNode;
19
+ /** Left pane content (thread + composer). */
20
+ chat?: React.ReactNode;
21
+ /** Right pane content (preview); the pane is position:relative. */
22
+ preview?: React.ReactNode;
23
+ /** Controlled chat-pane width fraction (0–1). Omit for uncontrolled (uses defaultSplit). */
24
+ split?: number;
25
+ /** Fires with the new fraction on divider drag — wire to a slider/Tweak so drag writes back. */
26
+ onSplitChange?: (fraction: number) => void;
27
+ /** Initial chat-pane width fraction when uncontrolled. @default 0.42 */
28
+ defaultSplit?: number;
29
+ /** Min/max chat-pane fraction while dragging. @default 0.28 / 0.7 */
30
+ minSplit?: number;
31
+ maxSplit?: number;
32
+ /** Phone segmented-switcher labels — any node (icon + count badge ok; use class `ax-dshell__mcount` for a count). @default { chat: "对话", preview: "预览" } */
33
+ mobileLabels?: { chat: React.ReactNode; preview: React.ReactNode };
34
+ /** Controlled phone pane: "chat" | "preview". Omit for uncontrolled (starts on chat). */
35
+ mobileView?: "chat" | "preview";
36
+ /** Fires when the phone switcher changes — set it to auto-jump to preview after generating. */
37
+ onMobileViewChange?: (view: "chat" | "preview") => void;
38
+ }
39
+ export declare function DesignerShell(props: DesignerShellProps): JSX.Element;
@@ -0,0 +1,146 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import React, { useState, useRef, useEffect } from "react";
3
+ import { BrandMark } from "../utilities/BrandMark.js";
4
+ const AX_DESIGNERSHELL_CSS = `
5
+ .ax-dshell { display: flex; flex-direction: column; height: 100%; background: var(--surface-page); }
6
+ .ax-dshell__top { display: flex; align-items: center; gap: 16px; height: var(--topbar-h); flex: none; padding: 0 16px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }
7
+ /* helper: use on a pane's sub-header (e.g. the preview tabs bar) so both panes' bars share --bar-h and line up */
8
+ .ax-dshell__panebar { display: flex; align-items: center; gap: 12px; height: var(--bar-h); flex: none; padding: 0 16px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }
9
+ .ax-dshell__div { color: var(--text-faint); }
10
+ .ax-dshell__crumb { font-family: var(--font-mono); font-size: 13px; color: var(--text-muted); }
11
+ .ax-dshell__title { flex: 1; display: flex; align-items: center; gap: 10px; justify-content: center; }
12
+ .ax-dshell__actions { display: flex; align-items: center; gap: 8px; }
13
+ .ax-dshell__sep { width: 1px; height: 20px; background: var(--border-default); margin: 0 2px; flex: none; }
14
+ .ax-dshell__split { flex: 1; display: flex; min-height: 0; }
15
+ .ax-dshell__pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
16
+ .ax-dshell__pane--preview { flex: 1; position: relative; }
17
+ .ax-dshell__divider { width: 9px; flex: none; cursor: col-resize; display: flex; align-items: center; justify-content: center;
18
+ background: var(--surface-page); border-left: 1px solid var(--border-default); border-right: 1px solid var(--border-default); }
19
+ .ax-dshell__grip { width: 2px; height: 26px; border-radius: 2px; background: var(--border-strong); transition: background var(--dur-1) var(--ease-out); }
20
+ .ax-dshell__divider:hover .ax-dshell__grip { background: var(--text-faint); }
21
+ .ax-dshell__mbar { display: none; }
22
+ @media (max-width: 720px) {
23
+ .ax-dshell__split { flex-direction: column; }
24
+ .ax-dshell__divider { display: none; }
25
+ .ax-dshell__pane { width: 100% !important; flex: 1; }
26
+ .ax-dshell__split[data-mview="chat"] .ax-dshell__pane--preview { display: none; }
27
+ .ax-dshell__split[data-mview="preview"] .ax-dshell__pane--chat { display: none; }
28
+ .ax-dshell__div, .ax-dshell__crumb { display: none; }
29
+ .ax-dshell__mbar { display: flex; flex: none; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }
30
+ .ax-dshell__mseg { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 38px; border: 1px solid var(--border-default);
31
+ background: var(--surface-page); border-radius: var(--radius-2); font-family: var(--font-body); font-size: var(--text-sm); color: var(--text-muted); cursor: pointer; }
32
+ .ax-dshell__mseg.is-on { background: var(--surface-card); border-color: var(--border-strong); color: var(--text-body); }
33
+ .ax-dshell__mcount { font-family: var(--font-mono); font-size: 11px; line-height: 16px; color: var(--text-faint); border: 1px solid var(--border-default); border-radius: var(--radius-1); padding: 0 5px; }
34
+ .ax-dshell__mseg.is-on .ax-dshell__mcount { color: var(--text-muted); }
35
+ }
36
+ `;
37
+ if (typeof document !== "undefined" && !document.getElementById("ax-dshell-css")) {
38
+ const s = document.createElement("style");
39
+ s.id = "ax-dshell-css";
40
+ s.textContent = AX_DESIGNERSHELL_CSS;
41
+ document.head.appendChild(s);
42
+ }
43
+ function DesignerShell({
44
+ brand,
45
+ crumb = "设计器",
46
+ title,
47
+ actions,
48
+ account,
49
+ chat,
50
+ preview,
51
+ split,
52
+ onSplitChange,
53
+ defaultSplit = 0.42,
54
+ minSplit = 0.28,
55
+ maxSplit = 0.7,
56
+ mobileLabels = { chat: "对话", preview: "预览" },
57
+ mobileView,
58
+ onMobileViewChange
59
+ }) {
60
+ const controlled = split !== void 0;
61
+ const [internalW, setInternalW] = useState(defaultSplit);
62
+ const leftW = controlled ? split : internalW;
63
+ const [internalMV, setInternalMV] = useState("chat");
64
+ const mview = mobileView !== void 0 ? mobileView : internalMV;
65
+ const setView = (v) => {
66
+ if (onMobileViewChange) onMobileViewChange(v);
67
+ if (mobileView === void 0) setInternalMV(v);
68
+ };
69
+ const dragging = useRef(false);
70
+ const splitRef = useRef(null);
71
+ const applyRef = useRef(null);
72
+ applyRef.current = (f) => {
73
+ const v = Math.min(maxSplit, Math.max(minSplit, f));
74
+ if (onSplitChange) onSplitChange(v);
75
+ if (!controlled) setInternalW(v);
76
+ };
77
+ useEffect(() => {
78
+ const move = (e) => {
79
+ if (!dragging.current || !splitRef.current) return;
80
+ const r = splitRef.current.getBoundingClientRect();
81
+ applyRef.current((e.clientX - r.left) / r.width);
82
+ };
83
+ const up = () => {
84
+ dragging.current = false;
85
+ document.body.style.cursor = "";
86
+ };
87
+ window.addEventListener("mousemove", move);
88
+ window.addEventListener("mouseup", up);
89
+ return () => {
90
+ window.removeEventListener("mousemove", move);
91
+ window.removeEventListener("mouseup", up);
92
+ };
93
+ }, []);
94
+ return /* @__PURE__ */ jsxs("div", { className: "ax-dshell", children: [
95
+ /* @__PURE__ */ jsxs("div", { className: "ax-dshell__top", children: [
96
+ brand || /* @__PURE__ */ jsx(BrandMark, { size: 18, wordmark: true, blink: false }),
97
+ crumb ? /* @__PURE__ */ jsxs(React.Fragment, { children: [
98
+ /* @__PURE__ */ jsx("span", { className: "ax-dshell__div", children: "/" }),
99
+ /* @__PURE__ */ jsx("span", { className: "ax-dshell__crumb", children: crumb })
100
+ ] }) : null,
101
+ /* @__PURE__ */ jsx("div", { className: "ax-dshell__title", children: title }),
102
+ /* @__PURE__ */ jsxs("div", { className: "ax-dshell__actions", children: [
103
+ actions,
104
+ actions && account ? /* @__PURE__ */ jsx("span", { className: "ax-dshell__sep" }) : null,
105
+ account
106
+ ] })
107
+ ] }),
108
+ /* @__PURE__ */ jsxs("div", { className: "ax-dshell__mbar", children: [
109
+ /* @__PURE__ */ jsx(
110
+ "button",
111
+ {
112
+ className: "ax-dshell__mseg" + (mview === "chat" ? " is-on" : ""),
113
+ onClick: () => setView("chat"),
114
+ children: mobileLabels.chat
115
+ }
116
+ ),
117
+ /* @__PURE__ */ jsx(
118
+ "button",
119
+ {
120
+ className: "ax-dshell__mseg" + (mview === "preview" ? " is-on" : ""),
121
+ onClick: () => setView("preview"),
122
+ children: mobileLabels.preview
123
+ }
124
+ )
125
+ ] }),
126
+ /* @__PURE__ */ jsxs("div", { className: "ax-dshell__split", ref: splitRef, "data-mview": mview, children: [
127
+ /* @__PURE__ */ jsx("div", { className: "ax-dshell__pane ax-dshell__pane--chat", style: { width: leftW * 100 + "%" }, children: chat }),
128
+ /* @__PURE__ */ jsx(
129
+ "div",
130
+ {
131
+ className: "ax-dshell__divider",
132
+ onMouseDown: () => {
133
+ dragging.current = true;
134
+ document.body.style.cursor = "col-resize";
135
+ },
136
+ children: /* @__PURE__ */ jsx("span", { className: "ax-dshell__grip" })
137
+ }
138
+ ),
139
+ /* @__PURE__ */ jsx("div", { className: "ax-dshell__pane ax-dshell__pane--preview", children: preview })
140
+ ] })
141
+ ] });
142
+ }
143
+ export {
144
+ DesignerShell
145
+ };
146
+ //# sourceMappingURL=DesignerShell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DesignerShell.js","sources":["../../../src/components/layout/DesignerShell.jsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport { BrandMark } from \"../utilities/BrandMark.jsx\";\n\n// DesignerShell — the two-pane \"AI designer\" frame: a chat column on the left\n// and a live preview on the right, separated by a draggable divider, collapsing\n// to a single pane with a segmented switcher on phones. Pure frame: pass `chat`\n// and `preview` nodes plus top-bar slots; mount your own overlays (AuthDialog,\n// IntegrationSettings, MarkupLayer) as siblings.\nconst AX_DESIGNERSHELL_CSS = `\n.ax-dshell { display: flex; flex-direction: column; height: 100%; background: var(--surface-page); }\n.ax-dshell__top { display: flex; align-items: center; gap: 16px; height: var(--topbar-h); flex: none; padding: 0 16px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }\n/* helper: use on a pane's sub-header (e.g. the preview tabs bar) so both panes' bars share --bar-h and line up */\n.ax-dshell__panebar { display: flex; align-items: center; gap: 12px; height: var(--bar-h); flex: none; padding: 0 16px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }\n.ax-dshell__div { color: var(--text-faint); }\n.ax-dshell__crumb { font-family: var(--font-mono); font-size: 13px; color: var(--text-muted); }\n.ax-dshell__title { flex: 1; display: flex; align-items: center; gap: 10px; justify-content: center; }\n.ax-dshell__actions { display: flex; align-items: center; gap: 8px; }\n.ax-dshell__sep { width: 1px; height: 20px; background: var(--border-default); margin: 0 2px; flex: none; }\n.ax-dshell__split { flex: 1; display: flex; min-height: 0; }\n.ax-dshell__pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; }\n.ax-dshell__pane--preview { flex: 1; position: relative; }\n.ax-dshell__divider { width: 9px; flex: none; cursor: col-resize; display: flex; align-items: center; justify-content: center;\n background: var(--surface-page); border-left: 1px solid var(--border-default); border-right: 1px solid var(--border-default); }\n.ax-dshell__grip { width: 2px; height: 26px; border-radius: 2px; background: var(--border-strong); transition: background var(--dur-1) var(--ease-out); }\n.ax-dshell__divider:hover .ax-dshell__grip { background: var(--text-faint); }\n.ax-dshell__mbar { display: none; }\n@media (max-width: 720px) {\n .ax-dshell__split { flex-direction: column; }\n .ax-dshell__divider { display: none; }\n .ax-dshell__pane { width: 100% !important; flex: 1; }\n .ax-dshell__split[data-mview=\"chat\"] .ax-dshell__pane--preview { display: none; }\n .ax-dshell__split[data-mview=\"preview\"] .ax-dshell__pane--chat { display: none; }\n .ax-dshell__div, .ax-dshell__crumb { display: none; }\n .ax-dshell__mbar { display: flex; flex: none; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }\n .ax-dshell__mseg { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 38px; border: 1px solid var(--border-default);\n background: var(--surface-page); border-radius: var(--radius-2); font-family: var(--font-body); font-size: var(--text-sm); color: var(--text-muted); cursor: pointer; }\n .ax-dshell__mseg.is-on { background: var(--surface-card); border-color: var(--border-strong); color: var(--text-body); }\n .ax-dshell__mcount { font-family: var(--font-mono); font-size: 11px; line-height: 16px; color: var(--text-faint); border: 1px solid var(--border-default); border-radius: var(--radius-1); padding: 0 5px; }\n .ax-dshell__mseg.is-on .ax-dshell__mcount { color: var(--text-muted); }\n}\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-dshell-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-dshell-css\";\n s.textContent = AX_DESIGNERSHELL_CSS;\n document.head.appendChild(s);\n}\n\nexport function DesignerShell({\n brand,\n crumb = \"设计器\",\n title,\n actions,\n account,\n chat,\n preview,\n split,\n onSplitChange,\n defaultSplit = 0.42,\n minSplit = 0.28,\n maxSplit = 0.7,\n mobileLabels = { chat: \"对话\", preview: \"预览\" },\n mobileView,\n onMobileViewChange,\n}) {\n const controlled = split !== undefined;\n const [internalW, setInternalW] = useState(defaultSplit);\n const leftW = controlled ? split : internalW;\n const [internalMV, setInternalMV] = useState(\"chat\");\n const mview = mobileView !== undefined ? mobileView : internalMV;\n const setView = (v) => {\n if (onMobileViewChange) onMobileViewChange(v);\n if (mobileView === undefined) setInternalMV(v);\n };\n const dragging = useRef(false);\n const splitRef = useRef(null);\n\n // latest applier (clamp + write back, controlled or internal), kept in a ref so\n // the window drag listeners always see current props without re-binding.\n const applyRef = useRef(null);\n applyRef.current = (f) => {\n const v = Math.min(maxSplit, Math.max(minSplit, f));\n if (onSplitChange) onSplitChange(v); // drag writes back to a controlled value (e.g. a slider)\n if (!controlled) setInternalW(v);\n };\n\n useEffect(() => {\n const move = (e) => {\n if (!dragging.current || !splitRef.current) return;\n const r = splitRef.current.getBoundingClientRect();\n applyRef.current((e.clientX - r.left) / r.width);\n };\n const up = () => {\n dragging.current = false;\n document.body.style.cursor = \"\";\n };\n window.addEventListener(\"mousemove\", move);\n window.addEventListener(\"mouseup\", up);\n return () => {\n window.removeEventListener(\"mousemove\", move);\n window.removeEventListener(\"mouseup\", up);\n };\n }, []);\n\n return (\n <div className=\"ax-dshell\">\n <div className=\"ax-dshell__top\">\n {brand || <BrandMark size={18} wordmark blink={false} />}\n {crumb ? (\n <React.Fragment>\n <span className=\"ax-dshell__div\">/</span>\n <span className=\"ax-dshell__crumb\">{crumb}</span>\n </React.Fragment>\n ) : null}\n <div className=\"ax-dshell__title\">{title}</div>\n <div className=\"ax-dshell__actions\">\n {actions}\n {actions && account ? <span className=\"ax-dshell__sep\"></span> : null}\n {account}\n </div>\n </div>\n\n <div className=\"ax-dshell__mbar\">\n <button\n className={\"ax-dshell__mseg\" + (mview === \"chat\" ? \" is-on\" : \"\")}\n onClick={() => setView(\"chat\")}\n >\n {mobileLabels.chat}\n </button>\n <button\n className={\"ax-dshell__mseg\" + (mview === \"preview\" ? \" is-on\" : \"\")}\n onClick={() => setView(\"preview\")}\n >\n {mobileLabels.preview}\n </button>\n </div>\n\n <div className=\"ax-dshell__split\" ref={splitRef} data-mview={mview}>\n <div className=\"ax-dshell__pane ax-dshell__pane--chat\" style={{ width: leftW * 100 + \"%\" }}>\n {chat}\n </div>\n <div\n className=\"ax-dshell__divider\"\n onMouseDown={() => {\n dragging.current = true;\n document.body.style.cursor = \"col-resize\";\n }}\n >\n <span className=\"ax-dshell__grip\"></span>\n </div>\n <div className=\"ax-dshell__pane ax-dshell__pane--preview\">{preview}</div>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;AAQA,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkC7B,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,eAAe,GAAG;AAChF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,WAAW;AAAA,EACX,WAAW;AAAA,EACX,eAAe,EAAE,MAAM,MAAM,SAAS,KAAA;AAAA,EACtC;AAAA,EACA;AACF,GAAG;AACD,QAAM,aAAa,UAAU;AAC7B,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,YAAY;AACvD,QAAM,QAAQ,aAAa,QAAQ;AACnC,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,MAAM;AACnD,QAAM,QAAQ,eAAe,SAAY,aAAa;AACtD,QAAM,UAAU,CAAC,MAAM;AACrB,QAAI,uCAAuC,CAAC;AAC5C,QAAI,eAAe,OAAW,eAAc,CAAC;AAAA,EAC/C;AACA,QAAM,WAAW,OAAO,KAAK;AAC7B,QAAM,WAAW,OAAO,IAAI;AAI5B,QAAM,WAAW,OAAO,IAAI;AAC5B,WAAS,UAAU,CAAC,MAAM;AACxB,UAAM,IAAI,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,CAAC,CAAC;AAClD,QAAI,6BAA6B,CAAC;AAClC,QAAI,CAAC,WAAY,cAAa,CAAC;AAAA,EACjC;AAEA,YAAU,MAAM;AACd,UAAM,OAAO,CAAC,MAAM;AAClB,UAAI,CAAC,SAAS,WAAW,CAAC,SAAS,QAAS;AAC5C,YAAM,IAAI,SAAS,QAAQ,sBAAA;AAC3B,eAAS,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK;AAAA,IACjD;AACA,UAAM,KAAK,MAAM;AACf,eAAS,UAAU;AACnB,eAAS,KAAK,MAAM,SAAS;AAAA,IAC/B;AACA,WAAO,iBAAiB,aAAa,IAAI;AACzC,WAAO,iBAAiB,WAAW,EAAE;AACrC,WAAO,MAAM;AACX,aAAO,oBAAoB,aAAa,IAAI;AAC5C,aAAO,oBAAoB,WAAW,EAAE;AAAA,IAC1C;AAAA,EACF,GAAG,CAAA,CAAE;AAEL,SACE,qBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,MAAA,6BAAU,WAAA,EAAU,MAAM,IAAI,UAAQ,MAAC,OAAO,OAAO;AAAA,MACrD,QACC,qBAAC,MAAM,UAAN,EACC,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,kBAAiB,UAAA,KAAC;AAAA,QAClC,oBAAC,QAAA,EAAK,WAAU,oBAAoB,UAAA,MAAA,CAAM;AAAA,MAAA,EAAA,CAC5C,IACE;AAAA,MACJ,oBAAC,OAAA,EAAI,WAAU,oBAAoB,UAAA,OAAM;AAAA,MACzC,qBAAC,OAAA,EAAI,WAAU,sBACZ,UAAA;AAAA,QAAA;AAAA,QACA,WAAW,UAAU,oBAAC,QAAA,EAAK,WAAU,kBAAiB,IAAU;AAAA,QAChE;AAAA,MAAA,EAAA,CACH;AAAA,IAAA,GACF;AAAA,IAEA,qBAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,qBAAqB,UAAU,SAAS,WAAW;AAAA,UAC9D,SAAS,MAAM,QAAQ,MAAM;AAAA,UAE5B,UAAA,aAAa;AAAA,QAAA;AAAA,MAAA;AAAA,MAEhB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAW,qBAAqB,UAAU,YAAY,WAAW;AAAA,UACjE,SAAS,MAAM,QAAQ,SAAS;AAAA,UAE/B,UAAA,aAAa;AAAA,QAAA;AAAA,MAAA;AAAA,IAChB,GACF;AAAA,yBAEC,OAAA,EAAI,WAAU,oBAAmB,KAAK,UAAU,cAAY,OAC3D,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,yCAAwC,OAAO,EAAE,OAAO,QAAQ,MAAM,IAAA,GAClF,UAAA,KAAA,CACH;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,aAAa,MAAM;AACjB,qBAAS,UAAU;AACnB,qBAAS,KAAK,MAAM,SAAS;AAAA,UAC/B;AAAA,UAEA,UAAA,oBAAC,QAAA,EAAK,WAAU,kBAAA,CAAkB;AAAA,QAAA;AAAA,MAAA;AAAA,MAEpC,oBAAC,OAAA,EAAI,WAAU,4CAA4C,UAAA,QAAA,CAAQ;AAAA,IAAA,EAAA,CACrE;AAAA,EAAA,GACF;AAEJ;"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Three-pane documentation frame: left section nav, centered article, right
3
+ * on-this-page TOC. The article is `children`; nav + TOC are data-driven and
4
+ * controlled (via active/on props) or self-managed. Collapses to two panes < 1080px.
5
+ */
6
+ export interface DocsSection {
7
+ title: string;
8
+ items: string[];
9
+ }
10
+ export interface DocsLayoutProps {
11
+ /** Nav brand lockup. @default <BrandMark wordmark blink={false} /> */
12
+ brand?: React.ReactNode;
13
+ sections?: DocsSection[];
14
+ activeItem?: string;
15
+ onNavigate?: (item: string) => void;
16
+ toc?: string[];
17
+ activeToc?: string;
18
+ onTocChange?: (item: string) => void;
19
+ /** @default "On this page" */
20
+ tocLabel?: string;
21
+ /** Article content. */
22
+ children?: React.ReactNode;
23
+ }
24
+ export declare function DocsLayout(props: DocsLayoutProps): JSX.Element;
@@ -0,0 +1,113 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { BrandMark } from "../utilities/BrandMark.js";
4
+ import { Icon } from "../utilities/Icon.js";
5
+ const AX_DOCS_CSS = `
6
+ .ax-docs { display: grid; grid-template-columns: 252px minmax(0,1fr) 220px; height: 100%; background: var(--surface-page); overflow: hidden; }
7
+ .ax-docs__nav { border-right: 1px solid var(--border-default); background: var(--surface-panel); overflow-y: auto; padding: 18px 0 32px; }
8
+ .ax-docs__brand { display: flex; align-items: center; gap: 9px; padding: 0 20px 16px; }
9
+ .ax-docs__sec { padding: 14px 20px 6px; }
10
+ .ax-docs__list { display: flex; flex-direction: column; padding: 0 12px; }
11
+ .ax-docs__item { padding: 7px 10px; border-radius: var(--radius-2); font-size: var(--text-sm); color: var(--text-muted); cursor: pointer;
12
+ border: none; background: none; text-align: left; font-family: inherit; transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }
13
+ .ax-docs__item:hover { background: var(--bg-3); color: var(--text-body); }
14
+ .ax-docs__item[data-on="true"] { color: var(--text-body); font-weight: var(--weight-medium); background: var(--bg-3); }
15
+ .ax-docs__art { overflow-y: auto; }
16
+ .ax-docs__artinner { max-width: 680px; margin: 0 auto; padding: 56px 40px 96px; }
17
+ .ax-docs__toc { border-left: 1px solid var(--border-default); padding: 56px 22px; overflow-y: auto; }
18
+ .ax-docs__tochead { margin-bottom: 14px; }
19
+ .ax-docs__toclist { display: flex; flex-direction: column; gap: 9px; border-left: 1px solid var(--border-default); }
20
+ .ax-docs__toclink { padding-left: 14px; margin-left: -1px; font-size: var(--text-sm); color: var(--text-muted); cursor: pointer; border-left: 2px solid transparent; }
21
+ .ax-docs__toclink[data-on="true"] { color: var(--text-body); border-left-color: var(--accent); }
22
+ .ax-docs__mtop { display: none; }
23
+ .ax-docs__burger { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; flex: none;
24
+ border: 1px solid var(--border-default); border-radius: var(--radius-2); background: none; color: var(--text-muted); cursor: pointer; }
25
+ .ax-docs__burger:hover { color: var(--text-body); border-color: var(--border-strong); }
26
+ .ax-docs__scrim { display: none; }
27
+ @media (max-width: 1080px) { .ax-docs { grid-template-columns: 252px 1fr; } .ax-docs__toc { display: none; } }
28
+ @media (max-width: 760px) {
29
+ .ax-docs { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
30
+ .ax-docs__mtop { display: flex; align-items: center; gap: 12px; height: 52px; flex: none; padding: 0 16px;
31
+ border-bottom: 1px solid var(--border-default); background: var(--surface-panel); grid-column: 1; }
32
+ .ax-docs__nav { position: fixed; top: 0; left: 0; bottom: 0; width: 264px; z-index: 40;
33
+ transform: translateX(-100%); transition: transform var(--dur-2) var(--ease-out); box-shadow: var(--shadow-3); }
34
+ .ax-docs__nav[data-open="true"] { transform: none; }
35
+ .ax-docs__scrim { display: block; position: fixed; inset: 0; z-index: 39; background: var(--bg-overlay);
36
+ opacity: 0; pointer-events: none; transition: opacity var(--dur-2) var(--ease-out); }
37
+ .ax-docs__scrim[data-open="true"] { opacity: 1; pointer-events: auto; }
38
+ .ax-docs__artinner { padding: 32px 18px 72px; }
39
+ }
40
+ `;
41
+ if (typeof document !== "undefined" && !document.getElementById("ax-docs-css")) {
42
+ const s = document.createElement("style");
43
+ s.id = "ax-docs-css";
44
+ s.textContent = AX_DOCS_CSS;
45
+ document.head.appendChild(s);
46
+ }
47
+ function DocsLayout({
48
+ brand,
49
+ sections = [],
50
+ activeItem,
51
+ onNavigate,
52
+ toc = [],
53
+ activeToc,
54
+ onTocChange,
55
+ tocLabel = "On this page",
56
+ children
57
+ }) {
58
+ const [navInt, setNavInt] = useState(activeItem);
59
+ const [tocInt, setTocInt] = useState(activeToc || toc[0]);
60
+ const [navOpen, setNavOpen] = useState(false);
61
+ const active = activeItem !== void 0 ? activeItem : navInt;
62
+ const tocActive = activeToc !== void 0 ? activeToc : tocInt;
63
+ const go = (it) => {
64
+ if (onNavigate) onNavigate(it);
65
+ else setNavInt(it);
66
+ setNavOpen(false);
67
+ };
68
+ const goToc = (t) => {
69
+ if (onTocChange) onTocChange(t);
70
+ else setTocInt(t);
71
+ };
72
+ return /* @__PURE__ */ jsxs("div", { className: "ax-docs", children: [
73
+ /* @__PURE__ */ jsxs("header", { className: "ax-docs__mtop", children: [
74
+ /* @__PURE__ */ jsx("button", { className: "ax-docs__burger", "aria-label": "Menu", onClick: () => setNavOpen(true), children: /* @__PURE__ */ jsx(Icon, { name: "menu", size: 17 }) }),
75
+ brand || /* @__PURE__ */ jsx(BrandMark, { size: 18, wordmark: true, blink: false })
76
+ ] }),
77
+ /* @__PURE__ */ jsx("div", { className: "ax-docs__scrim", "data-open": navOpen, onClick: () => setNavOpen(false) }),
78
+ /* @__PURE__ */ jsxs("aside", { className: "ax-docs__nav", "data-open": navOpen, children: [
79
+ /* @__PURE__ */ jsx("div", { className: "ax-docs__brand", children: brand || /* @__PURE__ */ jsx(BrandMark, { size: 20, wordmark: true, blink: false }) }),
80
+ sections.map((s) => /* @__PURE__ */ jsxs("div", { children: [
81
+ /* @__PURE__ */ jsx("div", { className: "ax-docs__sec", children: /* @__PURE__ */ jsx("span", { className: "ax-label", children: s.title }) }),
82
+ /* @__PURE__ */ jsx("div", { className: "ax-docs__list", children: s.items.map((it) => /* @__PURE__ */ jsx(
83
+ "button",
84
+ {
85
+ className: "ax-docs__item",
86
+ "data-on": active === it,
87
+ onClick: () => go(it),
88
+ children: it
89
+ },
90
+ it
91
+ )) })
92
+ ] }, s.title))
93
+ ] }),
94
+ /* @__PURE__ */ jsx("article", { className: "ax-docs__art", children: /* @__PURE__ */ jsx("div", { className: "ax-docs__artinner", children }) }),
95
+ /* @__PURE__ */ jsxs("aside", { className: "ax-docs__toc", children: [
96
+ /* @__PURE__ */ jsx("div", { className: "ax-docs__tochead", children: /* @__PURE__ */ jsx("span", { className: "ax-label", children: tocLabel }) }),
97
+ /* @__PURE__ */ jsx("div", { className: "ax-docs__toclist", children: toc.map((t) => /* @__PURE__ */ jsx(
98
+ "span",
99
+ {
100
+ className: "ax-docs__toclink",
101
+ "data-on": tocActive === t,
102
+ onClick: () => goToc(t),
103
+ children: t
104
+ },
105
+ t
106
+ )) })
107
+ ] })
108
+ ] });
109
+ }
110
+ export {
111
+ DocsLayout
112
+ };
113
+ //# sourceMappingURL=DocsLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DocsLayout.js","sources":["../../../src/components/layout/DocsLayout.jsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { BrandMark } from \"../utilities/BrandMark.jsx\";\nimport { Icon } from \"../utilities/Icon.jsx\";\n\n// DocsLayout — three-pane documentation frame: left section nav, centered\n// article, right on-this-page TOC. Article goes in `children`; nav + TOC are\n// data-driven and controlled-or-self-managed.\nconst AX_DOCS_CSS = `\n.ax-docs { display: grid; grid-template-columns: 252px minmax(0,1fr) 220px; height: 100%; background: var(--surface-page); overflow: hidden; }\n.ax-docs__nav { border-right: 1px solid var(--border-default); background: var(--surface-panel); overflow-y: auto; padding: 18px 0 32px; }\n.ax-docs__brand { display: flex; align-items: center; gap: 9px; padding: 0 20px 16px; }\n.ax-docs__sec { padding: 14px 20px 6px; }\n.ax-docs__list { display: flex; flex-direction: column; padding: 0 12px; }\n.ax-docs__item { padding: 7px 10px; border-radius: var(--radius-2); font-size: var(--text-sm); color: var(--text-muted); cursor: pointer;\n border: none; background: none; text-align: left; font-family: inherit; transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out); }\n.ax-docs__item:hover { background: var(--bg-3); color: var(--text-body); }\n.ax-docs__item[data-on=\"true\"] { color: var(--text-body); font-weight: var(--weight-medium); background: var(--bg-3); }\n.ax-docs__art { overflow-y: auto; }\n.ax-docs__artinner { max-width: 680px; margin: 0 auto; padding: 56px 40px 96px; }\n.ax-docs__toc { border-left: 1px solid var(--border-default); padding: 56px 22px; overflow-y: auto; }\n.ax-docs__tochead { margin-bottom: 14px; }\n.ax-docs__toclist { display: flex; flex-direction: column; gap: 9px; border-left: 1px solid var(--border-default); }\n.ax-docs__toclink { padding-left: 14px; margin-left: -1px; font-size: var(--text-sm); color: var(--text-muted); cursor: pointer; border-left: 2px solid transparent; }\n.ax-docs__toclink[data-on=\"true\"] { color: var(--text-body); border-left-color: var(--accent); }\n.ax-docs__mtop { display: none; }\n.ax-docs__burger { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; flex: none;\n border: 1px solid var(--border-default); border-radius: var(--radius-2); background: none; color: var(--text-muted); cursor: pointer; }\n.ax-docs__burger:hover { color: var(--text-body); border-color: var(--border-strong); }\n.ax-docs__scrim { display: none; }\n@media (max-width: 1080px) { .ax-docs { grid-template-columns: 252px 1fr; } .ax-docs__toc { display: none; } }\n@media (max-width: 760px) {\n .ax-docs { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }\n .ax-docs__mtop { display: flex; align-items: center; gap: 12px; height: 52px; flex: none; padding: 0 16px;\n border-bottom: 1px solid var(--border-default); background: var(--surface-panel); grid-column: 1; }\n .ax-docs__nav { position: fixed; top: 0; left: 0; bottom: 0; width: 264px; z-index: 40;\n transform: translateX(-100%); transition: transform var(--dur-2) var(--ease-out); box-shadow: var(--shadow-3); }\n .ax-docs__nav[data-open=\"true\"] { transform: none; }\n .ax-docs__scrim { display: block; position: fixed; inset: 0; z-index: 39; background: var(--bg-overlay);\n opacity: 0; pointer-events: none; transition: opacity var(--dur-2) var(--ease-out); }\n .ax-docs__scrim[data-open=\"true\"] { opacity: 1; pointer-events: auto; }\n .ax-docs__artinner { padding: 32px 18px 72px; }\n}\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-docs-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-docs-css\";\n s.textContent = AX_DOCS_CSS;\n document.head.appendChild(s);\n}\n\nexport function DocsLayout({\n brand,\n sections = [],\n activeItem,\n onNavigate,\n toc = [],\n activeToc,\n onTocChange,\n tocLabel = \"On this page\",\n children,\n}) {\n const [navInt, setNavInt] = useState(activeItem);\n const [tocInt, setTocInt] = useState(activeToc || toc[0]);\n const [navOpen, setNavOpen] = useState(false);\n const active = activeItem !== undefined ? activeItem : navInt;\n const tocActive = activeToc !== undefined ? activeToc : tocInt;\n const go = (it) => {\n if (onNavigate) onNavigate(it);\n else setNavInt(it);\n setNavOpen(false);\n };\n const goToc = (t) => {\n if (onTocChange) onTocChange(t);\n else setTocInt(t);\n };\n\n return (\n <div className=\"ax-docs\">\n <header className=\"ax-docs__mtop\">\n <button className=\"ax-docs__burger\" aria-label=\"Menu\" onClick={() => setNavOpen(true)}>\n <Icon name=\"menu\" size={17} />\n </button>\n {brand || <BrandMark size={18} wordmark blink={false} />}\n </header>\n <div className=\"ax-docs__scrim\" data-open={navOpen} onClick={() => setNavOpen(false)}></div>\n <aside className=\"ax-docs__nav\" data-open={navOpen}>\n <div className=\"ax-docs__brand\">\n {brand || <BrandMark size={20} wordmark blink={false} />}\n </div>\n {sections.map((s) => (\n <div key={s.title}>\n <div className=\"ax-docs__sec\">\n <span className=\"ax-label\">{s.title}</span>\n </div>\n <div className=\"ax-docs__list\">\n {s.items.map((it) => (\n <button\n key={it}\n className=\"ax-docs__item\"\n data-on={active === it}\n onClick={() => go(it)}\n >\n {it}\n </button>\n ))}\n </div>\n </div>\n ))}\n </aside>\n\n <article className=\"ax-docs__art\">\n <div className=\"ax-docs__artinner\">{children}</div>\n </article>\n\n <aside className=\"ax-docs__toc\">\n <div className=\"ax-docs__tochead\">\n <span className=\"ax-label\">{tocLabel}</span>\n </div>\n <div className=\"ax-docs__toclist\">\n {toc.map((t) => (\n <span\n key={t}\n className=\"ax-docs__toclink\"\n data-on={tocActive === t}\n onClick={() => goToc(t)}\n >\n {t}\n </span>\n ))}\n </div>\n </aside>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}