@agent-native/core 0.84.53 → 0.84.55
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/skills.ts +34 -16
- package/corpus/core/src/client/AssistantChat.tsx +198 -146
- package/corpus/core/src/client/agent-chat-adapter.ts +14 -4
- package/corpus/core/src/client/blocks/library/diagram.config.ts +13 -2
- package/corpus/core/src/client/blocks/library/diagram.tsx +27 -3
- package/corpus/core/src/client/blocks/library/server-specs.ts +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.config.ts +7 -1
- package/corpus/core/src/client/blocks/library/wireframe.tsx +42 -3
- package/corpus/core/src/client/blocks/types.ts +9 -0
- package/corpus/core/src/client/chat/message-components.tsx +6 -2
- package/corpus/core/src/client/sse-event-processor.ts +11 -4
- package/corpus/core/src/client/use-agent-engine-configured.ts +54 -12
- package/corpus/core/src/server/agent-chat-plugin.ts +9 -5
- package/corpus/core/src/styles/agent-native.css +44 -0
- package/corpus/core/src/styles/blocks.css +18 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/references/document-quality.md +10 -6
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +20 -9
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +4 -1
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +20 -9
- package/corpus/templates/plan/actions/create-ui-plan.ts +1 -1
- package/corpus/templates/plan/actions/create-visual-plan.ts +1 -1
- package/corpus/templates/plan/actions/create-visual-recap.ts +1 -1
- package/corpus/templates/plan/actions/get-plan-blocks.ts +2 -0
- package/corpus/templates/plan/app/components/plan/planBlocks.tsx +2 -0
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +38 -4
- package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +18 -0
- package/corpus/templates/plan/app/global.css +1 -2
- package/corpus/templates/plan/changelog/2026-07-02-plan-chat-keeps-the-composer-anchored-when-connect-ai-appears.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-02-wireframe-and-diagram-blocks-can-now-show-or-hide-their-outer-frame.md +6 -0
- package/corpus/templates/plan/server/plan-mdx.ts +3 -0
- package/corpus/templates/plan/shared/plan-content.ts +8 -0
- package/dist/cli/skills.d.ts +3 -3
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +34 -16
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +65 -45
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +12 -2
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/blocks/library/diagram.config.d.ts +3 -1
- package/dist/client/blocks/library/diagram.config.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.config.js +10 -1
- package/dist/client/blocks/library/diagram.config.js.map +1 -1
- package/dist/client/blocks/library/diagram.d.ts.map +1 -1
- package/dist/client/blocks/library/diagram.js +13 -7
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/server-specs.js +2 -2
- package/dist/client/blocks/library/server-specs.js.map +1 -1
- package/dist/client/blocks/library/wireframe.config.d.ts +3 -1
- package/dist/client/blocks/library/wireframe.config.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.config.js +4 -0
- package/dist/client/blocks/library/wireframe.config.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +20 -9
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/blocks/types.d.ts +8 -0
- package/dist/client/blocks/types.d.ts.map +1 -1
- package/dist/client/blocks/types.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +6 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +9 -4
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts +10 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +35 -10
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +4 -4
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +9 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/styles/agent-native.css +44 -0
- package/dist/styles/blocks.css +18 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-specs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/server-specs.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerBlocks, type BlockRegistry } from \"../registry.js\";\nimport { defineBlock, type BlockSpec } from \"../types.js\";\nimport {\n annotatedCodeSchema,\n annotatedCodeMdx,\n type AnnotatedCodeData,\n} from \"./annotated-code.config.js\";\nimport {\n apiEndpointSchema,\n apiEndpointMdx,\n type ApiEndpointData,\n} from \"./api-endpoint.config.js\";\nimport {\n calloutSchema,\n calloutMdx,\n type CalloutData,\n} from \"./callout.config.js\";\n// React-free schema + MDX config for the standard library. The matching React\n// `Read`/`Edit` live in the full client entry; the server path only ever touches\n// `spec.schema` / `spec.mdx`, so these configs register with a render-only stub.\nimport {\n checklistSchema,\n checklistMdx,\n type ChecklistData,\n} from \"./checklist.config.js\";\nimport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n} from \"./code-tabs.config.js\";\nimport { codeSchema, codeMdx, type CodeData } from \"./code.config.js\";\nimport {\n columnsSchema,\n columnsMdx,\n type ColumnsData,\n} from \"./columns.config.js\";\nimport {\n dataModelSchema,\n dataModelMdx,\n type DataModelData,\n} from \"./data-model.config.js\";\nimport {\n diagramSchema,\n diagramMdx,\n type DiagramData,\n} from \"./diagram.config.js\";\nimport { diffSchema, diffMdx, type DiffData } from \"./diff.config.js\";\nimport {\n fileTreeSchema,\n fileTreeMdx,\n type FileTreeData,\n} from \"./file-tree.config.js\";\nimport { htmlSchema, htmlMdx, type HtmlBlockData } from \"./html.config.js\";\nimport {\n jsonExplorerSchema,\n jsonExplorerMdx,\n type JsonExplorerData,\n} from \"./json-explorer.config.js\";\nimport {\n mermaidSchema,\n mermaidMdx,\n type MermaidData,\n} from \"./mermaid.config.js\";\nimport {\n openApiSpecSchema,\n openApiSpecMdx,\n type OpenApiSpecData,\n} from \"./openapi-spec.config.js\";\nimport {\n questionFormSchema,\n questionFormMdx,\n visualQuestionsSchema,\n visualQuestionsMdx,\n type QuestionFormData,\n type VisualQuestionsData,\n} from \"./question-form.config.js\";\nimport { tableSchema, tableMdx, type TableData } from \"./table.config.js\";\nimport { tabsSchema, tabsMdx, type TabsData } from \"./tabs.config.js\";\nimport {\n wireframeSchema,\n wireframeMdx,\n type WireframeData,\n} from \"./wireframe.config.js\";\n\n/** Render-only stub for server / agent registries (never invoked off-browser). */\nconst ServerReadStub = () => null;\n\n/**\n * Canonical React-free specs for the standard library, used by BOTH apps' server\n * / shared registries (`plan-block-registry.ts`, `nfm-registry.ts`). Each carries\n * only the parts the server path touches — `schema` + `mdx` + metadata for the\n * agent schema export — with a render-only `Read` stub. The full client specs\n * (with real React `Read`/`Edit`) live in `./specs.tsx`; both share the identical\n * `schema`/`mdx` config so inline source can never drift from what renders.\n *\n * `table` keeps the core default `type` here; content's server registry renames\n * it to `table-block` via {@link LibraryBlockConfigOverrides}. The descriptions\n * are the neutral agent-schema phrasing; an app that curates a longer\n * description for a block (e.g. plan's hand-drawn Mermaid, plan's detailed file\n * tree) passes an override rather than re-authoring the spec.\n */\nexport const libraryBlockConfigs: BlockSpec<any>[] = [\n defineBlock<ChecklistData>({\n type: \"checklist\",\n schema: checklistSchema,\n mdx: checklistMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n notionCompatible: true,\n label: \"Checklist\",\n description:\n \"A list of toggleable items, each with a label and an optional note.\",\n }),\n defineBlock<TableData>({\n type: \"table\",\n schema: tableSchema,\n mdx: tableMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n notionCompatible: true,\n label: \"Table\",\n description:\n \"A simple grid with header columns and string rows for comparisons, parameters, or structured lists.\",\n }),\n defineBlock<CodeData>({\n type: \"code\",\n schema: codeSchema,\n mdx: codeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n notionCompatible: true,\n label: \"Code\",\n description:\n \"A single syntax-highlighted code snippet (Notion-style: one border, hover language switcher + copy, collapse-to-N lines). Put several in a `tabs` block for a file rail.\",\n }),\n defineBlock<CodeTabsData>({\n type: \"code-tabs\",\n schema: codeTabsSchema,\n mdx: codeTabsMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Code tabs\",\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 defineBlock<HtmlBlockData>({\n type: \"custom-html\",\n schema: htmlSchema,\n mdx: htmlMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"HTML / Tailwind\",\n description:\n \"An author-supplied HTML (with optional CSS) fragment rendered in a sandboxed iframe, with inline source editing.\",\n }),\n defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: ServerReadStub,\n placement: [\"block\", \"inline\"],\n label: \"Tabs\",\n description:\n \"A top or side tab container; each tab holds its own list of blocks.\",\n }),\n defineBlock<ColumnsData>({\n type: \"columns\",\n schema: columnsSchema,\n mdx: columnsMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Columns\",\n description:\n \"A multi-column side-by-side layout container; each column holds its own list of blocks. Ideal for before/after or current/target comparisons.\",\n }),\n defineBlock<CalloutData>({\n type: \"callout\",\n schema: calloutSchema,\n mdx: calloutMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Callout\",\n description:\n \"An emphasized note with a tone (info/decision/risk/warning/success) and a markdown body.\",\n }),\n defineBlock<QuestionFormData>({\n type: \"question-form\",\n schema: questionFormSchema,\n mdx: questionFormMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Question form\",\n description:\n \"An interactive respondent-facing form block for open questions, single-choice or multi-choice option rows, freeform answers, recommended options, and optional wireframe/diagram previews.\",\n }),\n defineBlock<VisualQuestionsData>({\n type: \"visual-questions\",\n schema: visualQuestionsSchema,\n mdx: visualQuestionsMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Visual questions\",\n description:\n \"A visual-intake question block with the same editable question/option shape as question-form.\",\n }),\n defineBlock<DiagramData>({\n type: \"diagram\",\n schema: diagramSchema,\n mdx: diagramMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Diagram\",\n description:\n \"A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use .diagram-* primitives and --wf-* tokens for theme/sketch compatibility. Legacy nodes/edges are only for simple previews.\",\n }),\n defineBlock<WireframeData>({\n type: \"wireframe\",\n schema: wireframeSchema,\n mdx: wireframeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Wireframe\",\n description:\n \"A sketch wireframe of one screen built from kit primitives (or an HTML mockup), rendered in a chosen surface frame (desktop/mobile/popover/panel/browser).\",\n }),\n defineBlock<MermaidData>({\n type: \"mermaid\",\n schema: mermaidSchema,\n mdx: mermaidMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Diagram (Mermaid)\",\n description:\n \"A Mermaid diagram (flowchart, sequence, etc.) defined as text and rendered as a diagram.\",\n }),\n defineBlock<ApiEndpointData>({\n type: \"api-endpoint\",\n schema: apiEndpointSchema,\n mdx: apiEndpointMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"API endpoint\",\n description:\n \"A Swagger-style API endpoint reference: a colored method pill + path, collapsed by default, expanding to params, request body, and per-status response examples.\",\n }),\n defineBlock<OpenApiSpecData>({\n type: \"openapi-spec\",\n schema: openApiSpecSchema,\n mdx: openApiSpecMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"OpenAPI spec\",\n description:\n \"A whole-document API specification / Redoc / Swagger-UI-style API reference rendered from a complete OpenAPI 3 / Swagger 2 spec (JSON).\",\n }),\n defineBlock<DataModelData>({\n type: \"data-model\",\n schema: dataModelSchema,\n mdx: dataModelMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Data model\",\n description:\n \"A schema modeling / ERD / dbdiagram-style data model: entity cards with typed fields (PK/FK/nullable flags) and interactive foreign-key relations.\",\n }),\n defineBlock<DiffData>({\n type: \"diff\",\n schema: diffSchema,\n mdx: diffMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Diff\",\n description:\n \"A GitHub-style before/after line diff for a file, with unified or split view and added/removed line highlighting.\",\n }),\n defineBlock<FileTreeData>({\n type: \"file-tree\",\n schema: fileTreeSchema,\n mdx: fileTreeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"File tree\",\n description:\n \"A VS Code / GitHub-explorer file and change tree with per-file change badges, notes, and code snippets.\",\n }),\n defineBlock<JsonExplorerData>({\n type: \"json-explorer\",\n schema: jsonExplorerSchema,\n mdx: jsonExplorerMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"JSON explorer\",\n description:\n \"A collapsible browser-devtools / Postman-style JSON tree with type-colored values and expand/collapse.\",\n }),\n defineBlock<AnnotatedCodeData>({\n type: \"annotated-code\",\n schema: annotatedCodeSchema,\n mdx: annotatedCodeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Annotated code\",\n description:\n \"A line-numbered code walkthrough whose line ranges carry anchored explanatory notes.\",\n }),\n];\n\n/**\n * Per-block overrides for {@link registerLibraryBlockConfigs}, keyed by canonical\n * `type`. Servers tweak only the agent-facing fields that legitimately differ:\n * content re-types `table` → `table-block`; plan curates a longer Mermaid and\n * file-tree description. The `schema` / `mdx` config always stays shared.\n */\nexport type LibraryBlockConfigOverrides = Record<\n string,\n Partial<\n Pick<BlockSpec<any>, \"type\" | \"label\" | \"description\" | \"notionCompatible\">\n >\n>;\n\n/**\n * Register the React-free standard-library config stubs into a server / shared\n * {@link BlockRegistry}. Both `plan-block-registry.ts` and `nfm-registry.ts` call\n * this, then register only their app-specific block configs (plan adds callout /\n * diagram / wireframe / question-form) on top — so the shared library lives in\n * exactly one place across browser AND server registries.\n */\nexport function registerLibraryBlockConfigs(\n registry: BlockRegistry,\n options: { overrides?: LibraryBlockConfigOverrides } = {},\n): void {\n const overrides = options.overrides ?? {};\n const specs = libraryBlockConfigs.map((spec) => {\n const override = overrides[spec.type];\n return override ? ({ ...spec, ...override } as BlockSpec<any>) : spec;\n });\n registerBlocks(registry, specs);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server-specs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/server-specs.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerBlocks, type BlockRegistry } from \"../registry.js\";\nimport { defineBlock, type BlockSpec } from \"../types.js\";\nimport {\n annotatedCodeSchema,\n annotatedCodeMdx,\n type AnnotatedCodeData,\n} from \"./annotated-code.config.js\";\nimport {\n apiEndpointSchema,\n apiEndpointMdx,\n type ApiEndpointData,\n} from \"./api-endpoint.config.js\";\nimport {\n calloutSchema,\n calloutMdx,\n type CalloutData,\n} from \"./callout.config.js\";\n// React-free schema + MDX config for the standard library. The matching React\n// `Read`/`Edit` live in the full client entry; the server path only ever touches\n// `spec.schema` / `spec.mdx`, so these configs register with a render-only stub.\nimport {\n checklistSchema,\n checklistMdx,\n type ChecklistData,\n} from \"./checklist.config.js\";\nimport {\n codeTabsSchema,\n codeTabsMdx,\n type CodeTabsData,\n} from \"./code-tabs.config.js\";\nimport { codeSchema, codeMdx, type CodeData } from \"./code.config.js\";\nimport {\n columnsSchema,\n columnsMdx,\n type ColumnsData,\n} from \"./columns.config.js\";\nimport {\n dataModelSchema,\n dataModelMdx,\n type DataModelData,\n} from \"./data-model.config.js\";\nimport {\n diagramSchema,\n diagramMdx,\n type DiagramData,\n} from \"./diagram.config.js\";\nimport { diffSchema, diffMdx, type DiffData } from \"./diff.config.js\";\nimport {\n fileTreeSchema,\n fileTreeMdx,\n type FileTreeData,\n} from \"./file-tree.config.js\";\nimport { htmlSchema, htmlMdx, type HtmlBlockData } from \"./html.config.js\";\nimport {\n jsonExplorerSchema,\n jsonExplorerMdx,\n type JsonExplorerData,\n} from \"./json-explorer.config.js\";\nimport {\n mermaidSchema,\n mermaidMdx,\n type MermaidData,\n} from \"./mermaid.config.js\";\nimport {\n openApiSpecSchema,\n openApiSpecMdx,\n type OpenApiSpecData,\n} from \"./openapi-spec.config.js\";\nimport {\n questionFormSchema,\n questionFormMdx,\n visualQuestionsSchema,\n visualQuestionsMdx,\n type QuestionFormData,\n type VisualQuestionsData,\n} from \"./question-form.config.js\";\nimport { tableSchema, tableMdx, type TableData } from \"./table.config.js\";\nimport { tabsSchema, tabsMdx, type TabsData } from \"./tabs.config.js\";\nimport {\n wireframeSchema,\n wireframeMdx,\n type WireframeData,\n} from \"./wireframe.config.js\";\n\n/** Render-only stub for server / agent registries (never invoked off-browser). */\nconst ServerReadStub = () => null;\n\n/**\n * Canonical React-free specs for the standard library, used by BOTH apps' server\n * / shared registries (`plan-block-registry.ts`, `nfm-registry.ts`). Each carries\n * only the parts the server path touches — `schema` + `mdx` + metadata for the\n * agent schema export — with a render-only `Read` stub. The full client specs\n * (with real React `Read`/`Edit`) live in `./specs.tsx`; both share the identical\n * `schema`/`mdx` config so inline source can never drift from what renders.\n *\n * `table` keeps the core default `type` here; content's server registry renames\n * it to `table-block` via {@link LibraryBlockConfigOverrides}. The descriptions\n * are the neutral agent-schema phrasing; an app that curates a longer\n * description for a block (e.g. plan's hand-drawn Mermaid, plan's detailed file\n * tree) passes an override rather than re-authoring the spec.\n */\nexport const libraryBlockConfigs: BlockSpec<any>[] = [\n defineBlock<ChecklistData>({\n type: \"checklist\",\n schema: checklistSchema,\n mdx: checklistMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n notionCompatible: true,\n label: \"Checklist\",\n description:\n \"A list of toggleable items, each with a label and an optional note.\",\n }),\n defineBlock<TableData>({\n type: \"table\",\n schema: tableSchema,\n mdx: tableMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n notionCompatible: true,\n label: \"Table\",\n description:\n \"A simple grid with header columns and string rows for comparisons, parameters, or structured lists.\",\n }),\n defineBlock<CodeData>({\n type: \"code\",\n schema: codeSchema,\n mdx: codeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n notionCompatible: true,\n label: \"Code\",\n description:\n \"A single syntax-highlighted code snippet (Notion-style: one border, hover language switcher + copy, collapse-to-N lines). Put several in a `tabs` block for a file rail.\",\n }),\n defineBlock<CodeTabsData>({\n type: \"code-tabs\",\n schema: codeTabsSchema,\n mdx: codeTabsMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Code tabs\",\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 defineBlock<HtmlBlockData>({\n type: \"custom-html\",\n schema: htmlSchema,\n mdx: htmlMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"HTML / Tailwind\",\n description:\n \"An author-supplied HTML (with optional CSS) fragment rendered in a sandboxed iframe, with inline source editing.\",\n }),\n defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: ServerReadStub,\n placement: [\"block\", \"inline\"],\n label: \"Tabs\",\n description:\n \"A top or side tab container; each tab holds its own list of blocks.\",\n }),\n defineBlock<ColumnsData>({\n type: \"columns\",\n schema: columnsSchema,\n mdx: columnsMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Columns\",\n description:\n \"A multi-column side-by-side layout container; each column holds its own list of blocks. Ideal for before/after or current/target comparisons.\",\n }),\n defineBlock<CalloutData>({\n type: \"callout\",\n schema: calloutSchema,\n mdx: calloutMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Callout\",\n description:\n \"An emphasized note with a tone (info/decision/risk/warning/success) and a markdown body.\",\n }),\n defineBlock<QuestionFormData>({\n type: \"question-form\",\n schema: questionFormSchema,\n mdx: questionFormMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Question form\",\n description:\n \"An interactive respondent-facing form block for open questions, single-choice or multi-choice option rows, freeform answers, recommended options, and optional wireframe/diagram previews.\",\n }),\n defineBlock<VisualQuestionsData>({\n type: \"visual-questions\",\n schema: visualQuestionsSchema,\n mdx: visualQuestionsMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Visual questions\",\n description:\n \"A visual-intake question block with the same editable question/option shape as question-form.\",\n }),\n defineBlock<DiagramData>({\n type: \"diagram\",\n schema: diagramSchema,\n mdx: diagramMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Diagram\",\n description:\n \"A flexible inline architecture/code diagram. Prefer html/css with SVG or semantic HTML for polished two-dimensional layouts; use .diagram-* primitives and --wf-* tokens for theme/sketch compatibility. Set frame to show for standalone artifacts that need containment, hide when surrounding docs/canvas chrome already supplies the boundary. Legacy nodes/edges are only for simple previews.\",\n }),\n defineBlock<WireframeData>({\n type: \"wireframe\",\n schema: wireframeSchema,\n mdx: wireframeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Wireframe\",\n description:\n \"A sketch wireframe of one screen built from kit primitives (or an HTML mockup), rendered in a chosen surface (desktop/mobile/popover/panel/browser). Set frame to show for standalone screens and recap comparisons, hide only when surrounding chrome already supplies the boundary.\",\n }),\n defineBlock<MermaidData>({\n type: \"mermaid\",\n schema: mermaidSchema,\n mdx: mermaidMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Diagram (Mermaid)\",\n description:\n \"A Mermaid diagram (flowchart, sequence, etc.) defined as text and rendered as a diagram.\",\n }),\n defineBlock<ApiEndpointData>({\n type: \"api-endpoint\",\n schema: apiEndpointSchema,\n mdx: apiEndpointMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"API endpoint\",\n description:\n \"A Swagger-style API endpoint reference: a colored method pill + path, collapsed by default, expanding to params, request body, and per-status response examples.\",\n }),\n defineBlock<OpenApiSpecData>({\n type: \"openapi-spec\",\n schema: openApiSpecSchema,\n mdx: openApiSpecMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"OpenAPI spec\",\n description:\n \"A whole-document API specification / Redoc / Swagger-UI-style API reference rendered from a complete OpenAPI 3 / Swagger 2 spec (JSON).\",\n }),\n defineBlock<DataModelData>({\n type: \"data-model\",\n schema: dataModelSchema,\n mdx: dataModelMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Data model\",\n description:\n \"A schema modeling / ERD / dbdiagram-style data model: entity cards with typed fields (PK/FK/nullable flags) and interactive foreign-key relations.\",\n }),\n defineBlock<DiffData>({\n type: \"diff\",\n schema: diffSchema,\n mdx: diffMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Diff\",\n description:\n \"A GitHub-style before/after line diff for a file, with unified or split view and added/removed line highlighting.\",\n }),\n defineBlock<FileTreeData>({\n type: \"file-tree\",\n schema: fileTreeSchema,\n mdx: fileTreeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"File tree\",\n description:\n \"A VS Code / GitHub-explorer file and change tree with per-file change badges, notes, and code snippets.\",\n }),\n defineBlock<JsonExplorerData>({\n type: \"json-explorer\",\n schema: jsonExplorerSchema,\n mdx: jsonExplorerMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"JSON explorer\",\n description:\n \"A collapsible browser-devtools / Postman-style JSON tree with type-colored values and expand/collapse.\",\n }),\n defineBlock<AnnotatedCodeData>({\n type: \"annotated-code\",\n schema: annotatedCodeSchema,\n mdx: annotatedCodeMdx,\n Read: ServerReadStub,\n placement: [\"block\"],\n label: \"Annotated code\",\n description:\n \"A line-numbered code walkthrough whose line ranges carry anchored explanatory notes.\",\n }),\n];\n\n/**\n * Per-block overrides for {@link registerLibraryBlockConfigs}, keyed by canonical\n * `type`. Servers tweak only the agent-facing fields that legitimately differ:\n * content re-types `table` → `table-block`; plan curates a longer Mermaid and\n * file-tree description. The `schema` / `mdx` config always stays shared.\n */\nexport type LibraryBlockConfigOverrides = Record<\n string,\n Partial<\n Pick<BlockSpec<any>, \"type\" | \"label\" | \"description\" | \"notionCompatible\">\n >\n>;\n\n/**\n * Register the React-free standard-library config stubs into a server / shared\n * {@link BlockRegistry}. Both `plan-block-registry.ts` and `nfm-registry.ts` call\n * this, then register only their app-specific block configs (plan adds callout /\n * diagram / wireframe / question-form) on top — so the shared library lives in\n * exactly one place across browser AND server registries.\n */\nexport function registerLibraryBlockConfigs(\n registry: BlockRegistry,\n options: { overrides?: LibraryBlockConfigOverrides } = {},\n): void {\n const overrides = options.overrides ?? {};\n const specs = libraryBlockConfigs.map((spec) => {\n const override = overrides[spec.type];\n return override ? ({ ...spec, ...override } as BlockSpec<any>) : spec;\n });\n registerBlocks(registry, specs);\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { BlockMdxConfig } from "../types.js";
|
|
2
|
+
import type { BlockMdxConfig, BlockVisualFrame } from "../types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Pure (React-free) part of the shared `wireframe` block: its data shape, zod
|
|
5
5
|
* schema, the stable node-id helper, and the nested-MDX round-trip config. Lives
|
|
@@ -84,6 +84,8 @@ export interface WireframeData {
|
|
|
84
84
|
/** `design` renders full-fidelity branded HTML/CSS instead of a sketch. */
|
|
85
85
|
renderMode?: WireframeRenderMode;
|
|
86
86
|
caption?: string;
|
|
87
|
+
/** Outer surface frame. `auto` lets the host choose the right default. */
|
|
88
|
+
frame?: BlockVisualFrame;
|
|
87
89
|
/**
|
|
88
90
|
* Neutral, textless loading register. The renderer drops borders, the sketch
|
|
89
91
|
* outline, and color, rendering soft placeholder geometry only.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wireframe.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"wireframe.config.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEzD,gFAAgF;AAChF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;AAE3E;;;;GAIG;AACH,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,YAAY,GACZ,WAAW,GACX,SAAS,GACT,KAAK,GACL,KAAK,GACL,SAAS,GACT,SAAS,GACT,MAAM,GACN,OAAO,GACP,MAAM,GACN,OAAO,GACP,SAAS,GACT,SAAS,GACT,OAAO,GACP,MAAM,GACN,MAAM,GACN,OAAO,GACP,OAAO,GACP,KAAK,GACL,KAAK,GACL,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,IAAI,GACJ,WAAW,GACX,KAAK,GACL,SAAS,CAAC;AAEd;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,yEAAyE;IACzE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,eAAe,CAAC;IACpB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAG3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAG5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,aAAa,CAAC;IAGxB,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC,CAAC;IACH,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAMhD,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,EA8B/C,CAAC;AAmFF,eAAO,MAAM,eAAe,EAwBG,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;AAMxD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAiMD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,aAAa,CAWtD,CAAC"}
|
|
@@ -44,6 +44,7 @@ export const WIREFRAME_EL_NAMES = [
|
|
|
44
44
|
const toneSchema = z.enum(["default", "accent", "warn", "ok", "muted"]);
|
|
45
45
|
const elNameSchema = z.enum(WIREFRAME_EL_NAMES);
|
|
46
46
|
const idSchema = z.string().trim().min(1).max(120);
|
|
47
|
+
const visualFrameSchema = z.enum(["auto", "show", "hide"]);
|
|
47
48
|
/**
|
|
48
49
|
* Reject full-document HTML (html/head/body/script/style tags) in the `html` /
|
|
49
50
|
* `css` fields. Wireframe content must be a bounded fragment; document or script
|
|
@@ -106,6 +107,7 @@ export const wireframeSchema = z
|
|
|
106
107
|
surface: z.enum(["desktop", "mobile", "popover", "panel", "browser"]),
|
|
107
108
|
renderMode: z.enum(["wireframe", "design"]).optional(),
|
|
108
109
|
caption: z.string().trim().max(400).optional(),
|
|
110
|
+
frame: visualFrameSchema.optional(),
|
|
109
111
|
skeleton: z.boolean().optional(),
|
|
110
112
|
html: z
|
|
111
113
|
.string()
|
|
@@ -199,6 +201,7 @@ function serializeScreen(data) {
|
|
|
199
201
|
prop("surface", data.surface),
|
|
200
202
|
prop("renderMode", data.renderMode),
|
|
201
203
|
prop("caption", data.caption),
|
|
204
|
+
prop("frame", data.frame),
|
|
202
205
|
prop("html", data.html),
|
|
203
206
|
prop("css", data.css),
|
|
204
207
|
prop("skeleton", data.skeleton),
|
|
@@ -274,6 +277,7 @@ function parseScreen(node, idContext) {
|
|
|
274
277
|
surface: stringAttr(node, "surface") ?? "desktop",
|
|
275
278
|
renderMode: stringAttr(node, "renderMode"),
|
|
276
279
|
caption: stringAttr(node, "caption"),
|
|
280
|
+
frame: stringAttr(node, "frame"),
|
|
277
281
|
html: requiredStringAttr(node, "html"),
|
|
278
282
|
css: requiredStringAttr(node, "css"),
|
|
279
283
|
skeleton: boolAttr(node, "skeleton"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wireframe.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.config.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { prop, attributeValue } from \"../mdx.js\";\nimport type { BlockMdxConfig } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the shared `wireframe` block: its data shape, zod\n * schema, the stable node-id helper, and the nested-MDX round-trip config. Lives\n * in core so BOTH apps' server/shared registries and the client spec\n * (`wireframe.tsx`) consume one definition; importing it into a server module\n * never pulls React into the Nitro/SSR bundle.\n *\n * The wireframe block originated in the plan template. The vocabulary\n * (`PlanWireframe*` names, the `el` set, the `--wf-*` token contract) and the\n * MDX encoding (`<WireframeBlock>…<Screen>…</Screen></WireframeBlock>` with kit\n * component names `FrameScreen`/`Row`/`Col`/…) are preserved EXACTLY so stored\n * plans round-trip byte-compatibly and existing node ids never change.\n *\n * The wireframe is NESTED MDX, not a flat-attribute or prose block: its body is\n * a `<Screen surface caption>…kit-tree…</Screen>` subtree. So the config uses\n * `serializeChildren`/`parseChildren` (the registry's nested-MDX path) rather\n * than `toAttrs`/`childrenField`.\n */\n\n/* -------------------------------------------------------------------------- */\n/* Vocabulary (decoupled copy of the plan-content wireframe types) */\n/* -------------------------------------------------------------------------- */\n\nexport type WireframeSurface =\n | \"desktop\"\n | \"mobile\"\n | \"popover\"\n | \"panel\"\n | \"browser\";\n\nexport type WireframeRenderMode = \"wireframe\" | \"design\";\n\n/** Tone keyword reused across screen primitives. The renderer maps to color. */\nexport type WireframeTone = \"default\" | \"accent\" | \"warn\" | \"ok\" | \"muted\";\n\n/**\n * Names of the kit primitives. Component-like (MDX-friendly). The renderer maps\n * each to a flex kit component. Layout is ALWAYS flex; row/col/sidebar/main set\n * the flex direction.\n */\nexport type WireframeElName =\n | \"screen\"\n | \"browserBar\"\n | \"statusBar\"\n | \"toolbar\"\n | \"row\"\n | \"col\"\n | \"sidebar\"\n | \"navItem\"\n | \"main\"\n | \"title\"\n | \"text\"\n | \"lines\"\n | \"section\"\n | \"taskRow\"\n | \"chips\"\n | \"chip\"\n | \"pill\"\n | \"check\"\n | \"field\"\n | \"btn\"\n | \"fab\"\n | \"card\"\n | \"column\"\n | \"avatar\"\n | \"iconSquare\"\n | \"kv\"\n | \"searchBar\"\n | \"box\"\n | \"divider\";\n\n/**\n * A single node in the wireframe kit tree. `el` is the primitive name; the\n * remaining props are the union of every primitive's props (kept permissive so\n * the model can compose freely). `children` nests other nodes. `id` is a stable\n * node id used by node-addressable patch ops (auto-assigned on create).\n *\n * There is intentionally NO x/y/width/height here — wireframe internals are\n * geometry-free and laid out by the renderer with flex.\n */\nexport type WireframeNode = {\n /** Stable id for node-addressable patches; auto-assigned when absent. */\n id?: string;\n el: WireframeElName;\n children?: WireframeNode[];\n\n // Generic content props\n text?: string;\n value?: string;\n label?: string;\n placeholder?: string;\n title?: string;\n\n // Styling-by-intent (semantic only; renderer owns actual color/size)\n tone?: WireframeTone;\n color?: WireframeTone;\n weight?: \"normal\" | \"medium\" | \"bold\";\n active?: boolean;\n done?: boolean;\n emphasis?: boolean;\n full?: boolean;\n solid?: boolean;\n dashed?: boolean;\n dot?: boolean;\n script?: boolean;\n area?: boolean;\n shape?: \"square\" | \"circle\";\n\n // Numeric / structured props\n count?: number;\n prio?: number;\n n?: number;\n widths?: number[];\n icon?: string;\n\n // taskRow specifics\n note?: string;\n due?: string;\n dueTone?: WireframeTone;\n\n // Collection props (chips, kv)\n items?: Array<{\n label: string;\n active?: boolean;\n count?: number;\n dot?: boolean;\n }>;\n rows?: Array<{ k: string; v: string }>;\n};\n\nexport interface WireframeData {\n surface: WireframeSurface;\n /** `design` renders full-fidelity branded HTML/CSS instead of a sketch. */\n renderMode?: WireframeRenderMode;\n caption?: string;\n /**\n * Neutral, textless loading register. The renderer drops borders, the sketch\n * outline, and color, rendering soft placeholder geometry only.\n */\n skeleton?: boolean;\n /**\n * PRIMARY content: a self-contained HTML mockup of the screen (sanitized\n * fragment — no document/script/style tags). The renderer owns the surface\n * aspect, the dark/light theme, the hand-drawn font, and the rough overlay.\n * When `html` is set, `screen` is ignored.\n */\n html?: string;\n /** Optional scoped CSS for the html mockup (sanitized fragment). */\n css?: string;\n /** Kit-tree screen. Used when `html` is absent. */\n screen?: WireframeNode[];\n}\n\nexport const WIREFRAME_SURFACES: WireframeSurface[] = [\n \"desktop\",\n \"mobile\",\n \"popover\",\n \"panel\",\n \"browser\",\n];\n\nexport const WIREFRAME_EL_NAMES: WireframeElName[] = [\n \"screen\",\n \"browserBar\",\n \"statusBar\",\n \"toolbar\",\n \"row\",\n \"col\",\n \"sidebar\",\n \"navItem\",\n \"main\",\n \"title\",\n \"text\",\n \"lines\",\n \"section\",\n \"taskRow\",\n \"chips\",\n \"chip\",\n \"pill\",\n \"check\",\n \"field\",\n \"btn\",\n \"fab\",\n \"card\",\n \"column\",\n \"avatar\",\n \"iconSquare\",\n \"kv\",\n \"searchBar\",\n \"box\",\n \"divider\",\n];\n\n/* -------------------------------------------------------------------------- */\n/* Schema (mirrors the plan-content wireframeDataSchema) */\n/* -------------------------------------------------------------------------- */\n\nconst toneSchema = z.enum([\"default\", \"accent\", \"warn\", \"ok\", \"muted\"]);\nconst elNameSchema = z.enum(\n WIREFRAME_EL_NAMES as [WireframeElName, ...WireframeElName[]],\n);\nconst idSchema = z.string().trim().min(1).max(120);\n\n/**\n * Reject full-document HTML (html/head/body/script/style tags) in the `html` /\n * `css` fields. Wireframe content must be a bounded fragment; document or script\n * tags are a stored-XSS and layout-escape hazard.\n */\nfunction noFullHtmlDocument(value: string): boolean {\n return !/<\\s*(?:!doctype|html|head|body|script|style)\\b/i.test(value);\n}\n\nconst wireframeNodeSchema: z.ZodType<WireframeNode> = z.lazy(() =>\n z\n .object({\n id: idSchema.optional(),\n el: elNameSchema,\n children: z.array(wireframeNodeSchema).max(60).optional(),\n\n text: z.string().trim().max(400).optional(),\n value: z.string().trim().max(400).optional(),\n label: z.string().trim().max(200).optional(),\n placeholder: z.string().trim().max(200).optional(),\n title: z.string().trim().max(200).optional(),\n\n tone: toneSchema.optional(),\n color: toneSchema.optional(),\n weight: z.enum([\"normal\", \"medium\", \"bold\"]).optional(),\n active: z.boolean().optional(),\n done: z.boolean().optional(),\n emphasis: z.boolean().optional(),\n full: z.boolean().optional(),\n solid: z.boolean().optional(),\n dashed: z.boolean().optional(),\n dot: z.boolean().optional(),\n script: z.boolean().optional(),\n area: z.boolean().optional(),\n shape: z.enum([\"square\", \"circle\"]).optional(),\n\n count: z.number().int().min(0).max(9_999).optional(),\n prio: z.number().int().min(0).max(9).optional(),\n n: z.number().int().min(0).max(20).optional(),\n widths: z.array(z.number().min(0).max(100)).max(20).optional(),\n icon: z.string().trim().max(40).optional(),\n\n note: z.string().trim().max(400).optional(),\n due: z.string().trim().max(120).optional(),\n dueTone: toneSchema.optional(),\n\n items: z\n .array(\n z.object({\n label: z.string().trim().min(1).max(200),\n active: z.boolean().optional(),\n count: z.number().int().min(0).max(9_999).optional(),\n dot: z.boolean().optional(),\n }),\n )\n .max(40)\n .optional(),\n rows: z\n .array(\n z.object({\n k: z.string().trim().min(1).max(200),\n v: z.string().trim().max(400),\n }),\n )\n .max(40)\n .optional(),\n })\n .passthrough(),\n) as z.ZodType<WireframeNode>;\n\nexport const wireframeSchema = z\n .object({\n surface: z.enum([\"desktop\", \"mobile\", \"popover\", \"panel\", \"browser\"]),\n renderMode: z.enum([\"wireframe\", \"design\"]).optional(),\n caption: z.string().trim().max(400).optional(),\n skeleton: z.boolean().optional(),\n html: z\n .string()\n .max(40_000)\n .refine(noFullHtmlDocument, {\n message:\n \"Wireframe html must be a bounded fragment without html/head/body/script/style tags.\",\n })\n .optional(),\n css: z\n .string()\n .max(20_000)\n .refine(noFullHtmlDocument, {\n message: \"Wireframe css must not include document or script tags.\",\n })\n .optional(),\n screen: z.array(wireframeNodeSchema).max(200).optional(),\n })\n .passthrough() as unknown as z.ZodType<WireframeData>;\n\n/* -------------------------------------------------------------------------- */\n/* Stable node-id derivation (verbatim from plan-mdx.ts) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Derive a stable node id from the element name and tree path. Re-runs identically\n * to the legacy plan derivation so stored plans round-trip without changing ids.\n */\nexport function createStableWireframeNodeId(\n el: WireframeElName,\n path: string,\n): string {\n return `node-${el}-${path}`\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Kit node <-> MDX component name maps (mirrors plan-mdx.ts NODE_TO_COMPONENT) */\n/* -------------------------------------------------------------------------- */\n\nconst NODE_TO_COMPONENT: Record<WireframeElName, string> = {\n screen: \"FrameScreen\",\n browserBar: \"BrowserBar\",\n statusBar: \"StatusBar\",\n toolbar: \"Toolbar\",\n row: \"Row\",\n col: \"Col\",\n sidebar: \"Sidebar\",\n navItem: \"NavItem\",\n main: \"Main\",\n title: \"Title\",\n text: \"Text\",\n lines: \"Lines\",\n section: \"SectionLabel\",\n taskRow: \"TaskRow\",\n chips: \"Chips\",\n chip: \"Chip\",\n pill: \"Pill\",\n check: \"Check\",\n field: \"Field\",\n btn: \"Btn\",\n fab: \"Fab\",\n card: \"Card\",\n column: \"Column\",\n avatar: \"Avatar\",\n iconSquare: \"IconSquare\",\n kv: \"KV\",\n searchBar: \"SearchBar\",\n box: \"Box\",\n divider: \"Divider\",\n};\n\nconst COMPONENT_TO_NODE = Object.fromEntries(\n Object.entries(NODE_TO_COMPONENT).map(([el, component]) => [component, el]),\n) as Record<string, WireframeElName>;\n\n/* -------------------------------------------------------------------------- */\n/* Serialize (verbatim port of plan-mdx.ts serializeNode/serializeScreen) */\n/* -------------------------------------------------------------------------- */\n\nfunction serializeNode(node: WireframeNode, indent = \"\"): string {\n const name = NODE_TO_COMPONENT[node.el] ?? \"Box\";\n const attrs = Object.entries(node)\n .filter(([key]) => key !== \"children\" && key !== \"el\")\n .map(([key, value]) => prop(key, value))\n .join(\"\");\n if (!node.children?.length) return `${indent}<${name}${attrs} />`;\n const children = node.children\n .map((child) => serializeNode(child, `${indent} `))\n .join(\"\\n\");\n return `${indent}<${name}${attrs}>\\n${children}\\n${indent}</${name}>`;\n}\n\n/**\n * Serialize the wireframe data to its inner `<Screen>` MDX subtree. The registry\n * serializer wraps this between the `<WireframeBlock …>` open/close tags, so the\n * total output equals the legacy `serializeBlock` wireframe branch exactly.\n */\nfunction serializeScreen(data: WireframeData): string {\n const attrs = [\n prop(\"surface\", data.surface),\n prop(\"renderMode\", data.renderMode),\n prop(\"caption\", data.caption),\n prop(\"html\", data.html),\n prop(\"css\", data.css),\n prop(\"skeleton\", data.skeleton),\n ].join(\"\");\n const children = (data.screen ?? [])\n .map((node) => serializeNode(node, \" \"))\n .join(\"\\n\");\n if (!children) return `<Screen${attrs} />`;\n return `<Screen${attrs}>\\n${children}\\n</Screen>`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Parse (verbatim port of plan-mdx.ts parseScreen/parseWireframeNode) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Minimal MDX AST node shape used while walking the wireframe subtree. Declared\n * standalone (not an intersection with `MdxJsxNode`, whose `children` is\n * `unknown[]`) so recursive `children` stays narrowed to `WireframeMdxNode`.\n */\ntype WireframeMdxNode = {\n type: string;\n name?: string;\n attributes?: Array<{\n type: string;\n name?: string;\n value?: string | null | { type: string; value: string; data?: unknown };\n }>;\n children?: WireframeMdxNode[];\n};\n\nfunction elementName(node: WireframeMdxNode | undefined): string | undefined {\n return node?.type === \"mdxJsxFlowElement\" ||\n node?.type === \"mdxJsxTextElement\"\n ? node.name\n : undefined;\n}\n\nfunction findAttribute(node: WireframeMdxNode, name: string) {\n return node.attributes?.find(\n (attr) => attr.type === \"mdxJsxAttribute\" && attr.name === name,\n );\n}\n\nfunction stringAttr(node: WireframeMdxNode, name: string): string | undefined {\n const value = attributeValue(findAttribute(node, name));\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Resolve a required-when-present string attribute on a `<Screen>`. If the\n * attribute is absent we return undefined, but if it is present yet cannot be\n * resolved to a string (e.g. a number, an object, or an unevaluable expression)\n * we THROW so a malformed wireframe fails the import instead of silently\n * dropping the value and rendering an empty wireframe.\n */\nfunction requiredStringAttr(\n node: WireframeMdxNode,\n name: string,\n): string | undefined {\n const attr = findAttribute(node, name);\n if (!attr) return undefined;\n const value = attributeValue(attr);\n if (typeof value !== \"string\") {\n throw new Error(\n `Wireframe <Screen> attribute \"${name}\" must resolve to a string, got ${typeof value}. Use a quoted string or a static template literal.`,\n );\n }\n return value;\n}\n\nfunction boolAttr(node: WireframeMdxNode, name: string): boolean | undefined {\n const value = attributeValue(findAttribute(node, name));\n return typeof value === \"boolean\" ? value : undefined;\n}\n\nfunction parseWireframeNode(\n node: WireframeMdxNode,\n path = \"node\",\n): WireframeNode | null {\n const component = elementName(node);\n if (!component) return null;\n const el = COMPONENT_TO_NODE[component];\n if (!el) return null;\n const attrs = node.attributes ?? [];\n const parsed: WireframeNode = { el };\n for (const attr of attrs) {\n if (attr.type !== \"mdxJsxAttribute\") continue;\n const value = attributeValue(attr);\n if (value !== undefined)\n (parsed as Record<string, unknown>)[attr.name as string] = value;\n }\n parsed.el = el;\n parsed.id ??= createStableWireframeNodeId(el, path);\n const children = (node.children ?? [])\n .map((child, index) => parseWireframeNode(child, `${path}-${index}`))\n .filter(Boolean) as WireframeNode[];\n if (children.length > 0) parsed.children = children;\n return parsed;\n}\n\nfunction parseScreen(node: WireframeMdxNode, idContext: string): WireframeData {\n return {\n surface:\n (stringAttr(node, \"surface\") as WireframeData[\"surface\"]) ?? \"desktop\",\n renderMode: stringAttr(node, \"renderMode\") as WireframeData[\"renderMode\"],\n caption: stringAttr(node, \"caption\"),\n html: requiredStringAttr(node, \"html\"),\n css: requiredStringAttr(node, \"css\"),\n skeleton: boolAttr(node, \"skeleton\"),\n screen: (node.children ?? [])\n .map((child, index) =>\n parseWireframeNode(child, `${idContext}-screen-${index}`),\n )\n .filter(Boolean) as WireframeNode[],\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* MDX config */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Registry MDX config for the wireframe block. `tag` matches the legacy\n * `WireframeBlock`. The block has no flat attributes (`toAttrs` → `{}`); all data\n * lives in the nested `<Screen>` subtree handled by `serializeChildren` /\n * `parseChildren`. The registry serializer wraps `serializeChildren` between the\n * `<WireframeBlock>` open/close, producing the exact legacy bytes. On parse, the\n * registry passes the already-extended `${idContext}-${blockId}` to\n * `parseChildren` — the same id base the legacy `parseScreen` receives — so node\n * ids are reproduced identically.\n */\nexport const wireframeMdx: BlockMdxConfig<WireframeData> = {\n tag: \"WireframeBlock\",\n toAttrs: () => ({}),\n fromAttrs: () => ({ surface: \"desktop\", screen: [] }),\n serializeChildren: (data) => serializeScreen(data),\n parseChildren: (childNodes, idContext) => {\n const nodes = childNodes as WireframeMdxNode[];\n const screen = nodes.find((child) => elementName(child) === \"Screen\");\n if (!screen) return { surface: \"desktop\", screen: [] };\n return parseScreen(screen, idContext);\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"wireframe.config.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.config.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { prop, attributeValue } from \"../mdx.js\";\nimport type { BlockMdxConfig, BlockVisualFrame } from \"../types.js\";\n\n/**\n * Pure (React-free) part of the shared `wireframe` block: its data shape, zod\n * schema, the stable node-id helper, and the nested-MDX round-trip config. Lives\n * in core so BOTH apps' server/shared registries and the client spec\n * (`wireframe.tsx`) consume one definition; importing it into a server module\n * never pulls React into the Nitro/SSR bundle.\n *\n * The wireframe block originated in the plan template. The vocabulary\n * (`PlanWireframe*` names, the `el` set, the `--wf-*` token contract) and the\n * MDX encoding (`<WireframeBlock>…<Screen>…</Screen></WireframeBlock>` with kit\n * component names `FrameScreen`/`Row`/`Col`/…) are preserved EXACTLY so stored\n * plans round-trip byte-compatibly and existing node ids never change.\n *\n * The wireframe is NESTED MDX, not a flat-attribute or prose block: its body is\n * a `<Screen surface caption>…kit-tree…</Screen>` subtree. So the config uses\n * `serializeChildren`/`parseChildren` (the registry's nested-MDX path) rather\n * than `toAttrs`/`childrenField`.\n */\n\n/* -------------------------------------------------------------------------- */\n/* Vocabulary (decoupled copy of the plan-content wireframe types) */\n/* -------------------------------------------------------------------------- */\n\nexport type WireframeSurface =\n | \"desktop\"\n | \"mobile\"\n | \"popover\"\n | \"panel\"\n | \"browser\";\n\nexport type WireframeRenderMode = \"wireframe\" | \"design\";\n\n/** Tone keyword reused across screen primitives. The renderer maps to color. */\nexport type WireframeTone = \"default\" | \"accent\" | \"warn\" | \"ok\" | \"muted\";\n\n/**\n * Names of the kit primitives. Component-like (MDX-friendly). The renderer maps\n * each to a flex kit component. Layout is ALWAYS flex; row/col/sidebar/main set\n * the flex direction.\n */\nexport type WireframeElName =\n | \"screen\"\n | \"browserBar\"\n | \"statusBar\"\n | \"toolbar\"\n | \"row\"\n | \"col\"\n | \"sidebar\"\n | \"navItem\"\n | \"main\"\n | \"title\"\n | \"text\"\n | \"lines\"\n | \"section\"\n | \"taskRow\"\n | \"chips\"\n | \"chip\"\n | \"pill\"\n | \"check\"\n | \"field\"\n | \"btn\"\n | \"fab\"\n | \"card\"\n | \"column\"\n | \"avatar\"\n | \"iconSquare\"\n | \"kv\"\n | \"searchBar\"\n | \"box\"\n | \"divider\";\n\n/**\n * A single node in the wireframe kit tree. `el` is the primitive name; the\n * remaining props are the union of every primitive's props (kept permissive so\n * the model can compose freely). `children` nests other nodes. `id` is a stable\n * node id used by node-addressable patch ops (auto-assigned on create).\n *\n * There is intentionally NO x/y/width/height here — wireframe internals are\n * geometry-free and laid out by the renderer with flex.\n */\nexport type WireframeNode = {\n /** Stable id for node-addressable patches; auto-assigned when absent. */\n id?: string;\n el: WireframeElName;\n children?: WireframeNode[];\n\n // Generic content props\n text?: string;\n value?: string;\n label?: string;\n placeholder?: string;\n title?: string;\n\n // Styling-by-intent (semantic only; renderer owns actual color/size)\n tone?: WireframeTone;\n color?: WireframeTone;\n weight?: \"normal\" | \"medium\" | \"bold\";\n active?: boolean;\n done?: boolean;\n emphasis?: boolean;\n full?: boolean;\n solid?: boolean;\n dashed?: boolean;\n dot?: boolean;\n script?: boolean;\n area?: boolean;\n shape?: \"square\" | \"circle\";\n\n // Numeric / structured props\n count?: number;\n prio?: number;\n n?: number;\n widths?: number[];\n icon?: string;\n\n // taskRow specifics\n note?: string;\n due?: string;\n dueTone?: WireframeTone;\n\n // Collection props (chips, kv)\n items?: Array<{\n label: string;\n active?: boolean;\n count?: number;\n dot?: boolean;\n }>;\n rows?: Array<{ k: string; v: string }>;\n};\n\nexport interface WireframeData {\n surface: WireframeSurface;\n /** `design` renders full-fidelity branded HTML/CSS instead of a sketch. */\n renderMode?: WireframeRenderMode;\n caption?: string;\n /** Outer surface frame. `auto` lets the host choose the right default. */\n frame?: BlockVisualFrame;\n /**\n * Neutral, textless loading register. The renderer drops borders, the sketch\n * outline, and color, rendering soft placeholder geometry only.\n */\n skeleton?: boolean;\n /**\n * PRIMARY content: a self-contained HTML mockup of the screen (sanitized\n * fragment — no document/script/style tags). The renderer owns the surface\n * aspect, the dark/light theme, the hand-drawn font, and the rough overlay.\n * When `html` is set, `screen` is ignored.\n */\n html?: string;\n /** Optional scoped CSS for the html mockup (sanitized fragment). */\n css?: string;\n /** Kit-tree screen. Used when `html` is absent. */\n screen?: WireframeNode[];\n}\n\nexport const WIREFRAME_SURFACES: WireframeSurface[] = [\n \"desktop\",\n \"mobile\",\n \"popover\",\n \"panel\",\n \"browser\",\n];\n\nexport const WIREFRAME_EL_NAMES: WireframeElName[] = [\n \"screen\",\n \"browserBar\",\n \"statusBar\",\n \"toolbar\",\n \"row\",\n \"col\",\n \"sidebar\",\n \"navItem\",\n \"main\",\n \"title\",\n \"text\",\n \"lines\",\n \"section\",\n \"taskRow\",\n \"chips\",\n \"chip\",\n \"pill\",\n \"check\",\n \"field\",\n \"btn\",\n \"fab\",\n \"card\",\n \"column\",\n \"avatar\",\n \"iconSquare\",\n \"kv\",\n \"searchBar\",\n \"box\",\n \"divider\",\n];\n\n/* -------------------------------------------------------------------------- */\n/* Schema (mirrors the plan-content wireframeDataSchema) */\n/* -------------------------------------------------------------------------- */\n\nconst toneSchema = z.enum([\"default\", \"accent\", \"warn\", \"ok\", \"muted\"]);\nconst elNameSchema = z.enum(\n WIREFRAME_EL_NAMES as [WireframeElName, ...WireframeElName[]],\n);\nconst idSchema = z.string().trim().min(1).max(120);\nconst visualFrameSchema = z.enum([\"auto\", \"show\", \"hide\"]);\n\n/**\n * Reject full-document HTML (html/head/body/script/style tags) in the `html` /\n * `css` fields. Wireframe content must be a bounded fragment; document or script\n * tags are a stored-XSS and layout-escape hazard.\n */\nfunction noFullHtmlDocument(value: string): boolean {\n return !/<\\s*(?:!doctype|html|head|body|script|style)\\b/i.test(value);\n}\n\nconst wireframeNodeSchema: z.ZodType<WireframeNode> = z.lazy(() =>\n z\n .object({\n id: idSchema.optional(),\n el: elNameSchema,\n children: z.array(wireframeNodeSchema).max(60).optional(),\n\n text: z.string().trim().max(400).optional(),\n value: z.string().trim().max(400).optional(),\n label: z.string().trim().max(200).optional(),\n placeholder: z.string().trim().max(200).optional(),\n title: z.string().trim().max(200).optional(),\n\n tone: toneSchema.optional(),\n color: toneSchema.optional(),\n weight: z.enum([\"normal\", \"medium\", \"bold\"]).optional(),\n active: z.boolean().optional(),\n done: z.boolean().optional(),\n emphasis: z.boolean().optional(),\n full: z.boolean().optional(),\n solid: z.boolean().optional(),\n dashed: z.boolean().optional(),\n dot: z.boolean().optional(),\n script: z.boolean().optional(),\n area: z.boolean().optional(),\n shape: z.enum([\"square\", \"circle\"]).optional(),\n\n count: z.number().int().min(0).max(9_999).optional(),\n prio: z.number().int().min(0).max(9).optional(),\n n: z.number().int().min(0).max(20).optional(),\n widths: z.array(z.number().min(0).max(100)).max(20).optional(),\n icon: z.string().trim().max(40).optional(),\n\n note: z.string().trim().max(400).optional(),\n due: z.string().trim().max(120).optional(),\n dueTone: toneSchema.optional(),\n\n items: z\n .array(\n z.object({\n label: z.string().trim().min(1).max(200),\n active: z.boolean().optional(),\n count: z.number().int().min(0).max(9_999).optional(),\n dot: z.boolean().optional(),\n }),\n )\n .max(40)\n .optional(),\n rows: z\n .array(\n z.object({\n k: z.string().trim().min(1).max(200),\n v: z.string().trim().max(400),\n }),\n )\n .max(40)\n .optional(),\n })\n .passthrough(),\n) as z.ZodType<WireframeNode>;\n\nexport const wireframeSchema = z\n .object({\n surface: z.enum([\"desktop\", \"mobile\", \"popover\", \"panel\", \"browser\"]),\n renderMode: z.enum([\"wireframe\", \"design\"]).optional(),\n caption: z.string().trim().max(400).optional(),\n frame: visualFrameSchema.optional(),\n skeleton: z.boolean().optional(),\n html: z\n .string()\n .max(40_000)\n .refine(noFullHtmlDocument, {\n message:\n \"Wireframe html must be a bounded fragment without html/head/body/script/style tags.\",\n })\n .optional(),\n css: z\n .string()\n .max(20_000)\n .refine(noFullHtmlDocument, {\n message: \"Wireframe css must not include document or script tags.\",\n })\n .optional(),\n screen: z.array(wireframeNodeSchema).max(200).optional(),\n })\n .passthrough() as unknown as z.ZodType<WireframeData>;\n\n/* -------------------------------------------------------------------------- */\n/* Stable node-id derivation (verbatim from plan-mdx.ts) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Derive a stable node id from the element name and tree path. Re-runs identically\n * to the legacy plan derivation so stored plans round-trip without changing ids.\n */\nexport function createStableWireframeNodeId(\n el: WireframeElName,\n path: string,\n): string {\n return `node-${el}-${path}`\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 80);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Kit node <-> MDX component name maps (mirrors plan-mdx.ts NODE_TO_COMPONENT) */\n/* -------------------------------------------------------------------------- */\n\nconst NODE_TO_COMPONENT: Record<WireframeElName, string> = {\n screen: \"FrameScreen\",\n browserBar: \"BrowserBar\",\n statusBar: \"StatusBar\",\n toolbar: \"Toolbar\",\n row: \"Row\",\n col: \"Col\",\n sidebar: \"Sidebar\",\n navItem: \"NavItem\",\n main: \"Main\",\n title: \"Title\",\n text: \"Text\",\n lines: \"Lines\",\n section: \"SectionLabel\",\n taskRow: \"TaskRow\",\n chips: \"Chips\",\n chip: \"Chip\",\n pill: \"Pill\",\n check: \"Check\",\n field: \"Field\",\n btn: \"Btn\",\n fab: \"Fab\",\n card: \"Card\",\n column: \"Column\",\n avatar: \"Avatar\",\n iconSquare: \"IconSquare\",\n kv: \"KV\",\n searchBar: \"SearchBar\",\n box: \"Box\",\n divider: \"Divider\",\n};\n\nconst COMPONENT_TO_NODE = Object.fromEntries(\n Object.entries(NODE_TO_COMPONENT).map(([el, component]) => [component, el]),\n) as Record<string, WireframeElName>;\n\n/* -------------------------------------------------------------------------- */\n/* Serialize (verbatim port of plan-mdx.ts serializeNode/serializeScreen) */\n/* -------------------------------------------------------------------------- */\n\nfunction serializeNode(node: WireframeNode, indent = \"\"): string {\n const name = NODE_TO_COMPONENT[node.el] ?? \"Box\";\n const attrs = Object.entries(node)\n .filter(([key]) => key !== \"children\" && key !== \"el\")\n .map(([key, value]) => prop(key, value))\n .join(\"\");\n if (!node.children?.length) return `${indent}<${name}${attrs} />`;\n const children = node.children\n .map((child) => serializeNode(child, `${indent} `))\n .join(\"\\n\");\n return `${indent}<${name}${attrs}>\\n${children}\\n${indent}</${name}>`;\n}\n\n/**\n * Serialize the wireframe data to its inner `<Screen>` MDX subtree. The registry\n * serializer wraps this between the `<WireframeBlock …>` open/close tags, so the\n * total output equals the legacy `serializeBlock` wireframe branch exactly.\n */\nfunction serializeScreen(data: WireframeData): string {\n const attrs = [\n prop(\"surface\", data.surface),\n prop(\"renderMode\", data.renderMode),\n prop(\"caption\", data.caption),\n prop(\"frame\", data.frame),\n prop(\"html\", data.html),\n prop(\"css\", data.css),\n prop(\"skeleton\", data.skeleton),\n ].join(\"\");\n const children = (data.screen ?? [])\n .map((node) => serializeNode(node, \" \"))\n .join(\"\\n\");\n if (!children) return `<Screen${attrs} />`;\n return `<Screen${attrs}>\\n${children}\\n</Screen>`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Parse (verbatim port of plan-mdx.ts parseScreen/parseWireframeNode) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Minimal MDX AST node shape used while walking the wireframe subtree. Declared\n * standalone (not an intersection with `MdxJsxNode`, whose `children` is\n * `unknown[]`) so recursive `children` stays narrowed to `WireframeMdxNode`.\n */\ntype WireframeMdxNode = {\n type: string;\n name?: string;\n attributes?: Array<{\n type: string;\n name?: string;\n value?: string | null | { type: string; value: string; data?: unknown };\n }>;\n children?: WireframeMdxNode[];\n};\n\nfunction elementName(node: WireframeMdxNode | undefined): string | undefined {\n return node?.type === \"mdxJsxFlowElement\" ||\n node?.type === \"mdxJsxTextElement\"\n ? node.name\n : undefined;\n}\n\nfunction findAttribute(node: WireframeMdxNode, name: string) {\n return node.attributes?.find(\n (attr) => attr.type === \"mdxJsxAttribute\" && attr.name === name,\n );\n}\n\nfunction stringAttr(node: WireframeMdxNode, name: string): string | undefined {\n const value = attributeValue(findAttribute(node, name));\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Resolve a required-when-present string attribute on a `<Screen>`. If the\n * attribute is absent we return undefined, but if it is present yet cannot be\n * resolved to a string (e.g. a number, an object, or an unevaluable expression)\n * we THROW so a malformed wireframe fails the import instead of silently\n * dropping the value and rendering an empty wireframe.\n */\nfunction requiredStringAttr(\n node: WireframeMdxNode,\n name: string,\n): string | undefined {\n const attr = findAttribute(node, name);\n if (!attr) return undefined;\n const value = attributeValue(attr);\n if (typeof value !== \"string\") {\n throw new Error(\n `Wireframe <Screen> attribute \"${name}\" must resolve to a string, got ${typeof value}. Use a quoted string or a static template literal.`,\n );\n }\n return value;\n}\n\nfunction boolAttr(node: WireframeMdxNode, name: string): boolean | undefined {\n const value = attributeValue(findAttribute(node, name));\n return typeof value === \"boolean\" ? value : undefined;\n}\n\nfunction parseWireframeNode(\n node: WireframeMdxNode,\n path = \"node\",\n): WireframeNode | null {\n const component = elementName(node);\n if (!component) return null;\n const el = COMPONENT_TO_NODE[component];\n if (!el) return null;\n const attrs = node.attributes ?? [];\n const parsed: WireframeNode = { el };\n for (const attr of attrs) {\n if (attr.type !== \"mdxJsxAttribute\") continue;\n const value = attributeValue(attr);\n if (value !== undefined)\n (parsed as Record<string, unknown>)[attr.name as string] = value;\n }\n parsed.el = el;\n parsed.id ??= createStableWireframeNodeId(el, path);\n const children = (node.children ?? [])\n .map((child, index) => parseWireframeNode(child, `${path}-${index}`))\n .filter(Boolean) as WireframeNode[];\n if (children.length > 0) parsed.children = children;\n return parsed;\n}\n\nfunction parseScreen(node: WireframeMdxNode, idContext: string): WireframeData {\n return {\n surface:\n (stringAttr(node, \"surface\") as WireframeData[\"surface\"]) ?? \"desktop\",\n renderMode: stringAttr(node, \"renderMode\") as WireframeData[\"renderMode\"],\n caption: stringAttr(node, \"caption\"),\n frame: stringAttr(node, \"frame\") as WireframeData[\"frame\"],\n html: requiredStringAttr(node, \"html\"),\n css: requiredStringAttr(node, \"css\"),\n skeleton: boolAttr(node, \"skeleton\"),\n screen: (node.children ?? [])\n .map((child, index) =>\n parseWireframeNode(child, `${idContext}-screen-${index}`),\n )\n .filter(Boolean) as WireframeNode[],\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* MDX config */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Registry MDX config for the wireframe block. `tag` matches the legacy\n * `WireframeBlock`. The block has no flat attributes (`toAttrs` → `{}`); all data\n * lives in the nested `<Screen>` subtree handled by `serializeChildren` /\n * `parseChildren`. The registry serializer wraps `serializeChildren` between the\n * `<WireframeBlock>` open/close, producing the exact legacy bytes. On parse, the\n * registry passes the already-extended `${idContext}-${blockId}` to\n * `parseChildren` — the same id base the legacy `parseScreen` receives — so node\n * ids are reproduced identically.\n */\nexport const wireframeMdx: BlockMdxConfig<WireframeData> = {\n tag: \"WireframeBlock\",\n toAttrs: () => ({}),\n fromAttrs: () => ({ surface: \"desktop\", screen: [] }),\n serializeChildren: (data) => serializeScreen(data),\n parseChildren: (childNodes, idContext) => {\n const nodes = childNodes as WireframeMdxNode[];\n const screen = nodes.find((child) => elementName(child) === \"Screen\");\n if (!screen) return { surface: \"desktop\", screen: [] };\n return parseScreen(screen, idContext);\n },\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wireframe.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AAkBrB,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"wireframe.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AAkBrB,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AA0b/B,kDAAkD;AAClD,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,OAAO,EACP,GAAG,EACH,cAAc,GACf,EAAE,cAAc,CAAC,aAAa,CAAC,+BAY/B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,cAAc,CAAC,aAAa,CAAC,+BAE3E;AAED,oFAAoF;AACpF,eAAO,MAAM,cAAc,gDAczB,CAAC"}
|
|
@@ -26,7 +26,7 @@ function isHtmlData(data) {
|
|
|
26
26
|
/* content yields a short frame and tall content grows. Pass `canvasSize` to */
|
|
27
27
|
/* opt a fixed-aspect canvas artboard back into a hard pixel height. */
|
|
28
28
|
/* -------------------------------------------------------------------------- */
|
|
29
|
-
function ArtboardFrame({ surface, compact, canvasSize, canvasWidth, skeleton, renderMode, roughOverlay = true, selector, caption, render, }) {
|
|
29
|
+
function ArtboardFrame({ surface, compact, canvasSize, canvasWidth, skeleton, renderMode, roughOverlay = true, showFrame = true, selector, caption, render, }) {
|
|
30
30
|
const ref = useRef(null);
|
|
31
31
|
const fitRef = useRef(null);
|
|
32
32
|
const isDark = useIsDark();
|
|
@@ -53,6 +53,9 @@ function ArtboardFrame({ surface, compact, canvasSize, canvasWidth, skeleton, re
|
|
|
53
53
|
const designMode = renderMode === "design";
|
|
54
54
|
const sketchy = !designMode && style === "sketchy" && !skeleton;
|
|
55
55
|
const roughEnabled = sketchy && roughOverlay;
|
|
56
|
+
const frameBorder = skeleton
|
|
57
|
+
? "var(--plan-placeholder-line, var(--plan-line, hsl(var(--border))))"
|
|
58
|
+
: "var(--plan-line, hsl(var(--border)))";
|
|
56
59
|
useEffect(() => {
|
|
57
60
|
const element = fitRef.current;
|
|
58
61
|
if (!element)
|
|
@@ -100,7 +103,7 @@ function ArtboardFrame({ surface, compact, canvasSize, canvasWidth, skeleton, re
|
|
|
100
103
|
maxWidth: maxFrameWidth,
|
|
101
104
|
...(reserveScaledHeight ? { height: reservedHeight } : {}),
|
|
102
105
|
marginInline: "auto",
|
|
103
|
-
}, children: [_jsxs("div", { ref: ref, className: "plan-kit-artboard relative", "data-rough-scope": "wireframe", style: {
|
|
106
|
+
}, children: [_jsxs("div", { ref: ref, className: "plan-kit-artboard relative", "data-rough-scope": "wireframe", "data-frame": showFrame ? "show" : "hide", style: {
|
|
104
107
|
width,
|
|
105
108
|
// Auto-height by default (content-driven, floored at `minHeight`);
|
|
106
109
|
// a fixed `canvasSize` locks the height for canvas artboards.
|
|
@@ -117,7 +120,10 @@ function ArtboardFrame({ surface, compact, canvasSize, canvasWidth, skeleton, re
|
|
|
117
120
|
...(fixedHeight != null
|
|
118
121
|
? { position: "absolute", inset: 0 }
|
|
119
122
|
: { minHeight }),
|
|
120
|
-
}, children: render({ theme, style }) }),
|
|
123
|
+
}, children: render({ theme, style }) }), !roughEnabled && showFrame && (_jsx("div", { className: "pointer-events-none absolute inset-0", style: {
|
|
124
|
+
borderRadius: preset.radius,
|
|
125
|
+
border: `1.5px solid ${frameBorder}`,
|
|
126
|
+
} })), _jsx(RoughOverlay, { scopeRef: ref, enabled: roughEnabled, drawFrame: showFrame, frameRadius: preset.radius, selector: selector })] }), !designMode && !skeleton && _jsx(WireframeStyleToggleButton, {})] }), caption && (_jsx("p", { className: "mt-2 text-center text-xs text-plan-muted", children: caption }))] }));
|
|
121
127
|
}
|
|
122
128
|
function WireframeStyleToggleButton() {
|
|
123
129
|
const style = useWireframeStyle();
|
|
@@ -133,7 +139,7 @@ function WireframeStyleToggleButton() {
|
|
|
133
139
|
/* -------------------------------------------------------------------------- */
|
|
134
140
|
/* HTML artboard — author HTML, themed + roughened by the renderer. */
|
|
135
141
|
/* -------------------------------------------------------------------------- */
|
|
136
|
-
function HtmlArtboard({ data, ctx: _ctx, compact, }) {
|
|
142
|
+
function HtmlArtboard({ data, ctx: _ctx, showFrame, compact, }) {
|
|
137
143
|
const renderMode = data.renderMode ?? "wireframe";
|
|
138
144
|
const designMode = renderMode === "design";
|
|
139
145
|
// Sanitize author HTML/CSS at the render point (defense-in-depth against stored
|
|
@@ -152,13 +158,13 @@ function HtmlArtboard({ data, ctx: _ctx, compact, }) {
|
|
|
152
158
|
? scopeDesignCss(safeCss, `[data-plan-design-scope="${scopeId}"]`)
|
|
153
159
|
: "";
|
|
154
160
|
}, [data.css, scopeId]);
|
|
155
|
-
return (_jsx(ArtboardFrame, { surface: data.surface, compact: compact, skeleton: data.skeleton, renderMode: renderMode, selector: HTML_ROUGH_SELECTOR, caption: data.caption, render: ({ theme, style }) => (_jsxs("div", { className: "plan-html-frame", "data-theme": theme, "data-style": style, "data-render-mode": renderMode, "data-plan-design-scope": scopeId, "data-skeleton": data.skeleton ? "true" : undefined, children: [scopedCss && _jsx("style", { children: scopedCss }), _jsx("div", { className: "plan-html-frame-content", dangerouslySetInnerHTML: { __html: safeHtml } })] })) }));
|
|
161
|
+
return (_jsx(ArtboardFrame, { surface: data.surface, compact: compact, skeleton: data.skeleton, renderMode: renderMode, showFrame: showFrame, selector: HTML_ROUGH_SELECTOR, caption: data.caption, render: ({ theme, style }) => (_jsxs("div", { className: "plan-html-frame", "data-theme": theme, "data-style": style, "data-frame": showFrame ? "show" : "hide", "data-render-mode": renderMode, "data-plan-design-scope": scopeId, "data-skeleton": data.skeleton ? "true" : undefined, children: [scopedCss && _jsx("style", { children: scopedCss }), _jsx("div", { className: "plan-html-frame-content", dangerouslySetInnerHTML: { __html: safeHtml } })] })) }));
|
|
156
162
|
}
|
|
157
163
|
/* -------------------------------------------------------------------------- */
|
|
158
164
|
/* Kit artboard — declarative kit tree. */
|
|
159
165
|
/* -------------------------------------------------------------------------- */
|
|
160
|
-
function KitArtboard({ data, compact, }) {
|
|
161
|
-
return (_jsx(ArtboardFrame, { surface: data.surface, compact: compact, skeleton: data.skeleton, selector: "[data-rough]", caption: data.caption, render: ({ theme, style }) => (_jsx(KitConfigContext.Provider, { value: { skeleton: data.skeleton, theme, style }, children: renderKitScreen(data.screen ?? []) })) }));
|
|
166
|
+
function KitArtboard({ data, showFrame, compact, }) {
|
|
167
|
+
return (_jsx(ArtboardFrame, { surface: data.surface, compact: compact, skeleton: data.skeleton, showFrame: showFrame, selector: "[data-rough]", caption: data.caption, render: ({ theme, style }) => (_jsx(KitConfigContext.Provider, { value: { skeleton: data.skeleton, theme, style }, children: renderKitScreen(data.screen ?? []) })) }));
|
|
162
168
|
}
|
|
163
169
|
function renderKitScreen(nodes) {
|
|
164
170
|
if (nodes.length === 1 && nodes[0]?.el === "screen") {
|
|
@@ -174,10 +180,15 @@ function renderKitScreen(nodes) {
|
|
|
174
180
|
* the kit tree.
|
|
175
181
|
*/
|
|
176
182
|
function WireframeSurfaceView({ data, ctx, compact, }) {
|
|
183
|
+
const showFrame = resolveVisualFrame(data.frame, ctx);
|
|
177
184
|
if (isHtmlData(data)) {
|
|
178
|
-
return _jsx(HtmlArtboard, { data: data, ctx: ctx, compact: compact });
|
|
185
|
+
return (_jsx(HtmlArtboard, { data: data, ctx: ctx, showFrame: showFrame, compact: compact }));
|
|
179
186
|
}
|
|
180
|
-
return _jsx(KitArtboard, { data: data, compact: compact });
|
|
187
|
+
return _jsx(KitArtboard, { data: data, showFrame: showFrame, compact: compact });
|
|
188
|
+
}
|
|
189
|
+
function resolveVisualFrame(frame, ctx) {
|
|
190
|
+
const resolved = frame && frame !== "auto" ? frame : (ctx.visualFrame ?? "show");
|
|
191
|
+
return resolved !== "hide";
|
|
181
192
|
}
|
|
182
193
|
/* -------------------------------------------------------------------------- */
|
|
183
194
|
/* Block Read / Edit */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wireframe.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconPencil } from \"@tabler/icons-react\";\nimport {\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { ltrCodeBlockProps } from \"../code-block-direction.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n} from \"../types.js\";\nimport { useBlockCopy } from \"./block-copy.js\";\nimport {\n sanitizeWireframeCss,\n sanitizeWireframeHtml,\n scopeDesignCss,\n} from \"./sanitize-html.js\";\nimport { renderWireframeIconHtml } from \"./wireframe-icons.js\";\nimport {\n HTML_ROUGH_SELECTOR,\n KitConfigContext,\n RoughOverlay,\n Screen,\n renderNodes,\n toggleWireframeStyle,\n useIsDark,\n useWireframeStyle,\n} from \"./wireframe-kit.js\";\nimport {\n wireframeSchema,\n wireframeMdx,\n type WireframeData,\n type WireframeSurface,\n} from \"./wireframe.config.js\";\n\n/**\n * Shared `wireframe` block — a hand-drawn low-fi mockup of one screen, rendered\n * from either a declarative kit tree (`data.screen`) or a self-contained HTML\n * mockup (`data.html`), inside a surface-locked frame (desktop/mobile/popover/\n * panel/browser) with a rough.js sketch overlay. Lives in core so any app can\n * register it (it originated in the plan template).\n *\n * DECOUPLING from the plan original:\n * - Theme: `useIsDark()` reads `document.documentElement.classList` instead of\n * `next-themes` (the MermaidBlock precedent), so core stays dependency-light.\n * - HTML sanitize: the HTML path runs `data.html`/`data.css` through the\n * app-injected `ctx.sanitizeHtml`. If no sanitizer is wired the HTML path is\n * skipped (kit tree or an empty frame renders) — core never injects unsanitized\n * author HTML.\n * - The plan-only prototype runtime, design-element selection, and legacy region\n * fallback are intentionally NOT ported; those are plan-canvas features, not\n * part of the document-block render. The kit element vocabulary, the `--wf-*`\n * token contract, and the `.plan-wf` / `.wf-*` / `[data-rough]` classes the\n * overlay measures are preserved exactly.\n *\n * The section carries the app-neutral `an-block` class plus the legacy\n * `plan-block` class so plan renders byte-identically while any other app gets\n * the theme-token treatment from core's `blocks.css`.\n *\n * The wireframe is canvas / agent-patch edited (node-addressable content patches\n * applied server-side), NOT schema-form edited in the browser — so `Edit` reuses\n * the same static render as `Read`, mirroring the plan `WireframeEditor`.\n */\n\ntype SurfacePreset = {\n width: number;\n /**\n * Floor height for the surface. The frame is AUTO-HEIGHT (content-driven): it\n * grows past this when content is tall and shrinks toward its content height\n * when content is short, but never collapses below this floor — so an empty or\n * near-empty frame still reads as that surface instead of a thin sliver. This\n * is a `min-height`, not a fixed `height`: it is the lower bound the old fixed\n * preset height used to also be the UPPER bound, which is what left a big empty\n * vertical band below short content (e.g. a header + one dropdown padded to a\n * tall fixed aspect).\n */\n minHeight: number;\n radius: number;\n};\n\nconst SURFACE_PRESETS: Record<WireframeSurface, SurfacePreset> = {\n // mobile keeps a tall floor: a phone frame reads as a phone even when short.\n mobile: { width: 300, minHeight: 360, radius: 30 },\n desktop: { width: 840, minHeight: 200, radius: 14 },\n browser: { width: 900, minHeight: 200, radius: 14 },\n popover: { width: 360, minHeight: 120, radius: 16 },\n panel: { width: 420, minHeight: 200, radius: 16 },\n};\n\nfunction isHtmlData(data: WireframeData): boolean {\n return typeof data.html === \"string\" && data.html.trim().length > 0;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Shared frame shell: surface-locked WIDTH + auto (content-driven) height + */\n/* theme + rough overlay. The frame keeps each surface's footprint and chrome */\n/* but fits its content height instead of padding to a fixed aspect, so short */\n/* content yields a short frame and tall content grows. Pass `canvasSize` to */\n/* opt a fixed-aspect canvas artboard back into a hard pixel height. */\n/* -------------------------------------------------------------------------- */\n\nfunction ArtboardFrame({\n surface,\n compact,\n canvasSize,\n canvasWidth,\n skeleton,\n renderMode,\n roughOverlay = true,\n selector,\n caption,\n render,\n}: {\n surface: WireframeSurface;\n compact?: boolean;\n /**\n * Force a FIXED pixel height instead of the auto-height (content-driven)\n * default. Reserved for fixed-aspect canvas artboards (pan/zoom). Document-flow\n * wireframes — what recaps render — leave this unset so the frame fits content.\n */\n canvasSize?: number;\n canvasWidth?: number;\n skeleton?: boolean;\n renderMode?: \"wireframe\" | \"design\";\n roughOverlay?: boolean;\n selector: string;\n caption?: string;\n render: (ctx: {\n theme: \"light\" | \"dark\";\n style: \"sketchy\" | \"clean\";\n }) => ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const fitRef = useRef<HTMLDivElement>(null);\n const isDark = useIsDark();\n const theme: \"light\" | \"dark\" = isDark ? \"dark\" : \"light\";\n const style = useWireframeStyle();\n const preset = SURFACE_PRESETS[surface] ?? SURFACE_PRESETS.desktop;\n const width = canvasWidth ?? preset.width;\n // AUTO-HEIGHT: with no explicit `canvasSize` the artboard height is driven by\n // its content (`height: auto`), floored at the surface's `minHeight` so a short\n // screen produces a short frame and a tall screen grows — instead of every\n // surface being padded to a fixed preset height that left a big empty band\n // below short content. A `canvasSize` (fixed-aspect canvas artboard) overrides\n // this with a hard pixel height.\n const fixedHeight = canvasSize;\n const minHeight = fixedHeight ?? preset.minHeight;\n const baseScale = compact ? Math.min(1, 320 / preset.width) : 1;\n const maxFrameWidth = compact ? preset.width * baseScale : width;\n const [fitScale, setFitScale] = useState(baseScale);\n // The scaled artboard is `transform: scale()`-ed, which does not change its\n // layout box, so the wrapper that reserves vertical space must track the\n // artboard's ACTUAL rendered height. With a fixed height that's known up front;\n // with auto-height we measure it.\n const [measuredHeight, setMeasuredHeight] = useState<number | null>(\n fixedHeight ?? null,\n );\n const designMode = renderMode === \"design\";\n const sketchy = !designMode && style === \"sketchy\" && !skeleton;\n const roughEnabled = sketchy && roughOverlay;\n\n useEffect(() => {\n const element = fitRef.current;\n if (!element) return;\n const measure = () => {\n const availableWidth = element.clientWidth;\n const nextScale =\n availableWidth > 0\n ? Math.min(baseScale, availableWidth / width)\n : baseScale;\n setFitScale((current) =>\n Math.abs(current - nextScale) < 0.001 ? current : nextScale,\n );\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [baseScale, width]);\n\n // Track the auto-height artboard's rendered height so the (un-transformed)\n // wrapper reserves exactly the scaled space the frame occupies. Skipped when a\n // fixed height is supplied — there's nothing to measure.\n useEffect(() => {\n if (fixedHeight != null) return;\n const element = ref.current;\n if (!element) return;\n const measure = () => {\n const next = element.offsetHeight;\n setMeasuredHeight((current) =>\n current != null && Math.abs(current - next) < 0.5 ? current : next,\n );\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [fixedHeight]);\n\n // Height the wrapper reserves: the measured (or fixed) artboard height scaled\n // by the fit factor. Falls back to the surface floor before the first measure\n // so SSR / first paint reserves a sensible box rather than collapsing.\n const reservedHeight = (measuredHeight ?? minHeight) * fitScale;\n const reserveScaledHeight = fixedHeight != null || fitScale !== 1;\n\n return (\n <div\n ref={fitRef}\n className=\"plan-kit-wireframe\"\n style={{\n width: \"100%\",\n maxWidth: maxFrameWidth,\n }}\n >\n <div\n className=\"group/wireframe-artboard relative\"\n style={{\n width: \"100%\",\n maxWidth: maxFrameWidth,\n ...(reserveScaledHeight ? { height: reservedHeight } : {}),\n marginInline: \"auto\",\n }}\n >\n <div\n ref={ref}\n className=\"plan-kit-artboard relative\"\n data-rough-scope=\"wireframe\"\n style={{\n width,\n // Auto-height by default (content-driven, floored at `minHeight`);\n // a fixed `canvasSize` locks the height for canvas artboards.\n ...(fixedHeight != null ? { height: fixedHeight } : { minHeight }),\n borderRadius: preset.radius,\n ...(fitScale !== 1\n ? {\n transform: `scale(${fitScale})`,\n transformOrigin: \"top left\",\n }\n : {}),\n }}\n >\n {/* Content drives the artboard height in flow when auto-height; for a\n fixed height it's pinned to the box. Rounded corners clip overflow\n either way. */}\n <div\n className=\"overflow-hidden\"\n style={{\n borderRadius: preset.radius,\n ...(fixedHeight != null\n ? { position: \"absolute\", inset: 0 }\n : { minHeight }),\n }}\n >\n {render({ theme, style })}\n </div>\n <RoughOverlay\n scopeRef={ref}\n enabled={roughEnabled}\n drawFrame={false}\n frameRadius={preset.radius}\n selector={selector}\n />\n </div>\n {!designMode && !skeleton && <WireframeStyleToggleButton />}\n </div>\n {caption && (\n <p className=\"mt-2 text-center text-xs text-plan-muted\">{caption}</p>\n )}\n </div>\n );\n}\n\nfunction WireframeStyleToggleButton() {\n const style = useWireframeStyle();\n const copy = useBlockCopy();\n const nextStyle = style === \"sketchy\" ? \"clean\" : \"sketchy\";\n const label = nextStyle === \"clean\" ? copy.clean : copy.sketchy;\n const description = copy.switchVisualStyle.replace(\n \"{{style}}\",\n label.toLocaleLowerCase(),\n );\n\n return (\n <button\n type=\"button\"\n data-plan-interactive\n data-rough=\"none\"\n data-wireframe-style-toggle\n aria-label={description}\n title={description}\n onClick={(event) => {\n event.stopPropagation();\n toggleWireframeStyle();\n }}\n className=\"absolute right-2 top-2 z-30 inline-flex h-7 items-center gap-1 rounded-md border border-border/60 bg-background px-2 text-xs font-medium text-muted-foreground opacity-0 shadow-sm transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/wireframe-artboard:opacity-100\"\n >\n <IconPencil className=\"size-3.5\" aria-hidden=\"true\" />\n <span>{label}</span>\n </button>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* HTML artboard — author HTML, themed + roughened by the renderer. */\n/* -------------------------------------------------------------------------- */\n\nfunction HtmlArtboard({\n data,\n ctx: _ctx,\n compact,\n}: {\n data: WireframeData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const renderMode = data.renderMode ?? \"wireframe\";\n const designMode = renderMode === \"design\";\n // Sanitize author HTML/CSS at the render point (defense-in-depth against stored\n // XSS). Self-contained in core via the shared block sanitizer (DOM-based in the\n // browser, regex fallback on the server) so the HTML mockup path renders in any\n // app without the host wiring a sanitizer hook.\n const safeHtml = useMemo(\n () =>\n renderWireframeIconHtml(\n sanitizeWireframeHtml(data.html, {\n preserveThemeClasses: designMode,\n }),\n ),\n [data.html, designMode],\n );\n const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n const scopedCss = useMemo(() => {\n const safeCss = sanitizeWireframeCss(data.css);\n // Scope every author selector under this instance's artboard so global\n // selectors (body, *, .app-shell, :root) can't restyle/hide the host app.\n return safeCss\n ? scopeDesignCss(safeCss, `[data-plan-design-scope=\"${scopeId}\"]`)\n : \"\";\n }, [data.css, scopeId]);\n\n return (\n <ArtboardFrame\n surface={data.surface}\n compact={compact}\n skeleton={data.skeleton}\n renderMode={renderMode}\n selector={HTML_ROUGH_SELECTOR}\n caption={data.caption}\n render={({ theme, style }) => (\n <div\n className=\"plan-html-frame\"\n data-theme={theme}\n data-style={style}\n data-render-mode={renderMode}\n data-plan-design-scope={scopeId}\n data-skeleton={data.skeleton ? \"true\" : undefined}\n >\n {scopedCss && <style>{scopedCss}</style>}\n <div\n className=\"plan-html-frame-content\"\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n )}\n />\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Kit artboard — declarative kit tree. */\n/* -------------------------------------------------------------------------- */\n\nfunction KitArtboard({\n data,\n compact,\n}: {\n data: WireframeData;\n compact?: boolean;\n}) {\n return (\n <ArtboardFrame\n surface={data.surface}\n compact={compact}\n skeleton={data.skeleton}\n selector=\"[data-rough]\"\n caption={data.caption}\n render={({ theme, style }) => (\n <KitConfigContext.Provider\n value={{ skeleton: data.skeleton, theme, style }}\n >\n {renderKitScreen(data.screen ?? [])}\n </KitConfigContext.Provider>\n )}\n />\n );\n}\n\nfunction renderKitScreen(\n nodes: NonNullable<WireframeData[\"screen\"]>,\n): ReactNode {\n if (nodes.length === 1 && nodes[0]?.el === \"screen\") {\n return renderNodes(nodes);\n }\n // `minHeight` (not `height`) so the screen fills the auto-height artboard floor\n // but grows past it when content is tall, instead of locking to a fixed box.\n return (\n <Screen pad=\"calc(var(--pad) * 1.35)\" style={{ minHeight: \"100%\" }}>\n {renderNodes(nodes)}\n </Screen>\n );\n}\n\n/**\n * The bare wireframe surface (no block section / title). Routes to the HTML\n * mockup when `data.html` is present and a sanitizer is wired; otherwise renders\n * the kit tree.\n */\nfunction WireframeSurfaceView({\n data,\n ctx,\n compact,\n}: {\n data: WireframeData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n if (isHtmlData(data)) {\n return <HtmlArtboard data={data} ctx={ctx} compact={compact} />;\n }\n return <KitArtboard data={data} compact={compact} />;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Block Read / Edit */\n/* -------------------------------------------------------------------------- */\n\n/** Read-only renderer for a `wireframe` block. */\nexport function WireframeBlock({\n data,\n blockId,\n title,\n summary,\n ctx,\n compactVisuals,\n}: BlockReadProps<WireframeData>) {\n return (\n <section\n {...ltrCodeBlockProps}\n className=\"an-block plan-block an-wireframe\"\n data-block-id={blockId}\n >\n {title && <div className=\"an-block-label plan-block-label\">{title}</div>}\n <WireframeSurfaceView data={data} ctx={ctx} compact={compactVisuals} />\n {summary && <p className=\"mt-5 text-plan-muted\">{summary}</p>}\n </section>\n );\n}\n\n/**\n * Editor for the `wireframe` block. The wireframe is canvas / agent-patch edited\n * (it never calls `onChange`), so edit mode reuses the read surface — mirroring\n * the plan `WireframeEditor`. The host document editor already wraps the registry\n * edit path in a titled section, so this renders only the surface to avoid\n * double-nesting.\n */\nexport function WireframeEditor({ data, ctx }: BlockEditProps<WireframeData>) {\n return <WireframeSurfaceView data={data} ctx={ctx} />;\n}\n\n/** Full client spec for the shared `wireframe` block (schema + MDX + Read/Edit). */\nexport const wireframeBlock = defineBlock<WireframeData>({\n type: \"wireframe\",\n schema: wireframeSchema,\n mdx: wireframeMdx,\n Read: WireframeBlock,\n Edit: WireframeEditor,\n placement: [\"block\"],\n editSurface: \"inline\",\n label: \"Wireframe\",\n description:\n \"A sketch wireframe of one screen built from kit primitives (or an HTML mockup), rendered in a chosen surface frame (desktop/mobile/popover/panel/browser).\",\n // `surface` is the only required field; `screen` defaults to []. Start on the\n // desktop surface with an empty screen so the canvas/agent can fill it in.\n empty: () => ({ surface: \"desktop\", screen: [] }),\n});\n"]}
|
|
1
|
+
{"version":3,"file":"wireframe.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/wireframe.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconPencil } from \"@tabler/icons-react\";\nimport {\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport { ltrCodeBlockProps } from \"../code-block-direction.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n} from \"../types.js\";\nimport { useBlockCopy } from \"./block-copy.js\";\nimport {\n sanitizeWireframeCss,\n sanitizeWireframeHtml,\n scopeDesignCss,\n} from \"./sanitize-html.js\";\nimport { renderWireframeIconHtml } from \"./wireframe-icons.js\";\nimport {\n HTML_ROUGH_SELECTOR,\n KitConfigContext,\n RoughOverlay,\n Screen,\n renderNodes,\n toggleWireframeStyle,\n useIsDark,\n useWireframeStyle,\n} from \"./wireframe-kit.js\";\nimport {\n wireframeSchema,\n wireframeMdx,\n type WireframeData,\n type WireframeSurface,\n} from \"./wireframe.config.js\";\n\n/**\n * Shared `wireframe` block — a hand-drawn low-fi mockup of one screen, rendered\n * from either a declarative kit tree (`data.screen`) or a self-contained HTML\n * mockup (`data.html`), inside a surface-locked frame (desktop/mobile/popover/\n * panel/browser) with a rough.js sketch overlay. Lives in core so any app can\n * register it (it originated in the plan template).\n *\n * DECOUPLING from the plan original:\n * - Theme: `useIsDark()` reads `document.documentElement.classList` instead of\n * `next-themes` (the MermaidBlock precedent), so core stays dependency-light.\n * - HTML sanitize: the HTML path runs `data.html`/`data.css` through the\n * app-injected `ctx.sanitizeHtml`. If no sanitizer is wired the HTML path is\n * skipped (kit tree or an empty frame renders) — core never injects unsanitized\n * author HTML.\n * - The plan-only prototype runtime, design-element selection, and legacy region\n * fallback are intentionally NOT ported; those are plan-canvas features, not\n * part of the document-block render. The kit element vocabulary, the `--wf-*`\n * token contract, and the `.plan-wf` / `.wf-*` / `[data-rough]` classes the\n * overlay measures are preserved exactly.\n *\n * The section carries the app-neutral `an-block` class plus the legacy\n * `plan-block` class so plan renders byte-identically while any other app gets\n * the theme-token treatment from core's `blocks.css`.\n *\n * The wireframe is canvas / agent-patch edited (node-addressable content patches\n * applied server-side), NOT schema-form edited in the browser — so `Edit` reuses\n * the same static render as `Read`, mirroring the plan `WireframeEditor`.\n */\n\ntype SurfacePreset = {\n width: number;\n /**\n * Floor height for the surface. The frame is AUTO-HEIGHT (content-driven): it\n * grows past this when content is tall and shrinks toward its content height\n * when content is short, but never collapses below this floor — so an empty or\n * near-empty frame still reads as that surface instead of a thin sliver. This\n * is a `min-height`, not a fixed `height`: it is the lower bound the old fixed\n * preset height used to also be the UPPER bound, which is what left a big empty\n * vertical band below short content (e.g. a header + one dropdown padded to a\n * tall fixed aspect).\n */\n minHeight: number;\n radius: number;\n};\n\nconst SURFACE_PRESETS: Record<WireframeSurface, SurfacePreset> = {\n // mobile keeps a tall floor: a phone frame reads as a phone even when short.\n mobile: { width: 300, minHeight: 360, radius: 30 },\n desktop: { width: 840, minHeight: 200, radius: 14 },\n browser: { width: 900, minHeight: 200, radius: 14 },\n popover: { width: 360, minHeight: 120, radius: 16 },\n panel: { width: 420, minHeight: 200, radius: 16 },\n};\n\nfunction isHtmlData(data: WireframeData): boolean {\n return typeof data.html === \"string\" && data.html.trim().length > 0;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Shared frame shell: surface-locked WIDTH + auto (content-driven) height + */\n/* theme + rough overlay. The frame keeps each surface's footprint and chrome */\n/* but fits its content height instead of padding to a fixed aspect, so short */\n/* content yields a short frame and tall content grows. Pass `canvasSize` to */\n/* opt a fixed-aspect canvas artboard back into a hard pixel height. */\n/* -------------------------------------------------------------------------- */\n\nfunction ArtboardFrame({\n surface,\n compact,\n canvasSize,\n canvasWidth,\n skeleton,\n renderMode,\n roughOverlay = true,\n showFrame = true,\n selector,\n caption,\n render,\n}: {\n surface: WireframeSurface;\n compact?: boolean;\n /**\n * Force a FIXED pixel height instead of the auto-height (content-driven)\n * default. Reserved for fixed-aspect canvas artboards (pan/zoom). Document-flow\n * wireframes — what recaps render — leave this unset so the frame fits content.\n */\n canvasSize?: number;\n canvasWidth?: number;\n skeleton?: boolean;\n renderMode?: \"wireframe\" | \"design\";\n roughOverlay?: boolean;\n showFrame?: boolean;\n selector: string;\n caption?: string;\n render: (ctx: {\n theme: \"light\" | \"dark\";\n style: \"sketchy\" | \"clean\";\n }) => ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const fitRef = useRef<HTMLDivElement>(null);\n const isDark = useIsDark();\n const theme: \"light\" | \"dark\" = isDark ? \"dark\" : \"light\";\n const style = useWireframeStyle();\n const preset = SURFACE_PRESETS[surface] ?? SURFACE_PRESETS.desktop;\n const width = canvasWidth ?? preset.width;\n // AUTO-HEIGHT: with no explicit `canvasSize` the artboard height is driven by\n // its content (`height: auto`), floored at the surface's `minHeight` so a short\n // screen produces a short frame and a tall screen grows — instead of every\n // surface being padded to a fixed preset height that left a big empty band\n // below short content. A `canvasSize` (fixed-aspect canvas artboard) overrides\n // this with a hard pixel height.\n const fixedHeight = canvasSize;\n const minHeight = fixedHeight ?? preset.minHeight;\n const baseScale = compact ? Math.min(1, 320 / preset.width) : 1;\n const maxFrameWidth = compact ? preset.width * baseScale : width;\n const [fitScale, setFitScale] = useState(baseScale);\n // The scaled artboard is `transform: scale()`-ed, which does not change its\n // layout box, so the wrapper that reserves vertical space must track the\n // artboard's ACTUAL rendered height. With a fixed height that's known up front;\n // with auto-height we measure it.\n const [measuredHeight, setMeasuredHeight] = useState<number | null>(\n fixedHeight ?? null,\n );\n const designMode = renderMode === \"design\";\n const sketchy = !designMode && style === \"sketchy\" && !skeleton;\n const roughEnabled = sketchy && roughOverlay;\n const frameBorder = skeleton\n ? \"var(--plan-placeholder-line, var(--plan-line, hsl(var(--border))))\"\n : \"var(--plan-line, hsl(var(--border)))\";\n\n useEffect(() => {\n const element = fitRef.current;\n if (!element) return;\n const measure = () => {\n const availableWidth = element.clientWidth;\n const nextScale =\n availableWidth > 0\n ? Math.min(baseScale, availableWidth / width)\n : baseScale;\n setFitScale((current) =>\n Math.abs(current - nextScale) < 0.001 ? current : nextScale,\n );\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [baseScale, width]);\n\n // Track the auto-height artboard's rendered height so the (un-transformed)\n // wrapper reserves exactly the scaled space the frame occupies. Skipped when a\n // fixed height is supplied — there's nothing to measure.\n useEffect(() => {\n if (fixedHeight != null) return;\n const element = ref.current;\n if (!element) return;\n const measure = () => {\n const next = element.offsetHeight;\n setMeasuredHeight((current) =>\n current != null && Math.abs(current - next) < 0.5 ? current : next,\n );\n };\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(element);\n return () => observer.disconnect();\n }, [fixedHeight]);\n\n // Height the wrapper reserves: the measured (or fixed) artboard height scaled\n // by the fit factor. Falls back to the surface floor before the first measure\n // so SSR / first paint reserves a sensible box rather than collapsing.\n const reservedHeight = (measuredHeight ?? minHeight) * fitScale;\n const reserveScaledHeight = fixedHeight != null || fitScale !== 1;\n\n return (\n <div\n ref={fitRef}\n className=\"plan-kit-wireframe\"\n style={{\n width: \"100%\",\n maxWidth: maxFrameWidth,\n }}\n >\n <div\n className=\"group/wireframe-artboard relative\"\n style={{\n width: \"100%\",\n maxWidth: maxFrameWidth,\n ...(reserveScaledHeight ? { height: reservedHeight } : {}),\n marginInline: \"auto\",\n }}\n >\n <div\n ref={ref}\n className=\"plan-kit-artboard relative\"\n data-rough-scope=\"wireframe\"\n data-frame={showFrame ? \"show\" : \"hide\"}\n style={{\n width,\n // Auto-height by default (content-driven, floored at `minHeight`);\n // a fixed `canvasSize` locks the height for canvas artboards.\n ...(fixedHeight != null ? { height: fixedHeight } : { minHeight }),\n borderRadius: preset.radius,\n ...(fitScale !== 1\n ? {\n transform: `scale(${fitScale})`,\n transformOrigin: \"top left\",\n }\n : {}),\n }}\n >\n {/* Content drives the artboard height in flow when auto-height; for a\n fixed height it's pinned to the box. Rounded corners clip overflow\n either way. */}\n <div\n className=\"overflow-hidden\"\n style={{\n borderRadius: preset.radius,\n ...(fixedHeight != null\n ? { position: \"absolute\", inset: 0 }\n : { minHeight }),\n }}\n >\n {render({ theme, style })}\n </div>\n {!roughEnabled && showFrame && (\n <div\n className=\"pointer-events-none absolute inset-0\"\n style={{\n borderRadius: preset.radius,\n border: `1.5px solid ${frameBorder}`,\n }}\n />\n )}\n <RoughOverlay\n scopeRef={ref}\n enabled={roughEnabled}\n drawFrame={showFrame}\n frameRadius={preset.radius}\n selector={selector}\n />\n </div>\n {!designMode && !skeleton && <WireframeStyleToggleButton />}\n </div>\n {caption && (\n <p className=\"mt-2 text-center text-xs text-plan-muted\">{caption}</p>\n )}\n </div>\n );\n}\n\nfunction WireframeStyleToggleButton() {\n const style = useWireframeStyle();\n const copy = useBlockCopy();\n const nextStyle = style === \"sketchy\" ? \"clean\" : \"sketchy\";\n const label = nextStyle === \"clean\" ? copy.clean : copy.sketchy;\n const description = copy.switchVisualStyle.replace(\n \"{{style}}\",\n label.toLocaleLowerCase(),\n );\n\n return (\n <button\n type=\"button\"\n data-plan-interactive\n data-rough=\"none\"\n data-wireframe-style-toggle\n aria-label={description}\n title={description}\n onClick={(event) => {\n event.stopPropagation();\n toggleWireframeStyle();\n }}\n className=\"absolute right-2 top-2 z-30 inline-flex h-7 items-center gap-1 rounded-md border border-border/60 bg-background px-2 text-xs font-medium text-muted-foreground opacity-0 shadow-sm transition-[color,opacity] hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring group-hover/wireframe-artboard:opacity-100\"\n >\n <IconPencil className=\"size-3.5\" aria-hidden=\"true\" />\n <span>{label}</span>\n </button>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* HTML artboard — author HTML, themed + roughened by the renderer. */\n/* -------------------------------------------------------------------------- */\n\nfunction HtmlArtboard({\n data,\n ctx: _ctx,\n showFrame,\n compact,\n}: {\n data: WireframeData;\n ctx: BlockRenderContext;\n showFrame: boolean;\n compact?: boolean;\n}) {\n const renderMode = data.renderMode ?? \"wireframe\";\n const designMode = renderMode === \"design\";\n // Sanitize author HTML/CSS at the render point (defense-in-depth against stored\n // XSS). Self-contained in core via the shared block sanitizer (DOM-based in the\n // browser, regex fallback on the server) so the HTML mockup path renders in any\n // app without the host wiring a sanitizer hook.\n const safeHtml = useMemo(\n () =>\n renderWireframeIconHtml(\n sanitizeWireframeHtml(data.html, {\n preserveThemeClasses: designMode,\n }),\n ),\n [data.html, designMode],\n );\n const scopeId = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n const scopedCss = useMemo(() => {\n const safeCss = sanitizeWireframeCss(data.css);\n // Scope every author selector under this instance's artboard so global\n // selectors (body, *, .app-shell, :root) can't restyle/hide the host app.\n return safeCss\n ? scopeDesignCss(safeCss, `[data-plan-design-scope=\"${scopeId}\"]`)\n : \"\";\n }, [data.css, scopeId]);\n\n return (\n <ArtboardFrame\n surface={data.surface}\n compact={compact}\n skeleton={data.skeleton}\n renderMode={renderMode}\n showFrame={showFrame}\n selector={HTML_ROUGH_SELECTOR}\n caption={data.caption}\n render={({ theme, style }) => (\n <div\n className=\"plan-html-frame\"\n data-theme={theme}\n data-style={style}\n data-frame={showFrame ? \"show\" : \"hide\"}\n data-render-mode={renderMode}\n data-plan-design-scope={scopeId}\n data-skeleton={data.skeleton ? \"true\" : undefined}\n >\n {scopedCss && <style>{scopedCss}</style>}\n <div\n className=\"plan-html-frame-content\"\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n )}\n />\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* Kit artboard — declarative kit tree. */\n/* -------------------------------------------------------------------------- */\n\nfunction KitArtboard({\n data,\n showFrame,\n compact,\n}: {\n data: WireframeData;\n showFrame: boolean;\n compact?: boolean;\n}) {\n return (\n <ArtboardFrame\n surface={data.surface}\n compact={compact}\n skeleton={data.skeleton}\n showFrame={showFrame}\n selector=\"[data-rough]\"\n caption={data.caption}\n render={({ theme, style }) => (\n <KitConfigContext.Provider\n value={{ skeleton: data.skeleton, theme, style }}\n >\n {renderKitScreen(data.screen ?? [])}\n </KitConfigContext.Provider>\n )}\n />\n );\n}\n\nfunction renderKitScreen(\n nodes: NonNullable<WireframeData[\"screen\"]>,\n): ReactNode {\n if (nodes.length === 1 && nodes[0]?.el === \"screen\") {\n return renderNodes(nodes);\n }\n // `minHeight` (not `height`) so the screen fills the auto-height artboard floor\n // but grows past it when content is tall, instead of locking to a fixed box.\n return (\n <Screen pad=\"calc(var(--pad) * 1.35)\" style={{ minHeight: \"100%\" }}>\n {renderNodes(nodes)}\n </Screen>\n );\n}\n\n/**\n * The bare wireframe surface (no block section / title). Routes to the HTML\n * mockup when `data.html` is present and a sanitizer is wired; otherwise renders\n * the kit tree.\n */\nfunction WireframeSurfaceView({\n data,\n ctx,\n compact,\n}: {\n data: WireframeData;\n ctx: BlockRenderContext;\n compact?: boolean;\n}) {\n const showFrame = resolveVisualFrame(data.frame, ctx);\n if (isHtmlData(data)) {\n return (\n <HtmlArtboard\n data={data}\n ctx={ctx}\n showFrame={showFrame}\n compact={compact}\n />\n );\n }\n return <KitArtboard data={data} showFrame={showFrame} compact={compact} />;\n}\n\nfunction resolveVisualFrame(\n frame: WireframeData[\"frame\"],\n ctx: BlockRenderContext,\n): boolean {\n const resolved =\n frame && frame !== \"auto\" ? frame : (ctx.visualFrame ?? \"show\");\n return resolved !== \"hide\";\n}\n\n/* -------------------------------------------------------------------------- */\n/* Block Read / Edit */\n/* -------------------------------------------------------------------------- */\n\n/** Read-only renderer for a `wireframe` block. */\nexport function WireframeBlock({\n data,\n blockId,\n title,\n summary,\n ctx,\n compactVisuals,\n}: BlockReadProps<WireframeData>) {\n return (\n <section\n {...ltrCodeBlockProps}\n className=\"an-block plan-block an-wireframe\"\n data-block-id={blockId}\n >\n {title && <div className=\"an-block-label plan-block-label\">{title}</div>}\n <WireframeSurfaceView data={data} ctx={ctx} compact={compactVisuals} />\n {summary && <p className=\"mt-5 text-plan-muted\">{summary}</p>}\n </section>\n );\n}\n\n/**\n * Editor for the `wireframe` block. The wireframe is canvas / agent-patch edited\n * (it never calls `onChange`), so edit mode reuses the read surface — mirroring\n * the plan `WireframeEditor`. The host document editor already wraps the registry\n * edit path in a titled section, so this renders only the surface to avoid\n * double-nesting.\n */\nexport function WireframeEditor({ data, ctx }: BlockEditProps<WireframeData>) {\n return <WireframeSurfaceView data={data} ctx={ctx} />;\n}\n\n/** Full client spec for the shared `wireframe` block (schema + MDX + Read/Edit). */\nexport const wireframeBlock = defineBlock<WireframeData>({\n type: \"wireframe\",\n schema: wireframeSchema,\n mdx: wireframeMdx,\n Read: WireframeBlock,\n Edit: WireframeEditor,\n placement: [\"block\"],\n editSurface: \"inline\",\n label: \"Wireframe\",\n description:\n \"A sketch wireframe of one screen built from kit primitives (or an HTML mockup), rendered in a chosen surface frame (desktop/mobile/popover/panel/browser).\",\n // `surface` is the only required field; `screen` defaults to []. Start on the\n // desktop surface with an empty screen so the canvas/agent can fill it in.\n empty: () => ({ surface: \"desktop\", screen: [] }),\n});\n"]}
|
|
@@ -16,6 +16,8 @@ import type { ZodType } from "zod";
|
|
|
16
16
|
*/
|
|
17
17
|
/** Where a block can be placed in a document. */
|
|
18
18
|
export type BlockPlacement = "block" | "inline";
|
|
19
|
+
/** How visual blocks decide whether to draw an outer surface frame. */
|
|
20
|
+
export type BlockVisualFrame = "auto" | "show" | "hide";
|
|
19
21
|
/**
|
|
20
22
|
* A serialized MDX/NFM attribute value before the shared `prop()` encoder runs.
|
|
21
23
|
* `prop()` decides string-vs-JSON encoding; this is just the value domain.
|
|
@@ -85,6 +87,12 @@ export interface BlockRenderContext {
|
|
|
85
87
|
dialect?: "gfm" | "nfm";
|
|
86
88
|
/** Document text direction inferred by the host app. */
|
|
87
89
|
textDirection?: "ltr" | "rtl";
|
|
90
|
+
/**
|
|
91
|
+
* Host default for visual wireframe/diagram frames when block data leaves
|
|
92
|
+
* `frame` unset or set to `auto`. Plans/recaps usually show a frame; docs can
|
|
93
|
+
* hide it by default and let individual blocks opt back in.
|
|
94
|
+
*/
|
|
95
|
+
visualFrame?: Exclude<BlockVisualFrame, "auto">;
|
|
88
96
|
/** Resolve an asset id → displayable URL. */
|
|
89
97
|
resolveAssetSrc?: (assetId: string) => string | undefined;
|
|
90
98
|
/** Open the shared asset picker (returns the chosen asset). */
|