@agent-native/core 0.40.2 → 0.41.1
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/README.md +11 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +57 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +16 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/pr-visual-recap-workflow.d.ts +11 -0
- package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -0
- package/dist/cli/pr-visual-recap-workflow.js +11 -0
- package/dist/cli/pr-visual-recap-workflow.js.map +1 -0
- package/dist/cli/recap.d.ts +52 -0
- package/dist/cli/recap.d.ts.map +1 -0
- package/dist/cli/recap.js +581 -0
- package/dist/cli/recap.js.map +1 -0
- package/dist/cli/skills.d.ts +17 -4
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +60 -16
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/templates-meta.js +1 -1
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +19 -4
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/blocks/index.d.ts +3 -0
- package/dist/client/blocks/index.d.ts.map +1 -1
- package/dist/client/blocks/index.js +3 -0
- package/dist/client/blocks/index.js.map +1 -1
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts +6 -0
- package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -0
- package/dist/client/blocks/library/AnnotatedCodeBlock.js +134 -0
- package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -0
- package/dist/client/blocks/library/HighlightedCode.d.ts +21 -1
- package/dist/client/blocks/library/HighlightedCode.d.ts.map +1 -1
- package/dist/client/blocks/library/HighlightedCode.js +86 -4
- package/dist/client/blocks/library/HighlightedCode.js.map +1 -1
- package/dist/client/blocks/library/annotated-code.config.d.ts +58 -0
- package/dist/client/blocks/library/annotated-code.config.d.ts.map +1 -0
- package/dist/client/blocks/library/annotated-code.config.js +53 -0
- package/dist/client/blocks/library/annotated-code.config.js.map +1 -0
- package/dist/client/blocks/library/checklist.js +2 -2
- package/dist/client/blocks/library/checklist.js.map +1 -1
- package/dist/client/blocks/library/code-highlight.d.ts +16 -0
- package/dist/client/blocks/library/code-highlight.d.ts.map +1 -0
- package/dist/client/blocks/library/code-highlight.js +160 -0
- package/dist/client/blocks/library/code-highlight.js.map +1 -0
- package/dist/client/blocks/library/code-tabs.config.d.ts +6 -0
- package/dist/client/blocks/library/code-tabs.config.d.ts.map +1 -1
- package/dist/client/blocks/library/code-tabs.config.js +1 -0
- package/dist/client/blocks/library/code-tabs.config.js.map +1 -1
- package/dist/client/blocks/library/code-tabs.d.ts.map +1 -1
- package/dist/client/blocks/library/code-tabs.js +35 -5
- package/dist/client/blocks/library/code-tabs.js.map +1 -1
- package/dist/client/blocks/library/code.config.d.ts +43 -0
- package/dist/client/blocks/library/code.config.d.ts.map +1 -0
- package/dist/client/blocks/library/code.config.js +34 -0
- package/dist/client/blocks/library/code.config.js.map +1 -0
- package/dist/client/blocks/library/code.d.ts +3 -0
- package/dist/client/blocks/library/code.d.ts.map +1 -0
- package/dist/client/blocks/library/code.js +95 -0
- package/dist/client/blocks/library/code.js.map +1 -0
- package/dist/client/blocks/library/dev-doc-ui.d.ts +2 -1
- package/dist/client/blocks/library/dev-doc-ui.d.ts.map +1 -1
- package/dist/client/blocks/library/dev-doc-ui.js +2 -1
- package/dist/client/blocks/library/dev-doc-ui.js.map +1 -1
- package/dist/client/blocks/library/server-specs.d.ts.map +1 -1
- package/dist/client/blocks/library/server-specs.js +21 -0
- package/dist/client/blocks/library/server-specs.js.map +1 -1
- package/dist/client/blocks/library/specs.d.ts +1 -1
- package/dist/client/blocks/library/specs.d.ts.map +1 -1
- package/dist/client/blocks/library/specs.js +30 -2
- package/dist/client/blocks/library/specs.js.map +1 -1
- package/dist/client/blocks/server.d.ts +1 -0
- package/dist/client/blocks/server.d.ts.map +1 -1
- package/dist/client/blocks/server.js +1 -0
- package/dist/client/blocks/server.js.map +1 -1
- package/dist/client/blocks/types.d.ts +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/extensions/ExtensionsListPage.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsListPage.js +28 -13
- package/dist/client/extensions/ExtensionsListPage.js.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionsSidebarSection.js +31 -9
- package/dist/client/extensions/ExtensionsSidebarSection.js.map +1 -1
- package/dist/client/rich-markdown-editor/CodeBlockNode.d.ts +49 -0
- package/dist/client/rich-markdown-editor/CodeBlockNode.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/CodeBlockNode.js +126 -0
- package/dist/client/rich-markdown-editor/CodeBlockNode.js.map +1 -0
- package/dist/client/rich-markdown-editor/RegistryBlockNode.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +26 -3
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
- package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +1 -1
- package/dist/client/rich-markdown-editor/extensions.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/extensions.js +8 -8
- package/dist/client/rich-markdown-editor/extensions.js.map +1 -1
- package/dist/client/rich-markdown-editor/index.d.ts +1 -0
- package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/index.js +1 -0
- package/dist/client/rich-markdown-editor/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/registrySlashCommands.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/registrySlashCommands.js +1 -0
- package/dist/client/rich-markdown-editor/registrySlashCommands.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +63 -2
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/routes.d.ts.map +1 -1
- package/dist/extensions/routes.js +24 -3
- package/dist/extensions/routes.js.map +1 -1
- package/dist/extensions/schema.d.ts +43 -2
- package/dist/extensions/schema.d.ts.map +1 -1
- package/dist/extensions/schema.js +12 -0
- package/dist/extensions/schema.js.map +1 -1
- package/dist/extensions/store.d.ts +20 -0
- package/dist/extensions/store.d.ts.map +1 -1
- package/dist/extensions/store.js +82 -3
- package/dist/extensions/store.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +13 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +11 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/recap-image-route.d.ts +8 -0
- package/dist/server/recap-image-route.d.ts.map +1 -0
- package/dist/server/recap-image-route.js +200 -0
- package/dist/server/recap-image-route.js.map +1 -0
- package/dist/server/recap-image-store.d.ts +41 -0
- package/dist/server/recap-image-store.d.ts.map +1 -0
- package/dist/server/recap-image-store.js +138 -0
- package/dist/server/recap-image-store.js.map +1 -0
- package/dist/styles/rich-markdown-editor.css +66 -17
- package/dist/templates/default/pnpm-workspace.yaml +7 -0
- package/dist/templates/workspace-root/package.json +0 -5
- package/dist/templates/workspace-root/pnpm-workspace.yaml +14 -0
- package/docs/content/cloneable-saas.md +10 -0
- package/docs/content/external-agents.md +4 -7
- package/docs/content/faq.md +10 -0
- package/docs/content/getting-started.md +11 -0
- package/docs/content/pr-visual-recap.md +103 -0
- package/docs/content/skills-guide.md +1 -3
- package/docs/content/template-assets.md +1 -4
- package/docs/content/template-design.md +0 -57
- package/docs/content/template-plan.md +22 -18
- package/docs/content/visual-plans.md +10 -7
- package/docs/content/what-is-agent-native.md +2 -0
- package/package.json +5 -1
- package/src/templates/default/pnpm-workspace.yaml +7 -0
- package/src/templates/workspace-root/package.json +0 -5
- package/src/templates/workspace-root/pnpm-workspace.yaml +14 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tabs.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"code-tabs.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoCxB,yEAAyE;AACzE,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE,CAAC;SACJ,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;QACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;QAC9C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;QAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;QAC9C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;KACvD,CAAC,CACH;SACA,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;CACX,CAAuC,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAiC;IACvD,GAAG,EAAE,UAAU;IACf,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IACxC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAc,MAAM,CAAC,IAAI,EAAE;KAC7C,CAAC;CACH,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { BlockMdxConfig } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the standard `code-tabs` block: its data schema and\n * MDX round-trip config. Shared by the server MDX adapter (a plan/content app\n * registers it via `@agent-native/core/blocks/server`) and the full client spec\n * (`code-tabs.tsx`). Keeping this React-free means importing it into a server\n * module never pulls React into the Nitro/SSR bundle.\n *\n * `code-tabs` is a STANDARD library block (a vertical file tab rail of Shiki-\n * highlighted code), shareable by any app. Its schema MUST stay data-compatible\n * with the legacy plan `code-tabs` branch of `planBlockSchema`, and the MDX\n * `tag` + attribute shape MUST match the legacy\n * `<CodeTabs … tabs={[…]} />` encoding (`plan-mdx.ts` `serializeBlock`/\n * `parseBlock`) so stored `.mdx` round-trips byte-compatibly.\n */\n\nexport interface CodeTabsTab {\n id: string;\n label: string;\n language?: string;\n code: string;\n caption?: string;\n /**\n * Lines shown before the pane collapses behind a \"Show N more lines\" toggle.\n * Omitted ⇒ the default cap (`DEFAULT_CODE_MAX_LINES`, 30). `0` ⇒ never\n * collapse (always show the whole snippet).\n */\n maxLines?: number;\n}\n\nexport interface CodeTabsData {\n tabs: CodeTabsTab[];\n}\n\n/** Matches the plan `idSchema` (`z.string().trim().min(1).max(120)`). */\nconst tabIdSchema = z.string().trim().min(1).max(120);\n\nexport const codeTabsSchema = z.object({\n tabs: z\n .array(\n z.object({\n id: tabIdSchema,\n label: z.string().trim().min(1).max(120),\n language: z.string().trim().max(40).optional(),\n code: z.string().max(100_000),\n caption: z.string().trim().max(400).optional(),\n maxLines: z.number().int().min(0).max(2000).optional(),\n }),\n )\n .min(1)\n .max(12),\n}) as unknown as z.ZodType<CodeTabsData>;\n\n/**\n * MDX config: `tabs` is a single JSON-encoded attribute and the block is\n * self-closing — exactly the legacy `<CodeTabs id … tabs={[…]} />` form.\n * `toAttrs` returns only `tabs`; `fromAttrs` reads the `tabs` array (defaulting\n * to `[]` for backward-compat with malformed/empty stored blocks, mirroring the\n * legacy `arrayAttr(node, \"tabs\") ?? []`).\n */\nexport const codeTabsMdx: BlockMdxConfig<CodeTabsData> = {\n tag: \"CodeTabs\",\n toAttrs: (data) => ({ tabs: data.tabs }),\n fromAttrs: (attrs) => ({\n tabs: attrs.array<CodeTabsTab>(\"tabs\") ?? [],\n }),\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAGL,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"code-tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAGL,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAmjB/B,eAAO,MAAM,aAAa,+CAYxB,CAAC"}
|
|
@@ -5,7 +5,7 @@ import { common, createLowlight } from "lowlight";
|
|
|
5
5
|
import { cn } from "../../utils.js";
|
|
6
6
|
import { defineBlock } from "../types.js";
|
|
7
7
|
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover.js";
|
|
8
|
-
import { CodeSurface } from "./HighlightedCode.js";
|
|
8
|
+
import { CodeSurface, DEFAULT_CODE_MAX_LINES } from "./HighlightedCode.js";
|
|
9
9
|
import { codeTabsSchema, codeTabsMdx, } from "./code-tabs.config.js";
|
|
10
10
|
/**
|
|
11
11
|
* Standard `code-tabs` block (STANDARD core library): a vertical file tab rail
|
|
@@ -151,10 +151,30 @@ function CodeTabsRead({ data, blockId, title }) {
|
|
|
151
151
|
const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];
|
|
152
152
|
return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsxs("div", { className: "grid overflow-hidden border-y border-plan-line md:grid-cols-[300px_minmax(0,1fr)]", children: [_jsx("div", { className: "border-plan-line md:border-r", children: data.tabs.map((tab) => (_jsxs("button", { type: "button", "data-plan-interactive": true, className: cn("flex w-full items-start gap-3 border-b border-plan-line px-4 py-4 text-left", tab.id === active?.id
|
|
153
153
|
? "bg-primary/10 text-plan-text dark:bg-primary/20"
|
|
154
|
-
: "text-plan-muted hover:bg-accent/30"), onClick: () => setActiveId(tab.id), children: [_jsx(IconCode, { className: "mt-0.5 size-4 shrink-0" }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate font-mono text-sm font-semibold", children: tab.label }), tab.caption && (_jsx("span", { className: "mt-1 block text-xs leading-5", children: tab.caption }))] })] }, tab.id))) }), _jsx("div", { className: "min-w-0 p-5", children: active && (_jsxs(_Fragment, { children: [_jsx("h3", { className: "text-2xl font-semibold tracking-tight", children: active.label }), active.caption && (_jsx("p", { className: "mt-2 text-plan-muted", children: active.caption })), _jsx(CodeSurface, { code: active.code, language: codeTabLanguage(active) })] })) })] })] }));
|
|
154
|
+
: "text-plan-muted hover:bg-accent/30"), onClick: () => setActiveId(tab.id), children: [_jsx(IconCode, { className: "mt-0.5 size-4 shrink-0" }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate font-mono text-sm font-semibold", children: tab.label }), tab.caption && (_jsx("span", { className: "mt-1 block text-xs leading-5", children: tab.caption }))] })] }, tab.id))) }), _jsx("div", { className: "min-w-0 p-5", children: active && (_jsxs(_Fragment, { children: [_jsx("h3", { className: "text-2xl font-semibold tracking-tight", children: active.label }), active.caption && (_jsx("p", { className: "mt-2 text-plan-muted", children: active.caption })), _jsx(CodeSurface, { code: active.code, language: codeTabLanguage(active), maxLines: active.maxLines })] })) })] })] }));
|
|
155
155
|
}
|
|
156
156
|
/* ── Edit (code text areas per tab) ────────────────────────────────────────── */
|
|
157
157
|
const inputClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
158
|
+
/** Language options for the per-tab picker; "" is the Auto-detect sentinel. */
|
|
159
|
+
const CODE_TAB_LANGUAGES = [
|
|
160
|
+
{ value: "", label: "Auto" },
|
|
161
|
+
{ value: "typescript", label: "TypeScript" },
|
|
162
|
+
{ value: "javascript", label: "JavaScript" },
|
|
163
|
+
{ value: "tsx", label: "TSX" },
|
|
164
|
+
{ value: "jsx", label: "JSX" },
|
|
165
|
+
{ value: "json", label: "JSON" },
|
|
166
|
+
{ value: "html", label: "HTML" },
|
|
167
|
+
{ value: "css", label: "CSS" },
|
|
168
|
+
{ value: "bash", label: "Bash" },
|
|
169
|
+
{ value: "python", label: "Python" },
|
|
170
|
+
{ value: "sql", label: "SQL" },
|
|
171
|
+
{ value: "yaml", label: "YAML" },
|
|
172
|
+
{ value: "markdown", label: "Markdown" },
|
|
173
|
+
{ value: "graphql", label: "GraphQL" },
|
|
174
|
+
{ value: "go", label: "Go" },
|
|
175
|
+
{ value: "rust", label: "Rust" },
|
|
176
|
+
{ value: "diff", label: "Diff" },
|
|
177
|
+
];
|
|
158
178
|
/** Mint a reasonably-unique code-tab id without pulling a dep into core. */
|
|
159
179
|
function newCodeTabId() {
|
|
160
180
|
return `code-tab-${Math.random().toString(36).slice(2, 10)}`;
|
|
@@ -205,25 +225,35 @@ function CodeTabsEdit({ data, onChange, editable, }) {
|
|
|
205
225
|
return (_jsxs("button", { type: "button", role: "tab", "aria-selected": selected, onClick: () => setActiveId(tab.id), className: cn("flex shrink-0 items-center gap-2 whitespace-nowrap rounded-lg border border-transparent px-3 py-2 font-mono text-sm font-semibold transition-colors", selected
|
|
206
226
|
? "bg-primary/10 text-plan-text dark:bg-primary/20"
|
|
207
227
|
: "text-plan-muted hover:bg-plan-block/60 hover:text-plan-text"), children: [_jsx(IconCode, { className: "size-4 shrink-0" }), tab.label] }, tab.id));
|
|
208
|
-
}) }), editable && (_jsx(CodeTabsSettingsPopover, { active: active, tabs: data.tabs, onUpdate: updateTab, onAdd: addTab, onRemove: removeTab }))] }), active && (
|
|
228
|
+
}) }), editable && (_jsx(CodeTabsSettingsPopover, { active: active, tabs: data.tabs, onUpdate: updateTab, onAdd: addTab, onRemove: removeTab }))] }), active && (_jsx(HighlightedCodeTextarea, { value: active.code, editable: editable, label: active.label, language: active.language, onChange: (event) => updateTab(active.id, { code: event.target.value }) }))] }));
|
|
209
229
|
}
|
|
210
230
|
function CodeTabsSettingsPopover({ active, tabs, onUpdate, onAdd, onRemove, }) {
|
|
211
231
|
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": "Edit code tabs", className: "flex size-8 shrink-0 items-center justify-center rounded-md text-plan-muted transition-colors hover:text-plan-text focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", children: _jsx(IconPencil, { className: "size-4" }) }) }), _jsxs(PopoverContent, { align: "end", side: "bottom", className: "w-80 p-0", "data-plan-interactive": true, children: [_jsxs("div", { className: "border-b border-border px-3 py-2", children: [_jsx("div", { className: "text-sm font-semibold text-foreground", children: "Code tab settings" }), _jsx("div", { className: "text-xs text-muted-foreground", children: "Rename the active tab or manage its metadata." })] }), _jsxs("div", { className: "grid gap-3 p-3", children: [_jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Active tab label" }), _jsx("input", { type: "text", "data-plan-interactive": true, className: inputClass, value: active?.label ?? "", disabled: !active, onChange: (event) => {
|
|
212
232
|
if (!active)
|
|
213
233
|
return;
|
|
214
234
|
onUpdate(active.id, { label: event.target.value });
|
|
215
|
-
} })] }), _jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Language" }), _jsx("
|
|
235
|
+
} })] }), _jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Language" }), _jsx("select", { "data-plan-interactive": true, className: inputClass, value: active?.language ?? "", disabled: !active, onChange: (event) => {
|
|
216
236
|
if (!active)
|
|
217
237
|
return;
|
|
218
238
|
onUpdate(active.id, {
|
|
219
239
|
language: event.target.value || undefined,
|
|
220
240
|
});
|
|
221
|
-
} })] }), _jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Caption" }), _jsx("input", { type: "text", "data-plan-interactive": true, className: inputClass, value: active?.caption ?? "", disabled: !active, onChange: (event) => {
|
|
241
|
+
}, children: CODE_TAB_LANGUAGES.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value || "auto"))) })] }), _jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Caption" }), _jsx("input", { type: "text", "data-plan-interactive": true, className: inputClass, value: active?.caption ?? "", disabled: !active, onChange: (event) => {
|
|
222
242
|
if (!active)
|
|
223
243
|
return;
|
|
224
244
|
onUpdate(active.id, {
|
|
225
245
|
caption: event.target.value || undefined,
|
|
226
246
|
});
|
|
247
|
+
} })] }), _jsxs("label", { className: "grid gap-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Max lines before expand" }), _jsx("input", { type: "number", min: 0, step: 1, "data-plan-interactive": true, className: inputClass, placeholder: `${DEFAULT_CODE_MAX_LINES} (default) · 0 = no limit`, value: active?.maxLines ?? "", disabled: !active, onChange: (event) => {
|
|
248
|
+
if (!active)
|
|
249
|
+
return;
|
|
250
|
+
const raw = event.target.value.trim();
|
|
251
|
+
const parsed = raw === "" ? undefined : Number(raw);
|
|
252
|
+
onUpdate(active.id, {
|
|
253
|
+
maxLines: parsed === undefined || Number.isNaN(parsed)
|
|
254
|
+
? undefined
|
|
255
|
+
: Math.max(0, Math.min(2000, Math.floor(parsed))),
|
|
256
|
+
});
|
|
227
257
|
} })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", "data-plan-interactive": true, disabled: tabs.length >= 12, onClick: onAdd, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(IconPlus, { className: "size-3.5" }), "Add tab"] }), _jsxs("button", { type: "button", "data-plan-interactive": true, disabled: !active || tabs.length <= 1, onClick: () => {
|
|
228
258
|
if (!active)
|
|
229
259
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type ReactNode,\n type UIEvent,\n} from \"react\";\nimport { IconCode, IconPencil, IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { common, createLowlight } from \"lowlight\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps } from \"../types.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/ui/popover.js\";\nimport { CodeSurface } from \"./HighlightedCode.js\";\nimport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n type CodeTabsTab,\n} from \"./code-tabs.config.js\";\n\n/**\n * Standard `code-tabs` block (STANDARD core library): a vertical file tab rail\n * with Shiki-highlighted code panes. Moved verbatim from the plan\n * `CodeTabsBlock` (`DocumentArea.tsx`) so its rendered output is unchanged, then\n * generalized to the registry `Read`/`Edit` contract. Shareable by any app that\n * registers the core block library.\n *\n * `Edit` is hybrid: each tab's `code` field renders as a code-style monospace\n * text area, while tab metadata (label/language/caption/add/remove) stays in a\n * settings popover so the document surface only exposes authored content.\n */\n\n/* ── Syntax highlighting helpers ──────────────────────────────────────────── */\n\nconst lowlight = createLowlight(common);\n\ntype LowlightNode = {\n type: string;\n value?: string;\n properties?: {\n className?: string[] | string;\n };\n children?: LowlightNode[];\n};\n\nconst LANGUAGE_ALIASES: Record<string, string> = {\n cjs: \"javascript\",\n cts: \"typescript\",\n htm: \"html\",\n js: \"javascript\",\n jsonc: \"json\",\n jsx: \"jsx\",\n md: \"markdown\",\n mdx: \"markdown\",\n mjs: \"javascript\",\n mts: \"typescript\",\n py: \"python\",\n rb: \"ruby\",\n rs: \"rust\",\n sh: \"bash\",\n shell: \"bash\",\n ts: \"typescript\",\n tsx: \"tsx\",\n yml: \"yaml\",\n zsh: \"bash\",\n};\n\nconst TOKEN_CLASS_NAMES: Record<string, string> = {\n \"hljs-addition\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-attr\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-attribute\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-built_in\": \"text-amber-700 dark:text-amber-300\",\n \"hljs-bullet\": \"text-primary\",\n \"hljs-comment\": \"text-muted-foreground italic\",\n \"hljs-deletion\": \"text-destructive\",\n \"hljs-doctag\": \"text-destructive\",\n \"hljs-emphasis\": \"italic\",\n \"hljs-formula\": \"text-destructive\",\n \"hljs-keyword\": \"text-rose-700 dark:text-rose-300\",\n \"hljs-link\": \"text-primary underline-offset-2\",\n \"hljs-literal\": \"text-violet-700 dark:text-violet-300\",\n \"hljs-meta\": \"text-primary\",\n \"hljs-meta-string\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-name\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-number\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-params\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-property\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-quote\": \"text-muted-foreground italic\",\n \"hljs-regexp\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-section\": \"text-violet-700 dark:text-violet-300\",\n \"hljs-selector-attr\": \"text-primary\",\n \"hljs-selector-class\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-selector-id\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-selector-pseudo\": \"text-primary\",\n \"hljs-selector-tag\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-string\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-strong\": \"font-semibold\",\n \"hljs-subst\": \"text-destructive\",\n \"hljs-symbol\": \"text-primary\",\n \"hljs-tag\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-template-variable\": \"text-amber-700 dark:text-amber-300\",\n \"hljs-title\": \"text-violet-700 dark:text-violet-300\",\n \"hljs-type\": \"text-amber-700 dark:text-amber-300\",\n \"hljs-variable\": \"text-amber-700 dark:text-amber-300\",\n language_: \"text-amber-700 dark:text-amber-300\",\n};\n\nfunction normalizeCodeLanguage(value?: string | null): string | null {\n const raw = value\n ?.trim()\n .toLowerCase()\n .replace(/^language-/, \"\");\n if (!raw) return null;\n const normalized = LANGUAGE_ALIASES[raw] ?? raw;\n return lowlight.registered(normalized) ? normalized : null;\n}\n\nfunction inferLanguageFromFilename(filename?: string | null): string | null {\n const basename = filename?.split(\"/\").pop()?.toLowerCase();\n if (!basename) return null;\n if (basename === \"dockerfile\") return normalizeCodeLanguage(\"bash\");\n const extension = basename.includes(\".\")\n ? basename.split(\".\").pop()\n : undefined;\n return normalizeCodeLanguage(extension);\n}\n\nfunction codeTabLanguage(tab?: CodeTabsTab): string | undefined {\n return (\n normalizeCodeLanguage(tab?.language) ??\n inferLanguageFromFilename(tab?.label) ??\n undefined\n );\n}\n\nfunction tokenClassName(value: string[] | string | undefined): string {\n const classes = Array.isArray(value)\n ? value\n : typeof value === \"string\"\n ? value.split(/\\s+/)\n : [];\n return classes\n .map((className) => TOKEN_CLASS_NAMES[className] ?? \"\")\n .filter(Boolean)\n .join(\" \");\n}\n\nfunction hastToReact(children: LowlightNode[], keyPrefix: string): ReactNode[] {\n return children.map((node, index) => {\n if (node.type === \"text\") return node.value ?? \"\";\n if (node.type === \"element\") {\n const key = `${keyPrefix}${index}`;\n const renderedChildren = node.children?.length\n ? hastToReact(node.children, `${key}-`)\n : null;\n const className = tokenClassName(node.properties?.className);\n return (\n <span key={key} className={className || undefined}>\n {renderedChildren}\n </span>\n );\n }\n return null;\n });\n}\n\nfunction highlightCode(code: string, language?: string): ReactNode {\n const normalized = normalizeCodeLanguage(language);\n if (!normalized || normalized === \"plaintext\" || normalized === \"text\") {\n return code;\n }\n try {\n const tree = lowlight.highlight(normalized, code) as LowlightNode;\n return hastToReact(tree.children ?? [], `${normalized}-`);\n } catch {\n return code;\n }\n}\n\n/* ── Read (vertical tab rail + Shiki) ──────────────────────────────────────── */\n\nfunction CodeTabsRead({ data, blockId, title }: BlockReadProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className=\"grid overflow-hidden border-y border-plan-line md:grid-cols-[300px_minmax(0,1fr)]\">\n <div className=\"border-plan-line md:border-r\">\n {data.tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n data-plan-interactive\n className={cn(\n \"flex w-full items-start gap-3 border-b border-plan-line px-4 py-4 text-left\",\n tab.id === active?.id\n ? \"bg-primary/10 text-plan-text dark:bg-primary/20\"\n : \"text-plan-muted hover:bg-accent/30\",\n )}\n onClick={() => setActiveId(tab.id)}\n >\n <IconCode className=\"mt-0.5 size-4 shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-mono text-sm font-semibold\">\n {tab.label}\n </span>\n {tab.caption && (\n <span className=\"mt-1 block text-xs leading-5\">\n {tab.caption}\n </span>\n )}\n </span>\n </button>\n ))}\n </div>\n <div className=\"min-w-0 p-5\">\n {active && (\n <>\n <h3 className=\"text-2xl font-semibold tracking-tight\">\n {active.label}\n </h3>\n {active.caption && (\n <p className=\"mt-2 text-plan-muted\">{active.caption}</p>\n )}\n <CodeSurface\n code={active.code}\n language={codeTabLanguage(active)}\n />\n </>\n )}\n </div>\n </div>\n </section>\n );\n}\n\n/* ── Edit (code text areas per tab) ────────────────────────────────────────── */\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\n/** Mint a reasonably-unique code-tab id without pulling a dep into core. */\nfunction newCodeTabId(): string {\n return `code-tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction HighlightedCodeTextarea({\n value,\n language,\n label,\n editable,\n onChange,\n}: {\n value: string;\n language?: string;\n label?: string;\n editable: boolean;\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => void;\n}) {\n const highlightLayerRef = useRef<HTMLPreElement>(null);\n const resolvedLanguage =\n normalizeCodeLanguage(language) ?? inferLanguageFromFilename(label);\n const highlighted = useMemo(\n () => highlightCode(value, resolvedLanguage ?? undefined),\n [resolvedLanguage, value],\n );\n\n const syncScroll = (event: UIEvent<HTMLTextAreaElement>) => {\n const layer = highlightLayerRef.current;\n if (!layer) return;\n layer.scrollTop = event.currentTarget.scrollTop;\n layer.scrollLeft = event.currentTarget.scrollLeft;\n };\n\n return (\n <div\n className={cn(\n \"relative min-h-[140px] overflow-hidden rounded-md border border-input bg-background text-foreground focus-within:ring-1 focus-within:ring-ring\",\n !editable && \"cursor-not-allowed opacity-50\",\n )}\n data-code-tabs-highlighted-editor\n >\n <pre\n ref={highlightLayerRef}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 m-0 overflow-hidden whitespace-pre px-3 py-2 font-mono text-xs leading-5\"\n data-code-tabs-highlight-layer\n >\n <code>\n {highlighted}\n {value.endsWith(\"\\n\") ? \" \" : null}\n </code>\n </pre>\n <textarea\n data-plan-interactive\n spellCheck={false}\n wrap=\"off\"\n className={cn(\n \"relative z-10 block min-h-[140px] w-full resize-y overflow-auto rounded-md border-0 bg-transparent px-3 py-2 font-mono text-xs leading-5 caret-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed\",\n value ? \"text-transparent\" : \"text-muted-foreground\",\n )}\n value={value}\n disabled={!editable}\n onChange={onChange}\n onScroll={syncScroll}\n />\n </div>\n );\n}\n\n/**\n * Editor: a file-tab strip (one tab active at a time) with the active tab's code\n * editable inline. Tab metadata is edited from the settings popover, mirroring\n * the standard `tabs` block and keeping schema-ish controls out of the document.\n */\nfunction CodeTabsEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n\n const commit = (tabs: CodeTabsTab[]) => onChange({ tabs });\n\n const updateTab = (id: string, patch: Partial<CodeTabsTab>) =>\n commit(\n data.tabs.map((tab) => (tab.id === id ? { ...tab, ...patch } : tab)),\n );\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newCodeTabId();\n commit([\n ...data.tabs,\n { id, label: `file-${data.tabs.length + 1}.ts`, code: \"\" },\n ]);\n setActiveId(id);\n };\n\n return (\n <div className=\"an-code-tabs-editor flex min-w-0 flex-col gap-4\">\n <div className=\"flex w-full min-w-0 items-start gap-2\">\n <div\n className=\"flex w-full min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"flex shrink-0 items-center gap-2 whitespace-nowrap rounded-lg border border-transparent px-3 py-2 font-mono text-sm font-semibold transition-colors\",\n selected\n ? \"bg-primary/10 text-plan-text dark:bg-primary/20\"\n : \"text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\",\n )}\n >\n <IconCode className=\"size-4 shrink-0\" />\n {tab.label}\n </button>\n );\n })}\n </div>\n {editable && (\n <CodeTabsSettingsPopover\n active={active}\n tabs={data.tabs}\n onUpdate={updateTab}\n onAdd={addTab}\n onRemove={removeTab}\n />\n )}\n </div>\n {active && (\n <label className=\"flex flex-col gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Code\n </span>\n <HighlightedCodeTextarea\n value={active.code}\n editable={editable}\n label={active.label}\n language={active.language}\n onChange={(event) =>\n updateTab(active.id, { code: event.target.value })\n }\n />\n </label>\n )}\n </div>\n );\n}\n\nfunction CodeTabsSettingsPopover({\n active,\n tabs,\n onUpdate,\n onAdd,\n onRemove,\n}: {\n active: CodeTabsTab | undefined;\n tabs: CodeTabsTab[];\n onUpdate: (id: string, patch: Partial<CodeTabsTab>) => void;\n onAdd: () => void;\n onRemove: (id: string) => void;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Edit code tabs\"\n className=\"flex size-8 shrink-0 items-center justify-center rounded-md text-plan-muted transition-colors hover:text-plan-text focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <IconPencil className=\"size-4\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n side=\"bottom\"\n className=\"w-80 p-0\"\n data-plan-interactive\n >\n <div className=\"border-b border-border px-3 py-2\">\n <div className=\"text-sm font-semibold text-foreground\">\n Code tab settings\n </div>\n <div className=\"text-xs text-muted-foreground\">\n Rename the active tab or manage its metadata.\n </div>\n </div>\n <div className=\"grid gap-3 p-3\">\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Active tab label\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active?.label ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onUpdate(active.id, { label: event.target.value });\n }}\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Language\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active?.language ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onUpdate(active.id, {\n language: event.target.value || undefined,\n });\n }}\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Caption\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active?.caption ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onUpdate(active.id, {\n caption: event.target.value || undefined,\n });\n }}\n />\n </label>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n disabled={tabs.length >= 12}\n onClick={onAdd}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconPlus className=\"size-3.5\" />\n Add tab\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!active || tabs.length <= 1}\n onClick={() => {\n if (!active) return;\n onRemove(active.id);\n }}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-destructive transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconTrash className=\"size-3.5\" />\n Remove current\n </button>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\n/* ── Spec ──────────────────────────────────────────────────────────────────── */\n\nexport const codeTabsBlock = defineBlock<CodeTabsData>({\n type: \"code-tabs\",\n schema: codeTabsSchema,\n mdx: codeTabsMdx,\n Read: CodeTabsRead,\n Edit: CodeTabsEdit,\n placement: [\"block\"],\n editSurface: \"inline\",\n label: \"Code tabs\",\n icon: IconCode,\n description:\n \"A vertical file tab rail of syntax-highlighted code snippets, one tab per file with an optional language and caption.\",\n});\n"]}
|
|
1
|
+
{"version":3,"file":"code-tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code-tabs.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,OAAO,EACP,MAAM,EACN,QAAQ,GAIT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,OAAO,EACP,cAAc,EACd,cAAc,GACf,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,WAAW,GAGZ,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;GAUG;AAEH,iFAAiF;AAEjF,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;AAWxC,MAAM,gBAAgB,GAA2B;IAC/C,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,MAAM;IACX,EAAE,EAAE,YAAY;IAChB,KAAK,EAAE,MAAM;IACb,GAAG,EAAE,KAAK;IACV,EAAE,EAAE,UAAU;IACd,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,YAAY;IACjB,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,MAAM;IACb,EAAE,EAAE,YAAY;IAChB,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;CACZ,CAAC;AAEF,MAAM,iBAAiB,GAA2B;IAChD,eAAe,EAAE,wCAAwC;IACzD,WAAW,EAAE,gCAAgC;IAC7C,gBAAgB,EAAE,gCAAgC;IAClD,eAAe,EAAE,oCAAoC;IACrD,aAAa,EAAE,cAAc;IAC7B,cAAc,EAAE,8BAA8B;IAC9C,eAAe,EAAE,kBAAkB;IACnC,aAAa,EAAE,kBAAkB;IACjC,eAAe,EAAE,QAAQ;IACzB,cAAc,EAAE,kBAAkB;IAClC,cAAc,EAAE,kCAAkC;IAClD,WAAW,EAAE,iCAAiC;IAC9C,cAAc,EAAE,sCAAsC;IACtD,WAAW,EAAE,cAAc;IAC3B,kBAAkB,EAAE,wCAAwC;IAC5D,WAAW,EAAE,wCAAwC;IACrD,aAAa,EAAE,gCAAgC;IAC/C,aAAa,EAAE,gCAAgC;IAC/C,eAAe,EAAE,gCAAgC;IACjD,YAAY,EAAE,8BAA8B;IAC5C,aAAa,EAAE,wCAAwC;IACvD,cAAc,EAAE,sCAAsC;IACtD,oBAAoB,EAAE,cAAc;IACpC,qBAAqB,EAAE,wCAAwC;IAC/D,kBAAkB,EAAE,wCAAwC;IAC5D,sBAAsB,EAAE,cAAc;IACtC,mBAAmB,EAAE,wCAAwC;IAC7D,aAAa,EAAE,wCAAwC;IACvD,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,kBAAkB;IAChC,aAAa,EAAE,cAAc;IAC7B,UAAU,EAAE,wCAAwC;IACpD,wBAAwB,EAAE,oCAAoC;IAC9D,YAAY,EAAE,sCAAsC;IACpD,WAAW,EAAE,oCAAoC;IACjD,eAAe,EAAE,oCAAoC;IACrD,SAAS,EAAE,oCAAoC;CAChD,CAAC;AAEF,SAAS,qBAAqB,CAAC,KAAqB;IAClD,MAAM,GAAG,GAAG,KAAK;QACf,EAAE,IAAI,EAAE;SACP,WAAW,EAAE;SACb,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IAChD,OAAO,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,SAAS,yBAAyB,CAAC,QAAwB;IACzD,MAAM,QAAQ,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC;IAC3D,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QACtC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE;QAC3B,CAAC,CAAC,SAAS,CAAC;IACd,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,eAAe,CAAC,GAAiB;IACxC,OAAO,CACL,qBAAqB,CAAC,GAAG,EAAE,QAAQ,CAAC;QACpC,yBAAyB,CAAC,GAAG,EAAE,KAAK,CAAC;QACrC,SAAS,CACV,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAoC;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAClC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;YACpB,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;SACtD,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,QAAwB,EAAE,SAAiB;IAC9D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,GAAG,SAAS,GAAG,KAAK,EAAE,CAAC;YACnC,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM;gBAC5C,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAC7D,OAAO,CACL,eAAgB,SAAS,EAAE,SAAS,IAAI,SAAS,YAC9C,gBAAgB,IADR,GAAG,CAEP,CACR,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,QAAiB;IACpD,MAAM,UAAU,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAiB,CAAC;QAClE,OAAO,WAAW,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,GAAG,UAAU,GAAG,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,kFAAkF;AAElF,SAAS,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAgC;IAC1E,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CACL,mBAAS,SAAS,EAAC,YAAY,mBAAgB,OAAO,aACnD,KAAK,IAAI,cAAK,SAAS,EAAC,kBAAkB,YAAE,KAAK,GAAO,EACzD,eAAK,SAAS,EAAC,mFAAmF,aAChG,cAAK,SAAS,EAAC,8BAA8B,YAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACtB,kBAEE,IAAI,EAAC,QAAQ,iCAEb,SAAS,EAAE,EAAE,CACX,6EAA6E,EAC7E,GAAG,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE;gCACnB,CAAC,CAAC,iDAAiD;gCACnD,CAAC,CAAC,oCAAoC,CACzC,EACD,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,aAElC,KAAC,QAAQ,IAAC,SAAS,EAAC,wBAAwB,GAAG,EAC/C,gBAAM,SAAS,EAAC,SAAS,aACvB,eAAM,SAAS,EAAC,gDAAgD,YAC7D,GAAG,CAAC,KAAK,GACL,EACN,GAAG,CAAC,OAAO,IAAI,CACd,eAAM,SAAS,EAAC,8BAA8B,YAC3C,GAAG,CAAC,OAAO,GACP,CACR,IACI,KArBF,GAAG,CAAC,EAAE,CAsBJ,CACV,CAAC,GACE,EACN,cAAK,SAAS,EAAC,aAAa,YACzB,MAAM,IAAI,CACT,8BACE,aAAI,SAAS,EAAC,uCAAuC,YAClD,MAAM,CAAC,KAAK,GACV,EACJ,MAAM,CAAC,OAAO,IAAI,CACjB,YAAG,SAAS,EAAC,sBAAsB,YAAE,MAAM,CAAC,OAAO,GAAK,CACzD,EACD,KAAC,WAAW,IACV,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,EACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GACzB,IACD,CACJ,GACG,IACF,IACE,CACX,CAAC;AACJ,CAAC;AAED,kFAAkF;AAElF,MAAM,UAAU,GACd,6PAA6P,CAAC;AAEhQ,+EAA+E;AAC/E,MAAM,kBAAkB,GAAoD;IAC1E,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;IAC5B,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IAC5C,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;IAC5C,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;IAC9B,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;IAC9B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;IAC9B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;IACpC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;IAC9B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;IACxC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;IACtC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IAC5B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAChC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CACjC,CAAC;AAEF,4EAA4E;AAC5E,SAAS,YAAY;IACnB,OAAO,YAAY,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,uBAAuB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,GAOT;IACC,MAAM,iBAAiB,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACvD,MAAM,gBAAgB,GACpB,qBAAqB,CAAC,QAAQ,CAAC,IAAI,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG,OAAO,CACzB,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,gBAAgB,IAAI,SAAS,CAAC,EACzD,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAC1B,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,KAAmC,EAAE,EAAE;QACzD,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;QAChD,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC;IACpD,CAAC,CAAC;IAEF,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,gJAAgJ,EAChJ,CAAC,QAAQ,IAAI,+BAA+B,CAC7C,wDAGD,cACE,GAAG,EAAE,iBAAiB,iBACV,MAAM,EAClB,SAAS,EAAC,+GAA+G,oDAGzH,2BACG,WAAW,EACX,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAC7B,GACH,EACN,kDAEE,UAAU,EAAE,KAAK,EACjB,IAAI,EAAC,KAAK,EACV,SAAS,EAAE,EAAE,CACX,sOAAsO,EACtO,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,uBAAuB,CACrD,EACD,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,QAAQ,EACnB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,UAAU,GACpB,IACE,CACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,EACpB,IAAI,EACJ,QAAQ,EACR,QAAQ,GACqB;IAC7B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5E,MAAM,MAAM,GAAG,CAAC,IAAmB,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3D,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,KAA2B,EAAE,EAAE,CAC5D,MAAM,CACJ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CACrE,CAAC;IAEJ,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,6CAA6C;QAC5E,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,IAAI,QAAQ,KAAK,EAAE;YAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,CAAC,aAAa;QACjD,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;QAC1B,MAAM,CAAC;YACL,GAAG,IAAI,CAAC,IAAI;YACZ,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;SAC3D,CAAC,CAAC;QACH,WAAW,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,iDAAiD,aAC9D,eAAK,SAAS,EAAC,uCAAuC,aACpD,cACE,SAAS,EAAC,2EAA2E,EACrF,IAAI,EAAC,SAAS,2CAGb,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;4BACrB,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;4BACvC,OAAO,CACL,kBAEE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,QAAQ,EACvB,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAClC,SAAS,EAAE,EAAE,CACX,qJAAqJ,EACrJ,QAAQ;oCACN,CAAC,CAAC,iDAAiD;oCACnD,CAAC,CAAC,6DAA6D,CAClE,aAED,KAAC,QAAQ,IAAC,SAAS,EAAC,iBAAiB,GAAG,EACvC,GAAG,CAAC,KAAK,KAbL,GAAG,CAAC,EAAE,CAcJ,CACV,CAAC;wBACJ,CAAC,CAAC,GACE,EACL,QAAQ,IAAI,CACX,KAAC,uBAAuB,IACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,GACnB,CACH,IACG,EACL,MAAM,IAAI,CACT,KAAC,uBAAuB,IACtB,KAAK,EAAE,MAAM,CAAC,IAAI,EAClB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,GAEpD,CACH,IACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,EAC/B,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,QAAQ,GAOT;IACC,OAAO,CACL,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBACrB,iBACE,IAAI,EAAC,QAAQ,+CAEF,gBAAgB,EAC3B,SAAS,EAAC,4LAA4L,YAEtM,KAAC,UAAU,IAAC,SAAS,EAAC,QAAQ,GAAG,GAC1B,GACM,EACjB,MAAC,cAAc,IACb,KAAK,EAAC,KAAK,EACX,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,UAAU,4CAGpB,eAAK,SAAS,EAAC,kCAAkC,aAC/C,cAAK,SAAS,EAAC,uCAAuC,kCAEhD,EACN,cAAK,SAAS,EAAC,+BAA+B,8DAExC,IACF,EACN,eAAK,SAAS,EAAC,gBAAgB,aAC7B,iBAAO,SAAS,EAAC,cAAc,aAC7B,eAAM,SAAS,EAAC,2CAA2C,iCAEpD,EACP,gBACE,IAAI,EAAC,MAAM,iCAEX,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,EAC1B,QAAQ,EAAE,CAAC,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4CAClB,IAAI,CAAC,MAAM;gDAAE,OAAO;4CACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;wCACrD,CAAC,GACD,IACI,EACR,iBAAO,SAAS,EAAC,cAAc,aAC7B,eAAM,SAAS,EAAC,2CAA2C,yBAEpD,EACP,gDAEE,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,EAC7B,QAAQ,EAAE,CAAC,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4CAClB,IAAI,CAAC,MAAM;gDAAE,OAAO;4CACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE;gDAClB,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;6CAC1C,CAAC,CAAC;wCACL,CAAC,YAEA,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAClC,iBAAqC,KAAK,EAAE,MAAM,CAAC,KAAK,YACrD,MAAM,CAAC,KAAK,IADF,MAAM,CAAC,KAAK,IAAI,MAAM,CAE1B,CACV,CAAC,GACK,IACH,EACR,iBAAO,SAAS,EAAC,cAAc,aAC7B,eAAM,SAAS,EAAC,2CAA2C,wBAEpD,EACP,gBACE,IAAI,EAAC,MAAM,iCAEX,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE,EAC5B,QAAQ,EAAE,CAAC,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4CAClB,IAAI,CAAC,MAAM;gDAAE,OAAO;4CACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE;gDAClB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS;6CACzC,CAAC,CAAC;wCACL,CAAC,GACD,IACI,EACR,iBAAO,SAAS,EAAC,cAAc,aAC7B,eAAM,SAAS,EAAC,2CAA2C,wCAEpD,EACP,gBACE,IAAI,EAAC,QAAQ,EACb,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,iCAEP,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,GAAG,sBAAsB,2BAA2B,EACjE,KAAK,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,EAC7B,QAAQ,EAAE,CAAC,MAAM,EACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;4CAClB,IAAI,CAAC,MAAM;gDAAE,OAAO;4CACpB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;4CACtC,MAAM,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;4CACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE;gDAClB,QAAQ,EACN,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;oDAC1C,CAAC,CAAC,SAAS;oDACX,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;6CACtD,CAAC,CAAC;wCACL,CAAC,GACD,IACI,EACR,eAAK,SAAS,EAAC,yBAAyB,aACtC,kBACE,IAAI,EAAC,QAAQ,iCAEb,QAAQ,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAC3B,OAAO,EAAE,KAAK,EACd,SAAS,EAAC,mMAAmM,aAE7M,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,eAE1B,EACT,kBACE,IAAI,EAAC,QAAQ,iCAEb,QAAQ,EAAE,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EACrC,OAAO,EAAE,GAAG,EAAE;4CACZ,IAAI,CAAC,MAAM;gDAAE,OAAO;4CACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wCACtB,CAAC,EACD,SAAS,EAAC,4MAA4M,aAEtN,KAAC,SAAS,IAAC,SAAS,EAAC,UAAU,GAAG,sBAE3B,IACL,IACF,IACS,IACT,CACX,CAAC;AACJ,CAAC;AAED,kFAAkF;AAElF,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAe;IACrD,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,cAAc;IACtB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,SAAS,EAAE,CAAC,OAAO,CAAC;IACpB,WAAW,EAAE,QAAQ;IACrB,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,uHAAuH;CAC1H,CAAC,CAAC","sourcesContent":["import {\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type ReactNode,\n type UIEvent,\n} from \"react\";\nimport { IconCode, IconPencil, IconPlus, IconTrash } from \"@tabler/icons-react\";\nimport { common, createLowlight } from \"lowlight\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps } from \"../types.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/ui/popover.js\";\nimport { CodeSurface, DEFAULT_CODE_MAX_LINES } from \"./HighlightedCode.js\";\nimport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n type CodeTabsTab,\n} from \"./code-tabs.config.js\";\n\n/**\n * Standard `code-tabs` block (STANDARD core library): a vertical file tab rail\n * with Shiki-highlighted code panes. Moved verbatim from the plan\n * `CodeTabsBlock` (`DocumentArea.tsx`) so its rendered output is unchanged, then\n * generalized to the registry `Read`/`Edit` contract. Shareable by any app that\n * registers the core block library.\n *\n * `Edit` is hybrid: each tab's `code` field renders as a code-style monospace\n * text area, while tab metadata (label/language/caption/add/remove) stays in a\n * settings popover so the document surface only exposes authored content.\n */\n\n/* ── Syntax highlighting helpers ──────────────────────────────────────────── */\n\nconst lowlight = createLowlight(common);\n\ntype LowlightNode = {\n type: string;\n value?: string;\n properties?: {\n className?: string[] | string;\n };\n children?: LowlightNode[];\n};\n\nconst LANGUAGE_ALIASES: Record<string, string> = {\n cjs: \"javascript\",\n cts: \"typescript\",\n htm: \"html\",\n js: \"javascript\",\n jsonc: \"json\",\n jsx: \"jsx\",\n md: \"markdown\",\n mdx: \"markdown\",\n mjs: \"javascript\",\n mts: \"typescript\",\n py: \"python\",\n rb: \"ruby\",\n rs: \"rust\",\n sh: \"bash\",\n shell: \"bash\",\n ts: \"typescript\",\n tsx: \"tsx\",\n yml: \"yaml\",\n zsh: \"bash\",\n};\n\nconst TOKEN_CLASS_NAMES: Record<string, string> = {\n \"hljs-addition\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-attr\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-attribute\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-built_in\": \"text-amber-700 dark:text-amber-300\",\n \"hljs-bullet\": \"text-primary\",\n \"hljs-comment\": \"text-muted-foreground italic\",\n \"hljs-deletion\": \"text-destructive\",\n \"hljs-doctag\": \"text-destructive\",\n \"hljs-emphasis\": \"italic\",\n \"hljs-formula\": \"text-destructive\",\n \"hljs-keyword\": \"text-rose-700 dark:text-rose-300\",\n \"hljs-link\": \"text-primary underline-offset-2\",\n \"hljs-literal\": \"text-violet-700 dark:text-violet-300\",\n \"hljs-meta\": \"text-primary\",\n \"hljs-meta-string\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-name\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-number\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-params\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-property\": \"text-sky-700 dark:text-sky-300\",\n \"hljs-quote\": \"text-muted-foreground italic\",\n \"hljs-regexp\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-section\": \"text-violet-700 dark:text-violet-300\",\n \"hljs-selector-attr\": \"text-primary\",\n \"hljs-selector-class\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-selector-id\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-selector-pseudo\": \"text-primary\",\n \"hljs-selector-tag\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-string\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-strong\": \"font-semibold\",\n \"hljs-subst\": \"text-destructive\",\n \"hljs-symbol\": \"text-primary\",\n \"hljs-tag\": \"text-emerald-700 dark:text-emerald-300\",\n \"hljs-template-variable\": \"text-amber-700 dark:text-amber-300\",\n \"hljs-title\": \"text-violet-700 dark:text-violet-300\",\n \"hljs-type\": \"text-amber-700 dark:text-amber-300\",\n \"hljs-variable\": \"text-amber-700 dark:text-amber-300\",\n language_: \"text-amber-700 dark:text-amber-300\",\n};\n\nfunction normalizeCodeLanguage(value?: string | null): string | null {\n const raw = value\n ?.trim()\n .toLowerCase()\n .replace(/^language-/, \"\");\n if (!raw) return null;\n const normalized = LANGUAGE_ALIASES[raw] ?? raw;\n return lowlight.registered(normalized) ? normalized : null;\n}\n\nfunction inferLanguageFromFilename(filename?: string | null): string | null {\n const basename = filename?.split(\"/\").pop()?.toLowerCase();\n if (!basename) return null;\n if (basename === \"dockerfile\") return normalizeCodeLanguage(\"bash\");\n const extension = basename.includes(\".\")\n ? basename.split(\".\").pop()\n : undefined;\n return normalizeCodeLanguage(extension);\n}\n\nfunction codeTabLanguage(tab?: CodeTabsTab): string | undefined {\n return (\n normalizeCodeLanguage(tab?.language) ??\n inferLanguageFromFilename(tab?.label) ??\n undefined\n );\n}\n\nfunction tokenClassName(value: string[] | string | undefined): string {\n const classes = Array.isArray(value)\n ? value\n : typeof value === \"string\"\n ? value.split(/\\s+/)\n : [];\n return classes\n .map((className) => TOKEN_CLASS_NAMES[className] ?? \"\")\n .filter(Boolean)\n .join(\" \");\n}\n\nfunction hastToReact(children: LowlightNode[], keyPrefix: string): ReactNode[] {\n return children.map((node, index) => {\n if (node.type === \"text\") return node.value ?? \"\";\n if (node.type === \"element\") {\n const key = `${keyPrefix}${index}`;\n const renderedChildren = node.children?.length\n ? hastToReact(node.children, `${key}-`)\n : null;\n const className = tokenClassName(node.properties?.className);\n return (\n <span key={key} className={className || undefined}>\n {renderedChildren}\n </span>\n );\n }\n return null;\n });\n}\n\nfunction highlightCode(code: string, language?: string): ReactNode {\n const normalized = normalizeCodeLanguage(language);\n if (!normalized || normalized === \"plaintext\" || normalized === \"text\") {\n return code;\n }\n try {\n const tree = lowlight.highlight(normalized, code) as LowlightNode;\n return hastToReact(tree.children ?? [], `${normalized}-`);\n } catch {\n return code;\n }\n}\n\n/* ── Read (vertical tab rail + Shiki) ──────────────────────────────────────── */\n\nfunction CodeTabsRead({ data, blockId, title }: BlockReadProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className=\"grid overflow-hidden border-y border-plan-line md:grid-cols-[300px_minmax(0,1fr)]\">\n <div className=\"border-plan-line md:border-r\">\n {data.tabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n data-plan-interactive\n className={cn(\n \"flex w-full items-start gap-3 border-b border-plan-line px-4 py-4 text-left\",\n tab.id === active?.id\n ? \"bg-primary/10 text-plan-text dark:bg-primary/20\"\n : \"text-plan-muted hover:bg-accent/30\",\n )}\n onClick={() => setActiveId(tab.id)}\n >\n <IconCode className=\"mt-0.5 size-4 shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-mono text-sm font-semibold\">\n {tab.label}\n </span>\n {tab.caption && (\n <span className=\"mt-1 block text-xs leading-5\">\n {tab.caption}\n </span>\n )}\n </span>\n </button>\n ))}\n </div>\n <div className=\"min-w-0 p-5\">\n {active && (\n <>\n <h3 className=\"text-2xl font-semibold tracking-tight\">\n {active.label}\n </h3>\n {active.caption && (\n <p className=\"mt-2 text-plan-muted\">{active.caption}</p>\n )}\n <CodeSurface\n code={active.code}\n language={codeTabLanguage(active)}\n maxLines={active.maxLines}\n />\n </>\n )}\n </div>\n </div>\n </section>\n );\n}\n\n/* ── Edit (code text areas per tab) ────────────────────────────────────────── */\n\nconst inputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\n/** Language options for the per-tab picker; \"\" is the Auto-detect sentinel. */\nconst CODE_TAB_LANGUAGES: ReadonlyArray<{ value: string; label: string }> = [\n { value: \"\", label: \"Auto\" },\n { value: \"typescript\", label: \"TypeScript\" },\n { value: \"javascript\", label: \"JavaScript\" },\n { value: \"tsx\", label: \"TSX\" },\n { value: \"jsx\", label: \"JSX\" },\n { value: \"json\", label: \"JSON\" },\n { value: \"html\", label: \"HTML\" },\n { value: \"css\", label: \"CSS\" },\n { value: \"bash\", label: \"Bash\" },\n { value: \"python\", label: \"Python\" },\n { value: \"sql\", label: \"SQL\" },\n { value: \"yaml\", label: \"YAML\" },\n { value: \"markdown\", label: \"Markdown\" },\n { value: \"graphql\", label: \"GraphQL\" },\n { value: \"go\", label: \"Go\" },\n { value: \"rust\", label: \"Rust\" },\n { value: \"diff\", label: \"Diff\" },\n];\n\n/** Mint a reasonably-unique code-tab id without pulling a dep into core. */\nfunction newCodeTabId(): string {\n return `code-tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction HighlightedCodeTextarea({\n value,\n language,\n label,\n editable,\n onChange,\n}: {\n value: string;\n language?: string;\n label?: string;\n editable: boolean;\n onChange: (event: ChangeEvent<HTMLTextAreaElement>) => void;\n}) {\n const highlightLayerRef = useRef<HTMLPreElement>(null);\n const resolvedLanguage =\n normalizeCodeLanguage(language) ?? inferLanguageFromFilename(label);\n const highlighted = useMemo(\n () => highlightCode(value, resolvedLanguage ?? undefined),\n [resolvedLanguage, value],\n );\n\n const syncScroll = (event: UIEvent<HTMLTextAreaElement>) => {\n const layer = highlightLayerRef.current;\n if (!layer) return;\n layer.scrollTop = event.currentTarget.scrollTop;\n layer.scrollLeft = event.currentTarget.scrollLeft;\n };\n\n return (\n <div\n className={cn(\n \"relative min-h-[140px] overflow-hidden rounded-md border border-input bg-background text-foreground focus-within:ring-1 focus-within:ring-ring\",\n !editable && \"cursor-not-allowed opacity-50\",\n )}\n data-code-tabs-highlighted-editor\n >\n <pre\n ref={highlightLayerRef}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 m-0 overflow-hidden whitespace-pre px-3 py-2 font-mono text-xs leading-5\"\n data-code-tabs-highlight-layer\n >\n <code>\n {highlighted}\n {value.endsWith(\"\\n\") ? \" \" : null}\n </code>\n </pre>\n <textarea\n data-plan-interactive\n spellCheck={false}\n wrap=\"off\"\n className={cn(\n \"relative z-10 block min-h-[140px] w-full resize-y overflow-auto rounded-md border-0 bg-transparent px-3 py-2 font-mono text-xs leading-5 caret-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed\",\n value ? \"text-transparent\" : \"text-muted-foreground\",\n )}\n value={value}\n disabled={!editable}\n onChange={onChange}\n onScroll={syncScroll}\n />\n </div>\n );\n}\n\n/**\n * Editor: a file-tab strip (one tab active at a time) with the active tab's code\n * editable inline. Tab metadata is edited from the settings popover, mirroring\n * the standard `tabs` block and keeping schema-ish controls out of the document.\n */\nfunction CodeTabsEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<CodeTabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n\n const commit = (tabs: CodeTabsTab[]) => onChange({ tabs });\n\n const updateTab = (id: string, patch: Partial<CodeTabsTab>) =>\n commit(\n data.tabs.map((tab) => (tab.id === id ? { ...tab, ...patch } : tab)),\n );\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newCodeTabId();\n commit([\n ...data.tabs,\n { id, label: `file-${data.tabs.length + 1}.ts`, code: \"\" },\n ]);\n setActiveId(id);\n };\n\n return (\n <div className=\"an-code-tabs-editor flex min-w-0 flex-col gap-4\">\n <div className=\"flex w-full min-w-0 items-start gap-2\">\n <div\n className=\"flex w-full min-w-0 flex-1 flex-nowrap items-center gap-1 overflow-x-auto\"\n role=\"tablist\"\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n \"flex shrink-0 items-center gap-2 whitespace-nowrap rounded-lg border border-transparent px-3 py-2 font-mono text-sm font-semibold transition-colors\",\n selected\n ? \"bg-primary/10 text-plan-text dark:bg-primary/20\"\n : \"text-plan-muted hover:bg-plan-block/60 hover:text-plan-text\",\n )}\n >\n <IconCode className=\"size-4 shrink-0\" />\n {tab.label}\n </button>\n );\n })}\n </div>\n {editable && (\n <CodeTabsSettingsPopover\n active={active}\n tabs={data.tabs}\n onUpdate={updateTab}\n onAdd={addTab}\n onRemove={removeTab}\n />\n )}\n </div>\n {active && (\n <HighlightedCodeTextarea\n value={active.code}\n editable={editable}\n label={active.label}\n language={active.language}\n onChange={(event) =>\n updateTab(active.id, { code: event.target.value })\n }\n />\n )}\n </div>\n );\n}\n\nfunction CodeTabsSettingsPopover({\n active,\n tabs,\n onUpdate,\n onAdd,\n onRemove,\n}: {\n active: CodeTabsTab | undefined;\n tabs: CodeTabsTab[];\n onUpdate: (id: string, patch: Partial<CodeTabsTab>) => void;\n onAdd: () => void;\n onRemove: (id: string) => void;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Edit code tabs\"\n className=\"flex size-8 shrink-0 items-center justify-center rounded-md text-plan-muted transition-colors hover:text-plan-text focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n >\n <IconPencil className=\"size-4\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n side=\"bottom\"\n className=\"w-80 p-0\"\n data-plan-interactive\n >\n <div className=\"border-b border-border px-3 py-2\">\n <div className=\"text-sm font-semibold text-foreground\">\n Code tab settings\n </div>\n <div className=\"text-xs text-muted-foreground\">\n Rename the active tab or manage its metadata.\n </div>\n </div>\n <div className=\"grid gap-3 p-3\">\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Active tab label\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active?.label ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onUpdate(active.id, { label: event.target.value });\n }}\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Language\n </span>\n <select\n data-plan-interactive\n className={inputClass}\n value={active?.language ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onUpdate(active.id, {\n language: event.target.value || undefined,\n });\n }}\n >\n {CODE_TAB_LANGUAGES.map((option) => (\n <option key={option.value || \"auto\"} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Caption\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={inputClass}\n value={active?.caption ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onUpdate(active.id, {\n caption: event.target.value || undefined,\n });\n }}\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Max lines before expand\n </span>\n <input\n type=\"number\"\n min={0}\n step={1}\n data-plan-interactive\n className={inputClass}\n placeholder={`${DEFAULT_CODE_MAX_LINES} (default) · 0 = no limit`}\n value={active?.maxLines ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n const raw = event.target.value.trim();\n const parsed = raw === \"\" ? undefined : Number(raw);\n onUpdate(active.id, {\n maxLines:\n parsed === undefined || Number.isNaN(parsed)\n ? undefined\n : Math.max(0, Math.min(2000, Math.floor(parsed))),\n });\n }}\n />\n </label>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n disabled={tabs.length >= 12}\n onClick={onAdd}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconPlus className=\"size-3.5\" />\n Add tab\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!active || tabs.length <= 1}\n onClick={() => {\n if (!active) return;\n onRemove(active.id);\n }}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-destructive transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconTrash className=\"size-3.5\" />\n Remove current\n </button>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\n/* ── Spec ──────────────────────────────────────────────────────────────────── */\n\nexport const codeTabsBlock = defineBlock<CodeTabsData>({\n type: \"code-tabs\",\n schema: codeTabsSchema,\n mdx: codeTabsMdx,\n Read: CodeTabsRead,\n Edit: CodeTabsEdit,\n placement: [\"block\"],\n editSurface: \"inline\",\n label: \"Code tabs\",\n icon: IconCode,\n description:\n \"A vertical file tab rail of syntax-highlighted code snippets, one tab per file with an optional language and caption.\",\n});\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { BlockMdxConfig } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure (React-free) part of the standard `code` block: its data schema and MDX
|
|
5
|
+
* round-trip config. Shared by the server MDX adapter (a plan/content app
|
|
6
|
+
* registers it via `@agent-native/core/blocks/server`) and the full client spec
|
|
7
|
+
* (`code.tsx`). Keeping this React-free means importing it into a server module
|
|
8
|
+
* never pulls React into the Nitro/SSR bundle.
|
|
9
|
+
*
|
|
10
|
+
* `code` is THE primitive code block — a single syntax-highlighted snippet,
|
|
11
|
+
* Notion-style (one border, hover-revealed language switcher + copy, collapse to
|
|
12
|
+
* N lines). It deliberately holds ONE snippet: a "file rail" of several files is
|
|
13
|
+
* just the `tabs` primitive containing `code` blocks, so there is no bespoke
|
|
14
|
+
* "code-tabs" container. The legacy `code-tabs` block stays renderable for stored
|
|
15
|
+
* documents but is no longer authored.
|
|
16
|
+
*/
|
|
17
|
+
export interface CodeData {
|
|
18
|
+
/** The snippet. */
|
|
19
|
+
code: string;
|
|
20
|
+
/** Language hint (e.g. `ts`). Drives highlighting + the language label/switcher. */
|
|
21
|
+
language?: string;
|
|
22
|
+
/** Optional file path shown in the header (e.g. `src/server/auth.ts`). */
|
|
23
|
+
filename?: string;
|
|
24
|
+
/** Optional one-line caption under the header. */
|
|
25
|
+
caption?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Lines shown before the snippet collapses behind a "Show N more lines"
|
|
28
|
+
* toggle. Omitted ⇒ the default cap (`DEFAULT_CODE_MAX_LINES`, 30). `0` ⇒
|
|
29
|
+
* never collapse (always show the whole snippet).
|
|
30
|
+
*/
|
|
31
|
+
maxLines?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare const codeSchema: z.ZodType<CodeData>;
|
|
34
|
+
/**
|
|
35
|
+
* MDX config: `<Code filename language caption maxLines code />` self-closing
|
|
36
|
+
* form. `code` is a multiline string attribute (the shared `prop()` encoder
|
|
37
|
+
* round-trips multiline strings cleanly, and keeping it an attribute — not MDX
|
|
38
|
+
* children — avoids the source being reflowed as prose). `fromAttrs` is forgiving
|
|
39
|
+
* (`code ?? ""`, optional fields undefined when absent) so a snippet missing an
|
|
40
|
+
* attribute still parses.
|
|
41
|
+
*/
|
|
42
|
+
export declare const codeMdx: BlockMdxConfig<CodeData>;
|
|
43
|
+
//# sourceMappingURL=code.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/code.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,QAAQ;IACvB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,UAAU,EAMN,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErC;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,QAAQ,CAgB5C,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const codeSchema = z.object({
|
|
3
|
+
code: z.string().max(100_000),
|
|
4
|
+
language: z.string().trim().max(40).optional(),
|
|
5
|
+
filename: z.string().trim().max(400).optional(),
|
|
6
|
+
caption: z.string().trim().max(400).optional(),
|
|
7
|
+
maxLines: z.number().int().min(0).max(2000).optional(),
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* MDX config: `<Code filename language caption maxLines code />` self-closing
|
|
11
|
+
* form. `code` is a multiline string attribute (the shared `prop()` encoder
|
|
12
|
+
* round-trips multiline strings cleanly, and keeping it an attribute — not MDX
|
|
13
|
+
* children — avoids the source being reflowed as prose). `fromAttrs` is forgiving
|
|
14
|
+
* (`code ?? ""`, optional fields undefined when absent) so a snippet missing an
|
|
15
|
+
* attribute still parses.
|
|
16
|
+
*/
|
|
17
|
+
export const codeMdx = {
|
|
18
|
+
tag: "Code",
|
|
19
|
+
toAttrs: (data) => ({
|
|
20
|
+
filename: data.filename,
|
|
21
|
+
language: data.language,
|
|
22
|
+
caption: data.caption,
|
|
23
|
+
maxLines: data.maxLines,
|
|
24
|
+
code: data.code,
|
|
25
|
+
}),
|
|
26
|
+
fromAttrs: (attrs) => ({
|
|
27
|
+
code: attrs.string("code") ?? "",
|
|
28
|
+
language: attrs.string("language"),
|
|
29
|
+
filename: attrs.string("filename"),
|
|
30
|
+
caption: attrs.string("caption"),
|
|
31
|
+
maxLines: attrs.number("maxLines"),
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=code.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmCxB,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;IAC7B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC9C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC/C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC9C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAmC,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAA6B;IAC/C,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;KAChB,CAAC;IACF,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QAChC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAClC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;QAChC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;KACnC,CAAC;CACH,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { BlockMdxConfig } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the standard `code` block: its data schema and MDX\n * round-trip config. Shared by the server MDX adapter (a plan/content app\n * registers it via `@agent-native/core/blocks/server`) and the full client spec\n * (`code.tsx`). Keeping this React-free means importing it into a server module\n * never pulls React into the Nitro/SSR bundle.\n *\n * `code` is THE primitive code block — a single syntax-highlighted snippet,\n * Notion-style (one border, hover-revealed language switcher + copy, collapse to\n * N lines). It deliberately holds ONE snippet: a \"file rail\" of several files is\n * just the `tabs` primitive containing `code` blocks, so there is no bespoke\n * \"code-tabs\" container. The legacy `code-tabs` block stays renderable for stored\n * documents but is no longer authored.\n */\n\nexport interface CodeData {\n /** The snippet. */\n code: string;\n /** Language hint (e.g. `ts`). Drives highlighting + the language label/switcher. */\n language?: string;\n /** Optional file path shown in the header (e.g. `src/server/auth.ts`). */\n filename?: string;\n /** Optional one-line caption under the header. */\n caption?: string;\n /**\n * Lines shown before the snippet collapses behind a \"Show N more lines\"\n * toggle. Omitted ⇒ the default cap (`DEFAULT_CODE_MAX_LINES`, 30). `0` ⇒\n * never collapse (always show the whole snippet).\n */\n maxLines?: number;\n}\n\nexport const codeSchema = z.object({\n code: z.string().max(100_000),\n language: z.string().trim().max(40).optional(),\n filename: z.string().trim().max(400).optional(),\n caption: z.string().trim().max(400).optional(),\n maxLines: z.number().int().min(0).max(2000).optional(),\n}) as unknown as z.ZodType<CodeData>;\n\n/**\n * MDX config: `<Code filename language caption maxLines code />` self-closing\n * form. `code` is a multiline string attribute (the shared `prop()` encoder\n * round-trips multiline strings cleanly, and keeping it an attribute — not MDX\n * children — avoids the source being reflowed as prose). `fromAttrs` is forgiving\n * (`code ?? \"\"`, optional fields undefined when absent) so a snippet missing an\n * attribute still parses.\n */\nexport const codeMdx: BlockMdxConfig<CodeData> = {\n tag: \"Code\",\n toAttrs: (data) => ({\n filename: data.filename,\n language: data.language,\n caption: data.caption,\n maxLines: data.maxLines,\n code: data.code,\n }),\n fromAttrs: (attrs) => ({\n code: attrs.string(\"code\") ?? \"\",\n language: attrs.string(\"language\"),\n filename: attrs.string(\"filename\"),\n caption: attrs.string(\"caption\"),\n maxLines: attrs.number(\"maxLines\"),\n }),\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/code.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA2OtE,eAAO,MAAM,SAAS,2CAYpB,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId, useLayoutEffect, useMemo, useRef, useState, } from "react";
|
|
3
|
+
import { IconCheck, IconCode, IconCopy } from "@tabler/icons-react";
|
|
4
|
+
import { cn } from "../../utils.js";
|
|
5
|
+
import { defineBlock } from "../types.js";
|
|
6
|
+
import { CodeSurface } from "./HighlightedCode.js";
|
|
7
|
+
import { highlightCode, inferLanguageFromFilename, normalizeCodeLanguage, } from "./code-highlight.js";
|
|
8
|
+
import { codeSchema, codeMdx } from "./code.config.js";
|
|
9
|
+
/**
|
|
10
|
+
* Standard `code` block (STANDARD core library): THE primitive single code
|
|
11
|
+
* snippet, used everywhere in plan + content. Notion-style — one border, a
|
|
12
|
+
* hover-revealed language switcher + copy, and the shared collapse-to-N-lines
|
|
13
|
+
* read surface. A "file rail" of several files is just the `tabs` primitive
|
|
14
|
+
* holding `code` blocks; there is no bespoke "code-tabs" container.
|
|
15
|
+
*
|
|
16
|
+
* Read = the shared {@link CodeSurface} (Shiki, single border, language label,
|
|
17
|
+
* "Show N more lines"). Edit = a clean, single-border editable surface (no
|
|
18
|
+
* drag-to-resize; it auto-grows to its content) with the same hover chrome.
|
|
19
|
+
*/
|
|
20
|
+
/** Language options for the hover switcher; "" is the Auto-detect sentinel. */
|
|
21
|
+
const CODE_LANGUAGES = [
|
|
22
|
+
{ value: "", label: "Auto" },
|
|
23
|
+
{ value: "typescript", label: "TypeScript" },
|
|
24
|
+
{ value: "javascript", label: "JavaScript" },
|
|
25
|
+
{ value: "tsx", label: "TSX" },
|
|
26
|
+
{ value: "jsx", label: "JSX" },
|
|
27
|
+
{ value: "json", label: "JSON" },
|
|
28
|
+
{ value: "html", label: "HTML" },
|
|
29
|
+
{ value: "css", label: "CSS" },
|
|
30
|
+
{ value: "bash", label: "Bash" },
|
|
31
|
+
{ value: "python", label: "Python" },
|
|
32
|
+
{ value: "sql", label: "SQL" },
|
|
33
|
+
{ value: "yaml", label: "YAML" },
|
|
34
|
+
{ value: "markdown", label: "Markdown" },
|
|
35
|
+
{ value: "graphql", label: "GraphQL" },
|
|
36
|
+
{ value: "go", label: "Go" },
|
|
37
|
+
{ value: "rust", label: "Rust" },
|
|
38
|
+
{ value: "diff", label: "Diff" },
|
|
39
|
+
];
|
|
40
|
+
function CopyButton({ value }) {
|
|
41
|
+
const [copied, setCopied] = useState(false);
|
|
42
|
+
return (_jsx("button", { type: "button", "data-plan-interactive": true, "aria-label": copied ? "Copied" : "Copy code", title: copied ? "Copied" : "Copy code", className: "plan-code-chip", onClick: () => {
|
|
43
|
+
void navigator.clipboard?.writeText(value).then(() => {
|
|
44
|
+
setCopied(true);
|
|
45
|
+
setTimeout(() => setCopied(false), 1200);
|
|
46
|
+
}, () => { });
|
|
47
|
+
}, children: copied ? (_jsx(IconCheck, { className: "size-3.5" })) : (_jsx(IconCopy, { className: "size-3.5" })) }));
|
|
48
|
+
}
|
|
49
|
+
/* ── Read ──────────────────────────────────────────────────────────────────── */
|
|
50
|
+
function CodeRead({ data, blockId }) {
|
|
51
|
+
const language = normalizeCodeLanguage(data.language) ??
|
|
52
|
+
inferLanguageFromFilename(data.filename) ??
|
|
53
|
+
undefined;
|
|
54
|
+
return (_jsx("section", { className: "plan-block", "data-block-id": blockId, children: _jsxs("div", { className: "plan-code group relative", children: [data.filename && (_jsxs("div", { className: "plan-code-head", children: [_jsxs("span", { className: "plan-code-filename", children: [_jsx(IconCode, { className: "size-4 shrink-0 opacity-70" }), data.filename] }), _jsx("span", { className: "plan-code-chrome", children: _jsx(CopyButton, { value: data.code }) })] })), _jsx(CodeSurface, { code: data.code, language: language, maxLines: data.maxLines, className: data.filename ? "mt-0" : "mt-0" }), !data.filename && (_jsx("span", { className: "plan-code-chrome plan-code-chrome-float", children: _jsx(CopyButton, { value: data.code }) })), data.caption && _jsx("p", { className: "plan-code-caption", children: data.caption })] }) }));
|
|
55
|
+
}
|
|
56
|
+
/* ── Edit (single border, no resize, auto-grow, hover chrome) ──────────────── */
|
|
57
|
+
function CodeEditorSurface({ code, language, filename, editable, onCodeChange, onLanguageChange, }) {
|
|
58
|
+
const textareaRef = useRef(null);
|
|
59
|
+
const highlightLayerRef = useRef(null);
|
|
60
|
+
const selectId = useId();
|
|
61
|
+
const resolvedLanguage = normalizeCodeLanguage(language) ?? inferLanguageFromFilename(filename);
|
|
62
|
+
const highlighted = useMemo(() => highlightCode(code, resolvedLanguage), [resolvedLanguage, code]);
|
|
63
|
+
// Auto-grow to content height — no drag-to-resize handle.
|
|
64
|
+
useLayoutEffect(() => {
|
|
65
|
+
const node = textareaRef.current;
|
|
66
|
+
if (!node)
|
|
67
|
+
return;
|
|
68
|
+
node.style.height = "auto";
|
|
69
|
+
node.style.height = `${node.scrollHeight}px`;
|
|
70
|
+
}, [code]);
|
|
71
|
+
const syncScroll = (event) => {
|
|
72
|
+
const layer = highlightLayerRef.current;
|
|
73
|
+
if (!layer)
|
|
74
|
+
return;
|
|
75
|
+
layer.scrollLeft = event.currentTarget.scrollLeft;
|
|
76
|
+
};
|
|
77
|
+
return (_jsxs("div", { className: cn("plan-code plan-code-editing group relative", !editable && "opacity-60"), children: [_jsxs("div", { className: "plan-code-head", children: [_jsxs("span", { className: "plan-code-filename plan-code-muted", children: [_jsx(IconCode, { className: "size-4 shrink-0 opacity-70" }), filename || "Snippet"] }), _jsxs("span", { className: "plan-code-chrome", children: [_jsx("label", { htmlFor: selectId, className: "sr-only", children: "Code language" }), _jsx("select", { id: selectId, "data-plan-interactive": true, disabled: !editable, className: "plan-code-lang-select", value: normalizeCodeLanguage(language) ? (language ?? "") : "", onChange: (event) => onLanguageChange(event.target.value || undefined), children: CODE_LANGUAGES.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value || "auto"))) }), _jsx(CopyButton, { value: code })] })] }), _jsxs("div", { className: "plan-code-editor-body", children: [_jsx("pre", { ref: highlightLayerRef, "aria-hidden": "true", className: "plan-code-editor-layer", children: _jsxs("code", { children: [highlighted, code.endsWith("\n") ? " " : null] }) }), _jsx("textarea", { ref: textareaRef, "data-plan-interactive": true, spellCheck: false, wrap: "off", className: "plan-code-editor-input", value: code, disabled: !editable, onChange: (event) => onCodeChange(event.target.value), onScroll: syncScroll })] })] }));
|
|
78
|
+
}
|
|
79
|
+
function CodeEdit({ data, onChange, editable }) {
|
|
80
|
+
return (_jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [_jsx(CodeEditorSurface, { code: data.code, language: data.language, filename: data.filename, editable: editable, onCodeChange: (code) => onChange({ ...data, code }), onLanguageChange: (language) => onChange({ ...data, language }) }), editable && (_jsx("input", { type: "text", "data-plan-interactive": true, className: "plan-code-caption-input", placeholder: "Caption (optional)", value: data.caption ?? "", onChange: (event) => onChange({ ...data, caption: event.target.value || undefined }) }))] }));
|
|
81
|
+
}
|
|
82
|
+
/* ── Spec ──────────────────────────────────────────────────────────────────── */
|
|
83
|
+
export const codeBlock = defineBlock({
|
|
84
|
+
type: "code",
|
|
85
|
+
schema: codeSchema,
|
|
86
|
+
mdx: codeMdx,
|
|
87
|
+
Read: CodeRead,
|
|
88
|
+
Edit: CodeEdit,
|
|
89
|
+
placement: ["block"],
|
|
90
|
+
editSurface: "inline",
|
|
91
|
+
label: "Code",
|
|
92
|
+
icon: IconCode,
|
|
93
|
+
description: "A single syntax-highlighted code snippet, Notion-style: one border, a hover language switcher + copy, and collapse-to-N lines. Put several in a `tabs` block for a file rail.",
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/code.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type UIEvent,\n} from \"react\";\nimport { IconCheck, IconCode, IconCopy } from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type { BlockReadProps, BlockEditProps } from \"../types.js\";\nimport { CodeSurface } from \"./HighlightedCode.js\";\nimport {\n highlightCode,\n inferLanguageFromFilename,\n normalizeCodeLanguage,\n} from \"./code-highlight.js\";\nimport { codeSchema, codeMdx, type CodeData } from \"./code.config.js\";\n\n/**\n * Standard `code` block (STANDARD core library): THE primitive single code\n * snippet, used everywhere in plan + content. Notion-style — one border, a\n * hover-revealed language switcher + copy, and the shared collapse-to-N-lines\n * read surface. A \"file rail\" of several files is just the `tabs` primitive\n * holding `code` blocks; there is no bespoke \"code-tabs\" container.\n *\n * Read = the shared {@link CodeSurface} (Shiki, single border, language label,\n * \"Show N more lines\"). Edit = a clean, single-border editable surface (no\n * drag-to-resize; it auto-grows to its content) with the same hover chrome.\n */\n\n/** Language options for the hover switcher; \"\" is the Auto-detect sentinel. */\nconst CODE_LANGUAGES: ReadonlyArray<{ value: string; label: string }> = [\n { value: \"\", label: \"Auto\" },\n { value: \"typescript\", label: \"TypeScript\" },\n { value: \"javascript\", label: \"JavaScript\" },\n { value: \"tsx\", label: \"TSX\" },\n { value: \"jsx\", label: \"JSX\" },\n { value: \"json\", label: \"JSON\" },\n { value: \"html\", label: \"HTML\" },\n { value: \"css\", label: \"CSS\" },\n { value: \"bash\", label: \"Bash\" },\n { value: \"python\", label: \"Python\" },\n { value: \"sql\", label: \"SQL\" },\n { value: \"yaml\", label: \"YAML\" },\n { value: \"markdown\", label: \"Markdown\" },\n { value: \"graphql\", label: \"GraphQL\" },\n { value: \"go\", label: \"Go\" },\n { value: \"rust\", label: \"Rust\" },\n { value: \"diff\", label: \"Diff\" },\n];\n\nfunction CopyButton({ value }: { value: string }) {\n const [copied, setCopied] = useState(false);\n return (\n <button\n type=\"button\"\n data-plan-interactive\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n title={copied ? \"Copied\" : \"Copy code\"}\n className=\"plan-code-chip\"\n onClick={() => {\n void navigator.clipboard?.writeText(value).then(\n () => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1200);\n },\n () => {},\n );\n }}\n >\n {copied ? (\n <IconCheck className=\"size-3.5\" />\n ) : (\n <IconCopy className=\"size-3.5\" />\n )}\n </button>\n );\n}\n\n/* ── Read ──────────────────────────────────────────────────────────────────── */\n\nfunction CodeRead({ data, blockId }: BlockReadProps<CodeData>) {\n const language =\n normalizeCodeLanguage(data.language) ??\n inferLanguageFromFilename(data.filename) ??\n undefined;\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n <div className=\"plan-code group relative\">\n {data.filename && (\n <div className=\"plan-code-head\">\n <span className=\"plan-code-filename\">\n <IconCode className=\"size-4 shrink-0 opacity-70\" />\n {data.filename}\n </span>\n <span className=\"plan-code-chrome\">\n <CopyButton value={data.code} />\n </span>\n </div>\n )}\n <CodeSurface\n code={data.code}\n language={language}\n maxLines={data.maxLines}\n className={data.filename ? \"mt-0\" : \"mt-0\"}\n />\n {!data.filename && (\n <span className=\"plan-code-chrome plan-code-chrome-float\">\n <CopyButton value={data.code} />\n </span>\n )}\n {data.caption && <p className=\"plan-code-caption\">{data.caption}</p>}\n </div>\n </section>\n );\n}\n\n/* ── Edit (single border, no resize, auto-grow, hover chrome) ──────────────── */\n\nfunction CodeEditorSurface({\n code,\n language,\n filename,\n editable,\n onCodeChange,\n onLanguageChange,\n}: {\n code: string;\n language?: string;\n filename?: string;\n editable: boolean;\n onCodeChange: (code: string) => void;\n onLanguageChange: (language: string | undefined) => void;\n}) {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const highlightLayerRef = useRef<HTMLPreElement>(null);\n const selectId = useId();\n const resolvedLanguage =\n normalizeCodeLanguage(language) ?? inferLanguageFromFilename(filename);\n const highlighted = useMemo(\n () => highlightCode(code, resolvedLanguage),\n [resolvedLanguage, code],\n );\n\n // Auto-grow to content height — no drag-to-resize handle.\n useLayoutEffect(() => {\n const node = textareaRef.current;\n if (!node) return;\n node.style.height = \"auto\";\n node.style.height = `${node.scrollHeight}px`;\n }, [code]);\n\n const syncScroll = (event: UIEvent<HTMLTextAreaElement>) => {\n const layer = highlightLayerRef.current;\n if (!layer) return;\n layer.scrollLeft = event.currentTarget.scrollLeft;\n };\n\n return (\n <div\n className={cn(\n \"plan-code plan-code-editing group relative\",\n !editable && \"opacity-60\",\n )}\n >\n <div className=\"plan-code-head\">\n <span className=\"plan-code-filename plan-code-muted\">\n <IconCode className=\"size-4 shrink-0 opacity-70\" />\n {filename || \"Snippet\"}\n </span>\n <span className=\"plan-code-chrome\">\n <label htmlFor={selectId} className=\"sr-only\">\n Code language\n </label>\n <select\n id={selectId}\n data-plan-interactive\n disabled={!editable}\n className=\"plan-code-lang-select\"\n value={normalizeCodeLanguage(language) ? (language ?? \"\") : \"\"}\n onChange={(event) =>\n onLanguageChange(event.target.value || undefined)\n }\n >\n {CODE_LANGUAGES.map((option) => (\n <option key={option.value || \"auto\"} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <CopyButton value={code} />\n </span>\n </div>\n <div className=\"plan-code-editor-body\">\n <pre\n ref={highlightLayerRef}\n aria-hidden=\"true\"\n className=\"plan-code-editor-layer\"\n >\n <code>\n {highlighted}\n {code.endsWith(\"\\n\") ? \" \" : null}\n </code>\n </pre>\n <textarea\n ref={textareaRef}\n data-plan-interactive\n spellCheck={false}\n wrap=\"off\"\n className=\"plan-code-editor-input\"\n value={code}\n disabled={!editable}\n onChange={(event: ChangeEvent<HTMLTextAreaElement>) =>\n onCodeChange(event.target.value)\n }\n onScroll={syncScroll}\n />\n </div>\n </div>\n );\n}\n\nfunction CodeEdit({ data, onChange, editable }: BlockEditProps<CodeData>) {\n return (\n <div className=\"flex min-w-0 flex-col gap-2\">\n <CodeEditorSurface\n code={data.code}\n language={data.language}\n filename={data.filename}\n editable={editable}\n onCodeChange={(code) => onChange({ ...data, code })}\n onLanguageChange={(language) => onChange({ ...data, language })}\n />\n {editable && (\n <input\n type=\"text\"\n data-plan-interactive\n className=\"plan-code-caption-input\"\n placeholder=\"Caption (optional)\"\n value={data.caption ?? \"\"}\n onChange={(event) =>\n onChange({ ...data, caption: event.target.value || undefined })\n }\n />\n )}\n </div>\n );\n}\n\n/* ── Spec ──────────────────────────────────────────────────────────────────── */\n\nexport const codeBlock = defineBlock<CodeData>({\n type: \"code\",\n schema: codeSchema,\n mdx: codeMdx,\n Read: CodeRead,\n Edit: CodeEdit,\n placement: [\"block\"],\n editSurface: \"inline\",\n label: \"Code\",\n icon: IconCode,\n description:\n \"A single syntax-highlighted code snippet, Notion-style: one border, a hover language switcher + copy, and collapse-to-N lines. Put several in a `tabs` block for a file rail.\",\n});\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ComponentProps, InputHTMLAttributes, LabelHTMLAttributes, ReactNode, TextareaHTMLAttributes } from "react";
|
|
2
2
|
/**
|
|
3
3
|
* Minimal, app-agnostic form primitives for the core "dev-doc" block library
|
|
4
|
-
* (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer
|
|
4
|
+
* (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer /
|
|
5
|
+
* annotated-code).
|
|
5
6
|
* These blocks previously imported the plan app's shadcn/ui
|
|
6
7
|
* components (`@/components/ui/*`); core blocks must stay portable, so these are
|
|
7
8
|
* plain styled elements that reproduce the SAME shadcn Tailwind classes byte-for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-doc-ui.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/dev-doc-ui.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,sBAAsB,EACvB,MAAM,OAAO,CAAC;AAIf
|
|
1
|
+
{"version":3,"file":"dev-doc-ui.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/dev-doc-ui.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,EACT,sBAAsB,EACvB,MAAM,OAAO,CAAC;AAIf;;;;;;;;;;;;;;;GAeG;AAIH,eAAO,MAAM,QAAQ,oIAanB,CAAC;AAKH,eAAO,MAAM,QAAQ,oIAYnB,CAAC;AAKH,eAAO,MAAM,WAAW,6IAYtB,CAAC;AAKH,gEAAgE;AAChE,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,MAAM,CAAC,2CAUvE;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CACN,mBAAmB,CAAC,iBAAiB,CAAC,EACtC,UAAU,GAAG,SAAS,GAAG,MAAM,CAChC,2CAwBA;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAa,EACb,OAAO,EACP,QAAQ,EACR,SAAS,EACT,YAAY,EAAE,SAAS,GACxB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,2CAsBA"}
|
|
@@ -4,7 +4,8 @@ import { IconChevronDown } from "@tabler/icons-react";
|
|
|
4
4
|
import { cn } from "../../utils.js";
|
|
5
5
|
/**
|
|
6
6
|
* Minimal, app-agnostic form primitives for the core "dev-doc" block library
|
|
7
|
-
* (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer
|
|
7
|
+
* (mermaid / api-endpoint / data-model / diff / file-tree / json-explorer /
|
|
8
|
+
* annotated-code).
|
|
8
9
|
* These blocks previously imported the plan app's shadcn/ui
|
|
9
10
|
* components (`@/components/ui/*`); core blocks must stay portable, so these are
|
|
10
11
|
* plain styled elements that reproduce the SAME shadcn Tailwind classes byte-for
|