@agent-native/core 0.44.3 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/cli/connect.d.ts +2 -1
  2. package/dist/cli/connect.d.ts.map +1 -1
  3. package/dist/cli/connect.js +185 -5
  4. package/dist/cli/connect.js.map +1 -1
  5. package/dist/cli/index.js +27 -0
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/cli/plan-local.d.ts +43 -0
  8. package/dist/cli/plan-local.d.ts.map +1 -0
  9. package/dist/cli/plan-local.js +477 -0
  10. package/dist/cli/plan-local.js.map +1 -0
  11. package/dist/cli/pr-visual-recap-workflow.d.ts +1 -1
  12. package/dist/cli/pr-visual-recap-workflow.d.ts.map +1 -1
  13. package/dist/cli/pr-visual-recap-workflow.js +1 -1
  14. package/dist/cli/pr-visual-recap-workflow.js.map +1 -1
  15. package/dist/cli/recap.d.ts +164 -0
  16. package/dist/cli/recap.d.ts.map +1 -1
  17. package/dist/cli/recap.js +657 -10
  18. package/dist/cli/recap.js.map +1 -1
  19. package/dist/cli/skills.d.ts +6 -2
  20. package/dist/cli/skills.d.ts.map +1 -1
  21. package/dist/cli/skills.js +440 -37
  22. package/dist/cli/skills.js.map +1 -1
  23. package/dist/client/blocks/library/AnnotatedCodeBlock.d.ts.map +1 -1
  24. package/dist/client/blocks/library/AnnotatedCodeBlock.js +18 -4
  25. package/dist/client/blocks/library/AnnotatedCodeBlock.js.map +1 -1
  26. package/dist/client/blocks/library/ApiEndpointBlock.d.ts.map +1 -1
  27. package/dist/client/blocks/library/ApiEndpointBlock.js +11 -7
  28. package/dist/client/blocks/library/ApiEndpointBlock.js.map +1 -1
  29. package/dist/client/blocks/library/DiffBlock.d.ts.map +1 -1
  30. package/dist/client/blocks/library/DiffBlock.js +90 -7
  31. package/dist/client/blocks/library/DiffBlock.js.map +1 -1
  32. package/dist/client/blocks/library/HighlightedCode.d.ts +2 -1
  33. package/dist/client/blocks/library/HighlightedCode.d.ts.map +1 -1
  34. package/dist/client/blocks/library/HighlightedCode.js +2 -2
  35. package/dist/client/blocks/library/HighlightedCode.js.map +1 -1
  36. package/dist/client/blocks/library/JsonExplorerBlock.d.ts.map +1 -1
  37. package/dist/client/blocks/library/JsonExplorerBlock.js +57 -13
  38. package/dist/client/blocks/library/JsonExplorerBlock.js.map +1 -1
  39. package/dist/client/blocks/library/annotation-rail.d.ts +15 -5
  40. package/dist/client/blocks/library/annotation-rail.d.ts.map +1 -1
  41. package/dist/client/blocks/library/annotation-rail.js +35 -24
  42. package/dist/client/blocks/library/annotation-rail.js.map +1 -1
  43. package/dist/client/blocks/library/code-filename-label.d.ts +8 -0
  44. package/dist/client/blocks/library/code-filename-label.d.ts.map +1 -0
  45. package/dist/client/blocks/library/code-filename-label.js +15 -0
  46. package/dist/client/blocks/library/code-filename-label.js.map +1 -0
  47. package/dist/client/blocks/library/code.d.ts.map +1 -1
  48. package/dist/client/blocks/library/code.js +28 -6
  49. package/dist/client/blocks/library/code.js.map +1 -1
  50. package/dist/client/blocks/library/columns.d.ts.map +1 -1
  51. package/dist/client/blocks/library/columns.js +11 -1
  52. package/dist/client/blocks/library/columns.js.map +1 -1
  53. package/dist/client/blocks/library/diff.config.d.ts +1 -1
  54. package/dist/client/blocks/library/diff.config.js.map +1 -1
  55. package/dist/client/blocks/library/narrow-container.d.ts +13 -0
  56. package/dist/client/blocks/library/narrow-container.d.ts.map +1 -0
  57. package/dist/client/blocks/library/narrow-container.js +32 -0
  58. package/dist/client/blocks/library/narrow-container.js.map +1 -0
  59. package/dist/client/blocks/library/question-form.d.ts.map +1 -1
  60. package/dist/client/blocks/library/question-form.js +8 -9
  61. package/dist/client/blocks/library/question-form.js.map +1 -1
  62. package/dist/client/blocks/library/tabs.d.ts.map +1 -1
  63. package/dist/client/blocks/library/tabs.js +11 -5
  64. package/dist/client/blocks/library/tabs.js.map +1 -1
  65. package/dist/client/blocks/types.d.ts +2 -0
  66. package/dist/client/blocks/types.d.ts.map +1 -1
  67. package/dist/client/blocks/types.js.map +1 -1
  68. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  69. package/dist/client/composer/TiptapComposer.js +4 -1
  70. package/dist/client/composer/TiptapComposer.js.map +1 -1
  71. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  72. package/dist/client/db-admin/TableEditor.js +3 -1
  73. package/dist/client/db-admin/TableEditor.js.map +1 -1
  74. package/dist/db/client.d.ts +19 -0
  75. package/dist/db/client.d.ts.map +1 -1
  76. package/dist/db/client.js +43 -2
  77. package/dist/db/client.js.map +1 -1
  78. package/dist/db/migrations.d.ts.map +1 -1
  79. package/dist/db/migrations.js +9 -2
  80. package/dist/db/migrations.js.map +1 -1
  81. package/dist/deploy/build.d.ts.map +1 -1
  82. package/dist/deploy/build.js +8 -0
  83. package/dist/deploy/build.js.map +1 -1
  84. package/dist/extensions/html-shell.js +1 -1
  85. package/dist/extensions/html-shell.js.map +1 -1
  86. package/dist/jobs/scheduler.d.ts.map +1 -1
  87. package/dist/jobs/scheduler.js +5 -1
  88. package/dist/jobs/scheduler.js.map +1 -1
  89. package/dist/mcp/build-server.d.ts +1 -0
  90. package/dist/mcp/build-server.d.ts.map +1 -1
  91. package/dist/mcp/build-server.js +7 -3
  92. package/dist/mcp/build-server.js.map +1 -1
  93. package/dist/mcp/oauth-route.d.ts.map +1 -1
  94. package/dist/mcp/oauth-route.js +56 -19
  95. package/dist/mcp/oauth-route.js.map +1 -1
  96. package/dist/mcp/oauth-store.d.ts +1 -0
  97. package/dist/mcp/oauth-store.d.ts.map +1 -1
  98. package/dist/mcp/oauth-store.js +9 -0
  99. package/dist/mcp/oauth-store.js.map +1 -1
  100. package/dist/mcp/server.d.ts.map +1 -1
  101. package/dist/mcp/server.js +9 -4
  102. package/dist/mcp/server.js.map +1 -1
  103. package/dist/mcp-client/errors.js +3 -3
  104. package/dist/mcp-client/errors.js.map +1 -1
  105. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  106. package/dist/server/agent-chat-plugin.js +3 -1
  107. package/dist/server/agent-chat-plugin.js.map +1 -1
  108. package/dist/server/agent-teams.d.ts.map +1 -1
  109. package/dist/server/agent-teams.js +10 -2
  110. package/dist/server/agent-teams.js.map +1 -1
  111. package/dist/server/auth.d.ts.map +1 -1
  112. package/dist/server/auth.js +7 -3
  113. package/dist/server/auth.js.map +1 -1
  114. package/dist/server/recap-image-route.d.ts.map +1 -1
  115. package/dist/server/recap-image-route.js +3 -6
  116. package/dist/server/recap-image-route.js.map +1 -1
  117. package/dist/server/sentry.d.ts.map +1 -1
  118. package/dist/server/sentry.js +12 -5
  119. package/dist/server/sentry.js.map +1 -1
  120. package/dist/server/social-og-image.d.ts.map +1 -1
  121. package/dist/server/social-og-image.js +3 -1
  122. package/dist/server/social-og-image.js.map +1 -1
  123. package/dist/styles/blocks.css +36 -10
  124. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
  125. package/docs/content/plan-plugin.md +18 -1
  126. package/docs/content/pr-visual-recap.md +37 -10
  127. package/docs/content/template-plan.md +45 -1
  128. package/package.json +1 -1
  129. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +22 -6
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from "react";
2
+ /** True when the current block renders inside a constrained tab/column cell. */
3
+ export declare function useInNarrowContainer(): boolean;
4
+ /**
5
+ * Marks its subtree as living inside a width-constrained container. Wrap the
6
+ * children a vertical `tabs` or `columns` block renders so nested
7
+ * width-sensitive blocks can pick a container-appropriate default. Idempotent:
8
+ * nesting the provider keeps the flag `true`.
9
+ */
10
+ export declare function NarrowContainerProvider({ children }: {
11
+ children: ReactNode;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=narrow-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrow-container.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/narrow-container.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAmBlE,gFAAgF;AAChF,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAM5E"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ /**
4
+ * Flags that a block is rendered inside a WIDTH-CONSTRAINED container — a
5
+ * vertical `tabs` side rail or a `columns`/`Column` cell. Width-sensitive blocks
6
+ * (today the `diff` block) read this to pick a default layout that survives the
7
+ * narrower box: e.g. a diff with NO authored `mode` defaults to `unified` inside
8
+ * one of these containers instead of `split`, whose doubled line-number gutters
9
+ * crush the code in a half-width or vertical-tab column.
10
+ *
11
+ * It only nudges the DEFAULT. An explicitly authored mode (`mode="split"`) still
12
+ * wins, and the in-block Unified/Split toggle still works in either context —
13
+ * this never disables side-by-side, it just changes what you get before you pick.
14
+ *
15
+ * Lives in core beside the blocks so both the containers (`tabs`, `columns`) and
16
+ * the consumers (`DiffBlock`) share one source of truth without a new dep.
17
+ */
18
+ const NarrowContainerContext = createContext(false);
19
+ /** True when the current block renders inside a constrained tab/column cell. */
20
+ export function useInNarrowContainer() {
21
+ return useContext(NarrowContainerContext);
22
+ }
23
+ /**
24
+ * Marks its subtree as living inside a width-constrained container. Wrap the
25
+ * children a vertical `tabs` or `columns` block renders so nested
26
+ * width-sensitive blocks can pick a container-appropriate default. Idempotent:
27
+ * nesting the provider keeps the flag `true`.
28
+ */
29
+ export function NarrowContainerProvider({ children }) {
30
+ return (_jsx(NarrowContainerContext.Provider, { value: true, children: children }));
31
+ }
32
+ //# sourceMappingURL=narrow-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narrow-container.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/narrow-container.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,MAAM,sBAAsB,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAEpD,gFAAgF;AAChF,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAAU,CAAC,sBAAsB,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAE,QAAQ,EAA2B;IAC3E,OAAO,CACL,KAAC,sBAAsB,CAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,YACzC,QAAQ,GACuB,CACnC,CAAC;AACJ,CAAC","sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\n\n/**\n * Flags that a block is rendered inside a WIDTH-CONSTRAINED container — a\n * vertical `tabs` side rail or a `columns`/`Column` cell. Width-sensitive blocks\n * (today the `diff` block) read this to pick a default layout that survives the\n * narrower box: e.g. a diff with NO authored `mode` defaults to `unified` inside\n * one of these containers instead of `split`, whose doubled line-number gutters\n * crush the code in a half-width or vertical-tab column.\n *\n * It only nudges the DEFAULT. An explicitly authored mode (`mode=\"split\"`) still\n * wins, and the in-block Unified/Split toggle still works in either context —\n * this never disables side-by-side, it just changes what you get before you pick.\n *\n * Lives in core beside the blocks so both the containers (`tabs`, `columns`) and\n * the consumers (`DiffBlock`) share one source of truth without a new dep.\n */\nconst NarrowContainerContext = createContext(false);\n\n/** True when the current block renders inside a constrained tab/column cell. */\nexport function useInNarrowContainer(): boolean {\n return useContext(NarrowContainerContext);\n}\n\n/**\n * Marks its subtree as living inside a width-constrained container. Wrap the\n * children a vertical `tabs` or `columns` block renders so nested\n * width-sensitive blocks can pick a container-appropriate default. Idempotent:\n * nesting the provider keeps the flag `true`.\n */\nexport function NarrowContainerProvider({ children }: { children: ReactNode }) {\n return (\n <NarrowContainerContext.Provider value={true}>\n {children}\n </NarrowContainerContext.Provider>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"question-form.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,KAAK,gBAAgB,EAIrB,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAoanC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAEvE;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,CAAC,mBAAmB,CAAC,2CAG3C;AAaD,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAsTlC;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,mDAsB5B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,mDAmC/B,CAAC"}
1
+ {"version":3,"file":"question-form.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAGf,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,KAAK,gBAAgB,EAIrB,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAganC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAEvE;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,CAAC,mBAAmB,CAAC,2CAG3C;AAaD,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,cAAc,CAAC,gBAAgB,CAAC,2CAsTlC;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,mDAsB5B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,mDAmC/B,CAAC"}
@@ -70,16 +70,16 @@ function QuestionView({ question, index, answer, blockId, ctx, onAnswer, }) {
70
70
  }), question.allowOther !== false && (_jsx("input", { value: answer?.text ?? "", onChange: (event) => onAnswer({ ...answer, text: event.target.value }), className: cn("h-10 w-full rounded-lg border border-border bg-card px-4 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring", hasVisualOptions ? "md:col-span-2" : "sm:w-80"), "data-plan-interactive": true, placeholder: question.placeholder || "Other — type your own answer…" }))] }))] })] }));
71
71
  }
72
72
  /** The "Send to agent" affordance: a popover (via the app surface) when wired. */
73
- function SubmitMenu({ blockId, ctx, onSubmit, buildSummary, }) {
73
+ function SubmitMenu({ ctx, onSubmit, buildSummary, }) {
74
74
  const [open, setOpen] = useState(false);
75
75
  const trigger = (_jsxs("button", { type: "button", "data-plan-interactive": true, className: "inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90", children: ["Send to agent", _jsx(IconChevronDown, { className: "size-3.5 opacity-70" })] }));
76
- const menu = (_jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "px-1 py-1 text-xs font-semibold text-muted-foreground", children: "Send feedback" }), _jsxs("button", { type: "button", "data-plan-interactive": true, disabled: !onSubmit, onClick: () => {
77
- onSubmit?.(buildSummary());
78
- setOpen(false);
79
- }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(IconSend, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Send to inline agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Posts answered questions into the app side agent." })] })] }), _jsxs("button", { type: "button", "data-plan-interactive": true, onClick: () => {
76
+ const menu = (_jsxs("div", { className: "grid gap-1", children: [_jsx("div", { className: "px-1 py-1 text-xs font-semibold text-muted-foreground", children: "Send feedback" }), _jsxs("button", { type: "button", "data-plan-interactive": true, onClick: () => {
80
77
  void navigator.clipboard.writeText(buildSummary());
81
78
  setOpen(false);
82
- }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent", children: [_jsx(IconClipboardText, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Copy for your agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Copies a prompt you can paste into chat." })] })] })] }));
79
+ }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent", children: [_jsx(IconClipboardText, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Copy for your agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Copies a prompt you can paste into chat." })] })] }), _jsxs("button", { type: "button", "data-plan-interactive": true, disabled: !onSubmit, onClick: () => {
80
+ onSubmit?.(buildSummary());
81
+ setOpen(false);
82
+ }, className: "grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(IconSend, { className: "mt-0.5 size-4" }), _jsxs("span", { className: "grid gap-0.5", children: [_jsx("span", { children: "Send to inline agent" }), _jsx("span", { className: "text-xs font-normal leading-4 text-muted-foreground", children: "Posts answered questions into the app side agent." })] })] })] }));
83
83
  // Prefer the app-provided popover surface (shadcn Popover in plan/content);
84
84
  // core stays shadcn-free. Without a surface, fall back to a single button that
85
85
  // submits directly so the form still works.
@@ -87,8 +87,7 @@ function SubmitMenu({ blockId, ctx, onSubmit, buildSummary, }) {
87
87
  title: "Send to agent",
88
88
  open,
89
89
  onOpenChange: setOpen,
90
- blockId,
91
- blockType: "question-form",
90
+ variant: "menu",
92
91
  trigger,
93
92
  children: menu,
94
93
  });
@@ -109,7 +108,7 @@ function QuestionFormReadInner({ data, blockId, title, ctx, }) {
109
108
  };
110
109
  const answered = questions.filter((question) => isAnswered(question, answers[question.id])).length;
111
110
  const buildSummary = () => summarizeAnswers(blockId, title, questions, answers);
112
- return (_jsxs("section", { className: "an-questions-block plan-questions-block", "data-block-id": blockId, children: [title && (_jsx("h2", { className: "text-[1.45rem] font-semibold leading-tight text-foreground", children: title })), _jsx("div", { className: "mt-7 grid gap-8", children: questions.map((question, index) => (_jsx(QuestionView, { question: question, index: index, answer: answers[question.id], blockId: blockId, ctx: ctx, onAnswer: (next) => setAnswer(question.id, next) }, question.id))) }), _jsxs("div", { className: "sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border bg-background py-4 backdrop-blur", children: [_jsxs("p", { className: "text-sm font-semibold text-muted-foreground", children: [answered, "/", questions.length, " answered"] }), _jsx("div", { "data-plan-interactive": true, children: _jsx(SubmitMenu, { blockId: blockId, ctx: ctx, onSubmit: submitCtx.onQuestionFormSubmit, buildSummary: buildSummary }) })] })] }));
111
+ return (_jsxs("section", { className: "an-questions-block plan-questions-block", "data-block-id": blockId, children: [title && (_jsx("h2", { className: "text-[1.45rem] font-semibold leading-tight text-foreground", children: title })), _jsx("div", { className: "mt-7 grid gap-8", children: questions.map((question, index) => (_jsx(QuestionView, { question: question, index: index, answer: answers[question.id], blockId: blockId, ctx: ctx, onAnswer: (next) => setAnswer(question.id, next) }, question.id))) }), _jsxs("div", { className: "sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border py-4", children: [_jsxs("p", { className: "text-sm font-semibold text-muted-foreground", children: [answered, "/", questions.length, " answered"] }), _jsx("div", { "data-plan-interactive": true, children: _jsx(SubmitMenu, { ctx: ctx, onSubmit: submitCtx.onQuestionFormSubmit, buildSummary: buildSummary }) })] })] }));
113
112
  }
114
113
  export function QuestionFormRead(props) {
115
114
  return _jsx(QuestionFormReadInner, { ...props });
@@ -1 +1 @@
1
- {"version":3,"file":"question-form.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n IconCheck,\n IconChevronDown,\n IconClipboardText,\n IconPlus,\n IconSend,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n NestedBlock,\n} from \"../types.js\";\nimport {\n questionFormSchema,\n questionFormMdx,\n visualQuestionsSchema,\n visualQuestionsMdx,\n type QuestionFormData,\n type QuestionFormOption,\n type QuestionFormQuestion,\n type QuestionMode,\n type VisualQuestionsData,\n} from \"./question-form.config.js\";\n\n/**\n * Shared `question-form` and `visual-questions` blocks. A respondent-facing\n * intake form: single/multi/freeform questions, recommended options, optional\n * write-in answers, and optional inline wireframe/diagram previews per option.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * The block stays app-agnostic:\n * - It is shadcn-free. The \"Send to agent\" affordance uses `ctx.renderEditSurface`\n * (the app-provided popover primitive); when no surface is wired it falls back\n * to a plain button that submits directly.\n * - Submission routes through `ctx.onQuestionFormSubmit` so each app wires its own\n * destination (plan posts the summary into the side agent). The readable summary\n * string is built generically here from questions + collected answers.\n * - Per-option `wireframe`/`diagram` previews render through `ctx.renderBlock`\n * (the same nested-block seam tabs/columns use), so core never imports an app's\n * wireframe or diagram renderer.\n * - Colors map to shadcn theme tokens (`text-muted-foreground`, `border-border`,\n * `bg-background`, `bg-card`, `primary`). The root section carries BOTH the\n * app-neutral `an-questions-block` class and the legacy `plan-questions-block`\n * class so plan renders byte-identically while other apps get the theme treatment.\n */\n\n/**\n * `ctx.onQuestionFormSubmit` is the documented submit hook. It is read off the\n * render context as an optional extra so a host that has not yet added it to its\n * provider degrades to a no-op (the button disables) rather than throwing.\n */\ntype QuestionFormSubmitCtx = BlockRenderContext & {\n onQuestionFormSubmit?: (summary: string) => void;\n};\n\n/**\n * Reviewer answers are transient and never persisted on block data — they live\n * in local component state keyed by question id. `freeform` → a string;\n * `single`/`multi` → selected option ids (with an optional write-in `text`).\n */\ntype QuestionAnswer = { text?: string; selected?: string[] };\ntype QuestionAnswers = Record<string, QuestionAnswer>;\n\nfunction isAnswered(\n question: QuestionFormQuestion,\n answer?: QuestionAnswer,\n): boolean {\n if (question.mode === \"freeform\") return Boolean(answer?.text?.trim());\n return Boolean(answer?.selected?.length || answer?.text?.trim());\n}\n\n/**\n * Build a readable, agent-ready summary string from the questions + collected\n * answers. Generic replacement for the plan-specific `summarizeQuestionForm`.\n */\nfunction summarizeAnswers(\n blockId: string | undefined,\n blockTitle: string | undefined,\n questions: QuestionFormQuestion[],\n answers: QuestionAnswers,\n): string {\n const lines = [\n \"Use these question answers to revise the plan:\",\n blockId ? `Question block: ${blockId}` : \"\",\n blockTitle ? `Section: ${blockTitle}` : \"\",\n \"\",\n ].filter((line) => line !== \"\");\n for (const question of questions) {\n const answer = answers[question.id];\n const selectedLabels =\n question.options\n ?.filter((option) => answer?.selected?.includes(option.id))\n .map((option) => option.label) ?? [];\n const other = answer?.text?.trim();\n const value =\n question.mode === \"freeform\"\n ? other\n : [...selectedLabels, ...(other ? [`Other: ${other}`] : [])].join(\", \");\n lines.push(`- ${question.title}: ${value || \"No answer yet\"}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Render an inline preview (wireframe or diagram) through the app's dispatcher. */\nfunction OptionVisual({\n type,\n data,\n blockId,\n ctx,\n}: {\n type: \"wireframe\" | \"diagram\";\n data: unknown;\n blockId: string;\n ctx: BlockRenderContext;\n}) {\n if (!data || !ctx.renderBlock) return null;\n const block: NestedBlock = {\n id: `${blockId}-${type}`,\n type,\n data,\n };\n return (\n <>{ctx.renderBlock({ block, editing: false, compactVisuals: true })}</>\n );\n}\n\nfunction QuestionView({\n question,\n index,\n answer,\n blockId,\n ctx,\n onAnswer,\n}: {\n question: QuestionFormQuestion;\n index: number;\n answer?: QuestionAnswer;\n blockId: string;\n ctx: BlockRenderContext;\n onAnswer: (answer: QuestionAnswer) => void;\n}) {\n const selected = answer?.selected ?? [];\n const hasVisualOptions = Boolean(\n question.options?.some((option) => option.wireframe || option.diagram),\n );\n return (\n <article className=\"grid gap-4 sm:grid-cols-[36px_minmax(0,1fr)]\">\n <div className=\"flex size-7 items-center justify-center rounded-full border border-border bg-card text-xs font-semibold text-muted-foreground\">\n {index + 1}\n </div>\n <div>\n <h3 className=\"text-lg font-semibold leading-7 text-foreground\">\n {question.title}\n </h3>\n {question.subtitle && (\n <p className=\"mt-1.5 max-w-3xl text-sm leading-6 text-muted-foreground\">\n {question.subtitle}\n </p>\n )}\n {question.mode === \"freeform\" ? (\n <textarea\n value={answer?.text ?? \"\"}\n onChange={(event) => onAnswer({ text: event.target.value })}\n className=\"mt-4 min-h-28 w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\"\n data-plan-interactive\n placeholder={question.placeholder || \"Add details...\"}\n />\n ) : (\n <div\n className={cn(\n \"mt-4\",\n hasVisualOptions\n ? \"grid gap-4 md:grid-cols-2\"\n : \"grid max-w-4xl gap-3\",\n )}\n >\n {question.options?.map((option) => {\n const isSelected = selected.includes(option.id);\n return (\n <button\n key={option.id}\n type=\"button\"\n data-plan-interactive\n aria-pressed={isSelected}\n className={cn(\n hasVisualOptions\n ? \"grid gap-4 rounded-xl border border-border bg-card p-4 text-left transition-colors hover:bg-accent/30\"\n : \"grid w-full gap-2 rounded-xl border border-border bg-card px-4 py-3 text-left text-foreground transition-colors hover:border-primary/40 hover:bg-accent/30\",\n isSelected && \"border-primary/40 bg-primary/10\",\n )}\n onClick={() => {\n if (question.mode === \"single\") {\n onAnswer({ ...answer, selected: [option.id] });\n return;\n }\n onAnswer({\n ...answer,\n selected: isSelected\n ? selected.filter((id) => id !== option.id)\n : [...selected, option.id],\n });\n }}\n >\n <div className=\"flex min-w-0 items-start gap-3\">\n <span\n className={cn(\n \"mt-0.5 flex size-5 shrink-0 items-center justify-center border\",\n question.mode === \"single\" ? \"rounded-full\" : \"rounded\",\n isSelected\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border\",\n )}\n >\n {isSelected && <IconCheck className=\"size-3.5\" />}\n </span>\n <span>\n <span className=\"text-base font-semibold leading-6 text-foreground\">\n {option.label}\n </span>\n {option.recommended && (\n <>\n {\" \"}\n <span className=\"ml-3 rounded-md border border-primary/30 px-2 py-0.5 align-middle text-[11px] font-medium uppercase tracking-[0.12em] text-primary\">\n Recommended\n </span>\n </>\n )}\n {option.detail && (\n <span className=\"mt-1 block max-w-2xl whitespace-pre-line text-sm font-normal leading-6 text-muted-foreground\">\n {option.detail}\n </span>\n )}\n </span>\n </div>\n {hasVisualOptions && (option.wireframe || option.diagram) && (\n <div className=\"ml-8 grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]\">\n {option.wireframe != null && (\n <OptionVisual\n type=\"wireframe\"\n data={option.wireframe}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n {option.diagram != null && (\n <OptionVisual\n type=\"diagram\"\n data={option.diagram}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n </div>\n )}\n </button>\n );\n })}\n {/* Multiple-choice questions always offer a write-in answer so a\n reviewer can give a custom response instead of the listed\n options. Authors opt out only by setting allowOther: false. */}\n {question.allowOther !== false && (\n <input\n value={answer?.text ?? \"\"}\n onChange={(event) =>\n onAnswer({ ...answer, text: event.target.value })\n }\n className={cn(\n \"h-10 w-full rounded-lg border border-border bg-card px-4 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\",\n hasVisualOptions ? \"md:col-span-2\" : \"sm:w-80\",\n )}\n data-plan-interactive\n placeholder={\n question.placeholder || \"Other — type your own answer…\"\n }\n />\n )}\n </div>\n )}\n </div>\n </article>\n );\n}\n\n/** The \"Send to agent\" affordance: a popover (via the app surface) when wired. */\nfunction SubmitMenu({\n blockId,\n ctx,\n onSubmit,\n buildSummary,\n}: {\n blockId: string;\n ctx: BlockRenderContext;\n onSubmit?: (summary: string) => void;\n buildSummary: () => string;\n}) {\n const [open, setOpen] = useState(false);\n const trigger = (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90\"\n >\n Send to agent\n <IconChevronDown className=\"size-3.5 opacity-70\" />\n </button>\n );\n\n const menu = (\n <div className=\"grid gap-1\">\n <div className=\"px-1 py-1 text-xs font-semibold text-muted-foreground\">\n Send feedback\n </div>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => {\n onSubmit?.(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconSend className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Send to inline agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Posts answered questions into the app side agent.\n </span>\n </span>\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => {\n void navigator.clipboard.writeText(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent\"\n >\n <IconClipboardText className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Copy for your agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Copies a prompt you can paste into chat.\n </span>\n </span>\n </button>\n </div>\n );\n\n // Prefer the app-provided popover surface (shadcn Popover in plan/content);\n // core stays shadcn-free. Without a surface, fall back to a single button that\n // submits directly so the form still works.\n const surface = ctx.renderEditSurface?.({\n title: \"Send to agent\",\n open,\n onOpenChange: setOpen,\n blockId,\n blockType: \"question-form\",\n trigger,\n children: menu,\n });\n if (surface) return <>{surface}</>;\n\n return (\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => onSubmit?.(buildSummary())}\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n Send to agent\n </button>\n );\n}\n\n/** Shared read renderer for both `question-form` and `visual-questions`. */\nfunction QuestionFormReadInner({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<QuestionFormData>) {\n const questions = data.questions;\n const [answers, setAnswers] = useState<QuestionAnswers>({});\n const submitCtx = ctx as QuestionFormSubmitCtx;\n\n useEffect(() => {\n setAnswers({});\n }, [blockId]);\n\n const setAnswer = (questionId: string, next: QuestionAnswer) => {\n setAnswers((current) => ({ ...current, [questionId]: next }));\n };\n\n const answered = questions.filter((question) =>\n isAnswered(question, answers[question.id]),\n ).length;\n const buildSummary = () =>\n summarizeAnswers(blockId, title, questions, answers);\n\n return (\n <section\n className=\"an-questions-block plan-questions-block\"\n data-block-id={blockId}\n >\n {title && (\n <h2 className=\"text-[1.45rem] font-semibold leading-tight text-foreground\">\n {title}\n </h2>\n )}\n <div className=\"mt-7 grid gap-8\">\n {questions.map((question, index) => (\n <QuestionView\n key={question.id}\n question={question}\n index={index}\n answer={answers[question.id]}\n blockId={blockId}\n ctx={ctx}\n onAnswer={(next) => setAnswer(question.id, next)}\n />\n ))}\n </div>\n <div className=\"sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border bg-background py-4 backdrop-blur\">\n <p className=\"text-sm font-semibold text-muted-foreground\">\n {answered}/{questions.length} answered\n </p>\n <div data-plan-interactive>\n <SubmitMenu\n blockId={blockId}\n ctx={ctx}\n onSubmit={submitCtx.onQuestionFormSubmit}\n buildSummary={buildSummary}\n />\n </div>\n </div>\n </section>\n );\n}\n\nexport function QuestionFormRead(props: BlockReadProps<QuestionFormData>) {\n return <QuestionFormReadInner {...props} />;\n}\n\nexport function VisualQuestionsRead(\n props: BlockReadProps<VisualQuestionsData>,\n) {\n return <QuestionFormReadInner {...props} />;\n}\n\nconst inlineInputClass =\n \"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineTextareaClass =\n \"w-full resize-y rounded-md border border-border bg-background px-3 py-2 text-sm leading-6 text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineLabelClass =\n \"text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground\";\n\nfunction newLocalId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Shared editor for both `question-form` and `visual-questions`. */\nexport function QuestionFormEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<QuestionFormData>) {\n const updateQuestion = (\n questionId: string,\n patch: Partial<QuestionFormQuestion>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId ? { ...question, ...patch } : question,\n ),\n });\n\n const addQuestion = () => {\n if (data.questions.length >= 40) return;\n onChange({\n ...data,\n questions: [\n ...data.questions,\n {\n id: newLocalId(\"question\"),\n title: \"New question\",\n mode: \"freeform\",\n placeholder: \"Type an answer...\",\n },\n ],\n });\n };\n\n const removeQuestion = (questionId: string) => {\n if (data.questions.length <= 1) return;\n onChange({\n ...data,\n questions: data.questions.filter(\n (question) => question.id !== questionId,\n ),\n });\n };\n\n const setQuestionMode = (\n question: QuestionFormQuestion,\n mode: QuestionMode,\n ) =>\n updateQuestion(question.id, {\n mode,\n options:\n mode === \"freeform\"\n ? question.options\n : question.options && question.options.length > 0\n ? question.options\n : [\n { id: newLocalId(\"option\"), label: \"Option A\" },\n { id: newLocalId(\"option\"), label: \"Option B\" },\n ],\n });\n\n const updateOption = (\n questionId: string,\n optionId: string,\n patch: Partial<QuestionFormOption>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId\n ? {\n ...question,\n options: (question.options ?? []).map((option) =>\n option.id === optionId ? { ...option, ...patch } : option,\n ),\n }\n : question,\n ),\n });\n\n const addOption = (questionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId && (question.options?.length ?? 0) < 40\n ? {\n ...question,\n options: [\n ...(question.options ?? []),\n { id: newLocalId(\"option\"), label: \"New option\" },\n ],\n }\n : question,\n ),\n });\n\n const removeOption = (questionId: string, optionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) => {\n if (question.id !== questionId) return question;\n const nextOptions = (question.options ?? []).filter(\n (option) => option.id !== optionId,\n );\n return { ...question, options: nextOptions };\n }),\n });\n\n return (\n <div className=\"grid gap-6\" data-plan-interactive>\n <div className=\"grid gap-4\">\n {data.questions.map((question, index) => {\n const options = question.options ?? [];\n return (\n <article\n key={question.id}\n className=\"rounded-lg border border-border bg-card p-4\"\n >\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <span className={inlineLabelClass}>Question {index + 1}</span>\n {data.questions.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete question ${index + 1}`}\n className=\"inline-flex size-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeQuestion(question.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n <div className=\"grid gap-3 md:grid-cols-[minmax(0,1fr)_12rem]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Title</span>\n <input\n className={inlineInputClass}\n value={question.title}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n title: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Mode</span>\n <select\n className={inlineInputClass}\n value={question.mode}\n disabled={!editable}\n onChange={(event) =>\n setQuestionMode(\n question,\n event.target.value as QuestionMode,\n )\n }\n >\n <option value=\"freeform\">Freeform</option>\n <option value=\"single\">Single choice</option>\n <option value=\"multi\">Multi choice</option>\n </select>\n </label>\n </div>\n <label className=\"mt-3 grid gap-1.5\">\n <span className={inlineLabelClass}>Subtitle</span>\n <textarea\n className={inlineTextareaClass}\n rows={2}\n value={question.subtitle ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n subtitle: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"mt-3 grid gap-3 md:grid-cols-[minmax(0,1fr)_auto_auto]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Placeholder</span>\n <input\n className={inlineInputClass}\n value={question.placeholder ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n placeholder: event.target.value || undefined,\n })\n }\n />\n </label>\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={Boolean(question.required)}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n required: event.target.checked || undefined,\n })\n }\n />\n Required\n </label>\n {question.mode !== \"freeform\" && (\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={question.allowOther !== false}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n allowOther: event.target.checked ? undefined : false,\n })\n }\n />\n Allow write-in\n </label>\n )}\n </div>\n {question.mode !== \"freeform\" && (\n <div className=\"mt-4 grid gap-3\">\n {options.map((option) => (\n <div\n key={option.id}\n className=\"grid gap-3 rounded-md border border-border/80 bg-background p-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\n >\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Option</span>\n <input\n className={inlineInputClass}\n value={option.label}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n label: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Detail</span>\n <input\n className={inlineInputClass}\n value={option.detail ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n detail: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"flex items-end gap-2\">\n <button\n type=\"button\"\n className={cn(\n \"inline-flex h-9 items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\",\n option.recommended && \"border-ring text-foreground\",\n )}\n disabled={!editable}\n onClick={() =>\n updateOption(question.id, option.id, {\n recommended: !option.recommended,\n })\n }\n >\n {option.recommended && (\n <IconCheck className=\"size-4\" />\n )}\n Recommended\n </button>\n {options.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete ${option.label}`}\n className=\"inline-flex size-9 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeOption(question.id, option.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || options.length >= 40}\n onClick={() => addOption(question.id)}\n >\n <IconPlus className=\"size-4\" />\n Add option\n </button>\n </div>\n )}\n </article>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || data.questions.length >= 40}\n onClick={addQuestion}\n >\n <IconPlus className=\"size-4\" />\n Add question\n </button>\n </div>\n );\n}\n\n/**\n * Full client spec for the shared `question-form` block. A respondent-facing\n * intake form edited from the block panel (the schema-ish question shape lives\n * behind the edit surface, not inline).\n */\nexport const questionFormBlock = defineBlock<QuestionFormData>({\n type: \"question-form\",\n schema: questionFormSchema,\n mdx: questionFormMdx,\n Read: QuestionFormRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\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. Edit the question schema from the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"open-question\",\n title: \"What should the agent clarify before revising this plan?\",\n mode: \"freeform\",\n placeholder: \"Add constraints, preferences, or a decision...\",\n },\n ],\n }),\n});\n\n/**\n * Full client spec for the shared `visual-questions` block — the same form UI\n * and data shape as `question-form`, branded for explicit visual intake before a\n * plan. Shares the Read/Edit internals; only the type, MDX tag, label, and seed\n * differ.\n */\nexport const visualQuestionsBlock = defineBlock<VisualQuestionsData>({\n type: \"visual-questions\",\n schema: visualQuestionsSchema,\n mdx: visualQuestionsMdx,\n Read: VisualQuestionsRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Visual questions\",\n description:\n \"A visual-intake question block that renders the respondent-facing question UI (single/multi/freeform, recommended options, inline wireframe/diagram previews) and keeps schema editing in the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"visual-question\",\n title: \"Which direction should this plan take?\",\n mode: \"single\",\n options: [\n {\n id: \"option-a\",\n label: \"Direction A\",\n detail: \"Keep the current shape and refine it.\",\n recommended: true,\n },\n {\n id: \"option-b\",\n label: \"Direction B\",\n detail: \"Try a larger structural revision.\",\n },\n ],\n allowOther: true,\n },\n ],\n }),\n});\n"]}
1
+ {"version":3,"file":"question-form.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/question-form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n IconCheck,\n IconChevronDown,\n IconClipboardText,\n IconPlus,\n IconSend,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockReadProps,\n BlockEditProps,\n BlockRenderContext,\n NestedBlock,\n} from \"../types.js\";\nimport {\n questionFormSchema,\n questionFormMdx,\n visualQuestionsSchema,\n visualQuestionsMdx,\n type QuestionFormData,\n type QuestionFormOption,\n type QuestionFormQuestion,\n type QuestionMode,\n type VisualQuestionsData,\n} from \"./question-form.config.js\";\n\n/**\n * Shared `question-form` and `visual-questions` blocks. A respondent-facing\n * intake form: single/multi/freeform questions, recommended options, optional\n * write-in answers, and optional inline wireframe/diagram previews per option.\n * Lives in core so any app can register it (it originated in the plan template).\n *\n * The block stays app-agnostic:\n * - It is shadcn-free. The \"Send to agent\" affordance uses `ctx.renderEditSurface`\n * (the app-provided popover primitive); when no surface is wired it falls back\n * to a plain button that submits directly.\n * - Submission routes through `ctx.onQuestionFormSubmit` so each app wires its own\n * destination (plan posts the summary into the side agent). The readable summary\n * string is built generically here from questions + collected answers.\n * - Per-option `wireframe`/`diagram` previews render through `ctx.renderBlock`\n * (the same nested-block seam tabs/columns use), so core never imports an app's\n * wireframe or diagram renderer.\n * - Colors map to shadcn theme tokens (`text-muted-foreground`, `border-border`,\n * `bg-background`, `bg-card`, `primary`). The root section carries BOTH the\n * app-neutral `an-questions-block` class and the legacy `plan-questions-block`\n * class so plan renders byte-identically while other apps get the theme treatment.\n */\n\n/**\n * `ctx.onQuestionFormSubmit` is the documented submit hook. It is read off the\n * render context as an optional extra so a host that has not yet added it to its\n * provider degrades to a no-op (the button disables) rather than throwing.\n */\ntype QuestionFormSubmitCtx = BlockRenderContext & {\n onQuestionFormSubmit?: (summary: string) => void;\n};\n\n/**\n * Reviewer answers are transient and never persisted on block data — they live\n * in local component state keyed by question id. `freeform` → a string;\n * `single`/`multi` → selected option ids (with an optional write-in `text`).\n */\ntype QuestionAnswer = { text?: string; selected?: string[] };\ntype QuestionAnswers = Record<string, QuestionAnswer>;\n\nfunction isAnswered(\n question: QuestionFormQuestion,\n answer?: QuestionAnswer,\n): boolean {\n if (question.mode === \"freeform\") return Boolean(answer?.text?.trim());\n return Boolean(answer?.selected?.length || answer?.text?.trim());\n}\n\n/**\n * Build a readable, agent-ready summary string from the questions + collected\n * answers. Generic replacement for the plan-specific `summarizeQuestionForm`.\n */\nfunction summarizeAnswers(\n blockId: string | undefined,\n blockTitle: string | undefined,\n questions: QuestionFormQuestion[],\n answers: QuestionAnswers,\n): string {\n const lines = [\n \"Use these question answers to revise the plan:\",\n blockId ? `Question block: ${blockId}` : \"\",\n blockTitle ? `Section: ${blockTitle}` : \"\",\n \"\",\n ].filter((line) => line !== \"\");\n for (const question of questions) {\n const answer = answers[question.id];\n const selectedLabels =\n question.options\n ?.filter((option) => answer?.selected?.includes(option.id))\n .map((option) => option.label) ?? [];\n const other = answer?.text?.trim();\n const value =\n question.mode === \"freeform\"\n ? other\n : [...selectedLabels, ...(other ? [`Other: ${other}`] : [])].join(\", \");\n lines.push(`- ${question.title}: ${value || \"No answer yet\"}`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Render an inline preview (wireframe or diagram) through the app's dispatcher. */\nfunction OptionVisual({\n type,\n data,\n blockId,\n ctx,\n}: {\n type: \"wireframe\" | \"diagram\";\n data: unknown;\n blockId: string;\n ctx: BlockRenderContext;\n}) {\n if (!data || !ctx.renderBlock) return null;\n const block: NestedBlock = {\n id: `${blockId}-${type}`,\n type,\n data,\n };\n return (\n <>{ctx.renderBlock({ block, editing: false, compactVisuals: true })}</>\n );\n}\n\nfunction QuestionView({\n question,\n index,\n answer,\n blockId,\n ctx,\n onAnswer,\n}: {\n question: QuestionFormQuestion;\n index: number;\n answer?: QuestionAnswer;\n blockId: string;\n ctx: BlockRenderContext;\n onAnswer: (answer: QuestionAnswer) => void;\n}) {\n const selected = answer?.selected ?? [];\n const hasVisualOptions = Boolean(\n question.options?.some((option) => option.wireframe || option.diagram),\n );\n return (\n <article className=\"grid gap-4 sm:grid-cols-[36px_minmax(0,1fr)]\">\n <div className=\"flex size-7 items-center justify-center rounded-full border border-border bg-card text-xs font-semibold text-muted-foreground\">\n {index + 1}\n </div>\n <div>\n <h3 className=\"text-lg font-semibold leading-7 text-foreground\">\n {question.title}\n </h3>\n {question.subtitle && (\n <p className=\"mt-1.5 max-w-3xl text-sm leading-6 text-muted-foreground\">\n {question.subtitle}\n </p>\n )}\n {question.mode === \"freeform\" ? (\n <textarea\n value={answer?.text ?? \"\"}\n onChange={(event) => onAnswer({ text: event.target.value })}\n className=\"mt-4 min-h-28 w-full rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\"\n data-plan-interactive\n placeholder={question.placeholder || \"Add details...\"}\n />\n ) : (\n <div\n className={cn(\n \"mt-4\",\n hasVisualOptions\n ? \"grid gap-4 md:grid-cols-2\"\n : \"grid max-w-4xl gap-3\",\n )}\n >\n {question.options?.map((option) => {\n const isSelected = selected.includes(option.id);\n return (\n <button\n key={option.id}\n type=\"button\"\n data-plan-interactive\n aria-pressed={isSelected}\n className={cn(\n hasVisualOptions\n ? \"grid gap-4 rounded-xl border border-border bg-card p-4 text-left transition-colors hover:bg-accent/30\"\n : \"grid w-full gap-2 rounded-xl border border-border bg-card px-4 py-3 text-left text-foreground transition-colors hover:border-primary/40 hover:bg-accent/30\",\n isSelected && \"border-primary/40 bg-primary/10\",\n )}\n onClick={() => {\n if (question.mode === \"single\") {\n onAnswer({ ...answer, selected: [option.id] });\n return;\n }\n onAnswer({\n ...answer,\n selected: isSelected\n ? selected.filter((id) => id !== option.id)\n : [...selected, option.id],\n });\n }}\n >\n <div className=\"flex min-w-0 items-start gap-3\">\n <span\n className={cn(\n \"mt-0.5 flex size-5 shrink-0 items-center justify-center border\",\n question.mode === \"single\" ? \"rounded-full\" : \"rounded\",\n isSelected\n ? \"border-primary bg-primary text-primary-foreground\"\n : \"border-border\",\n )}\n >\n {isSelected && <IconCheck className=\"size-3.5\" />}\n </span>\n <span>\n <span className=\"text-base font-semibold leading-6 text-foreground\">\n {option.label}\n </span>\n {option.recommended && (\n <>\n {\" \"}\n <span className=\"ml-3 rounded-md border border-primary/30 px-2 py-0.5 align-middle text-[11px] font-medium uppercase tracking-[0.12em] text-primary\">\n Recommended\n </span>\n </>\n )}\n {option.detail && (\n <span className=\"mt-1 block max-w-2xl whitespace-pre-line text-sm font-normal leading-6 text-muted-foreground\">\n {option.detail}\n </span>\n )}\n </span>\n </div>\n {hasVisualOptions && (option.wireframe || option.diagram) && (\n <div className=\"ml-8 grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]\">\n {option.wireframe != null && (\n <OptionVisual\n type=\"wireframe\"\n data={option.wireframe}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n {option.diagram != null && (\n <OptionVisual\n type=\"diagram\"\n data={option.diagram}\n blockId={`${blockId}-${option.id}`}\n ctx={ctx}\n />\n )}\n </div>\n )}\n </button>\n );\n })}\n {/* Multiple-choice questions always offer a write-in answer so a\n reviewer can give a custom response instead of the listed\n options. Authors opt out only by setting allowOther: false. */}\n {question.allowOther !== false && (\n <input\n value={answer?.text ?? \"\"}\n onChange={(event) =>\n onAnswer({ ...answer, text: event.target.value })\n }\n className={cn(\n \"h-10 w-full rounded-lg border border-border bg-card px-4 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\",\n hasVisualOptions ? \"md:col-span-2\" : \"sm:w-80\",\n )}\n data-plan-interactive\n placeholder={\n question.placeholder || \"Other — type your own answer…\"\n }\n />\n )}\n </div>\n )}\n </div>\n </article>\n );\n}\n\n/** The \"Send to agent\" affordance: a popover (via the app surface) when wired. */\nfunction SubmitMenu({\n ctx,\n onSubmit,\n buildSummary,\n}: {\n ctx: BlockRenderContext;\n onSubmit?: (summary: string) => void;\n buildSummary: () => string;\n}) {\n const [open, setOpen] = useState(false);\n const trigger = (\n <button\n type=\"button\"\n data-plan-interactive\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90\"\n >\n Send to agent\n <IconChevronDown className=\"size-3.5 opacity-70\" />\n </button>\n );\n\n const menu = (\n <div className=\"grid gap-1\">\n <div className=\"px-1 py-1 text-xs font-semibold text-muted-foreground\">\n Send feedback\n </div>\n <button\n type=\"button\"\n data-plan-interactive\n onClick={() => {\n void navigator.clipboard.writeText(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent\"\n >\n <IconClipboardText className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Copy for your agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Copies a prompt you can paste into chat.\n </span>\n </span>\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => {\n onSubmit?.(buildSummary());\n setOpen(false);\n }}\n className=\"grid grid-cols-[auto_1fr] items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconSend className=\"mt-0.5 size-4\" />\n <span className=\"grid gap-0.5\">\n <span>Send to inline agent</span>\n <span className=\"text-xs font-normal leading-4 text-muted-foreground\">\n Posts answered questions into the app side agent.\n </span>\n </span>\n </button>\n </div>\n );\n\n // Prefer the app-provided popover surface (shadcn Popover in plan/content);\n // core stays shadcn-free. Without a surface, fall back to a single button that\n // submits directly so the form still works.\n const surface = ctx.renderEditSurface?.({\n title: \"Send to agent\",\n open,\n onOpenChange: setOpen,\n variant: \"menu\",\n trigger,\n children: menu,\n });\n if (surface) return <>{surface}</>;\n\n return (\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!onSubmit}\n onClick={() => onSubmit?.(buildSummary())}\n className=\"inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n Send to agent\n </button>\n );\n}\n\n/** Shared read renderer for both `question-form` and `visual-questions`. */\nfunction QuestionFormReadInner({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<QuestionFormData>) {\n const questions = data.questions;\n const [answers, setAnswers] = useState<QuestionAnswers>({});\n const submitCtx = ctx as QuestionFormSubmitCtx;\n\n useEffect(() => {\n setAnswers({});\n }, [blockId]);\n\n const setAnswer = (questionId: string, next: QuestionAnswer) => {\n setAnswers((current) => ({ ...current, [questionId]: next }));\n };\n\n const answered = questions.filter((question) =>\n isAnswered(question, answers[question.id]),\n ).length;\n const buildSummary = () =>\n summarizeAnswers(blockId, title, questions, answers);\n\n return (\n <section\n className=\"an-questions-block plan-questions-block\"\n data-block-id={blockId}\n >\n {title && (\n <h2 className=\"text-[1.45rem] font-semibold leading-tight text-foreground\">\n {title}\n </h2>\n )}\n <div className=\"mt-7 grid gap-8\">\n {questions.map((question, index) => (\n <QuestionView\n key={question.id}\n question={question}\n index={index}\n answer={answers[question.id]}\n blockId={blockId}\n ctx={ctx}\n onAnswer={(next) => setAnswer(question.id, next)}\n />\n ))}\n </div>\n <div className=\"sticky bottom-0 mt-10 flex items-center justify-between gap-4 border-t border-border py-4\">\n <p className=\"text-sm font-semibold text-muted-foreground\">\n {answered}/{questions.length} answered\n </p>\n <div data-plan-interactive>\n <SubmitMenu\n ctx={ctx}\n onSubmit={submitCtx.onQuestionFormSubmit}\n buildSummary={buildSummary}\n />\n </div>\n </div>\n </section>\n );\n}\n\nexport function QuestionFormRead(props: BlockReadProps<QuestionFormData>) {\n return <QuestionFormReadInner {...props} />;\n}\n\nexport function VisualQuestionsRead(\n props: BlockReadProps<VisualQuestionsData>,\n) {\n return <QuestionFormReadInner {...props} />;\n}\n\nconst inlineInputClass =\n \"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineTextareaClass =\n \"w-full resize-y rounded-md border border-border bg-background px-3 py-2 text-sm leading-6 text-foreground shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-1 focus-visible:ring-ring\";\nconst inlineLabelClass =\n \"text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground\";\n\nfunction newLocalId(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Shared editor for both `question-form` and `visual-questions`. */\nexport function QuestionFormEdit({\n data,\n onChange,\n editable,\n}: BlockEditProps<QuestionFormData>) {\n const updateQuestion = (\n questionId: string,\n patch: Partial<QuestionFormQuestion>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId ? { ...question, ...patch } : question,\n ),\n });\n\n const addQuestion = () => {\n if (data.questions.length >= 40) return;\n onChange({\n ...data,\n questions: [\n ...data.questions,\n {\n id: newLocalId(\"question\"),\n title: \"New question\",\n mode: \"freeform\",\n placeholder: \"Type an answer...\",\n },\n ],\n });\n };\n\n const removeQuestion = (questionId: string) => {\n if (data.questions.length <= 1) return;\n onChange({\n ...data,\n questions: data.questions.filter(\n (question) => question.id !== questionId,\n ),\n });\n };\n\n const setQuestionMode = (\n question: QuestionFormQuestion,\n mode: QuestionMode,\n ) =>\n updateQuestion(question.id, {\n mode,\n options:\n mode === \"freeform\"\n ? question.options\n : question.options && question.options.length > 0\n ? question.options\n : [\n { id: newLocalId(\"option\"), label: \"Option A\" },\n { id: newLocalId(\"option\"), label: \"Option B\" },\n ],\n });\n\n const updateOption = (\n questionId: string,\n optionId: string,\n patch: Partial<QuestionFormOption>,\n ) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId\n ? {\n ...question,\n options: (question.options ?? []).map((option) =>\n option.id === optionId ? { ...option, ...patch } : option,\n ),\n }\n : question,\n ),\n });\n\n const addOption = (questionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) =>\n question.id === questionId && (question.options?.length ?? 0) < 40\n ? {\n ...question,\n options: [\n ...(question.options ?? []),\n { id: newLocalId(\"option\"), label: \"New option\" },\n ],\n }\n : question,\n ),\n });\n\n const removeOption = (questionId: string, optionId: string) =>\n onChange({\n ...data,\n questions: data.questions.map((question) => {\n if (question.id !== questionId) return question;\n const nextOptions = (question.options ?? []).filter(\n (option) => option.id !== optionId,\n );\n return { ...question, options: nextOptions };\n }),\n });\n\n return (\n <div className=\"grid gap-6\" data-plan-interactive>\n <div className=\"grid gap-4\">\n {data.questions.map((question, index) => {\n const options = question.options ?? [];\n return (\n <article\n key={question.id}\n className=\"rounded-lg border border-border bg-card p-4\"\n >\n <div className=\"mb-4 flex items-center justify-between gap-3\">\n <span className={inlineLabelClass}>Question {index + 1}</span>\n {data.questions.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete question ${index + 1}`}\n className=\"inline-flex size-8 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeQuestion(question.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n <div className=\"grid gap-3 md:grid-cols-[minmax(0,1fr)_12rem]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Title</span>\n <input\n className={inlineInputClass}\n value={question.title}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n title: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Mode</span>\n <select\n className={inlineInputClass}\n value={question.mode}\n disabled={!editable}\n onChange={(event) =>\n setQuestionMode(\n question,\n event.target.value as QuestionMode,\n )\n }\n >\n <option value=\"freeform\">Freeform</option>\n <option value=\"single\">Single choice</option>\n <option value=\"multi\">Multi choice</option>\n </select>\n </label>\n </div>\n <label className=\"mt-3 grid gap-1.5\">\n <span className={inlineLabelClass}>Subtitle</span>\n <textarea\n className={inlineTextareaClass}\n rows={2}\n value={question.subtitle ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n subtitle: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"mt-3 grid gap-3 md:grid-cols-[minmax(0,1fr)_auto_auto]\">\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Placeholder</span>\n <input\n className={inlineInputClass}\n value={question.placeholder ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n placeholder: event.target.value || undefined,\n })\n }\n />\n </label>\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={Boolean(question.required)}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n required: event.target.checked || undefined,\n })\n }\n />\n Required\n </label>\n {question.mode !== \"freeform\" && (\n <label className=\"flex items-end gap-2 text-sm font-semibold text-muted-foreground\">\n <input\n type=\"checkbox\"\n className=\"mb-2 size-4\"\n checked={question.allowOther !== false}\n disabled={!editable}\n onChange={(event) =>\n updateQuestion(question.id, {\n allowOther: event.target.checked ? undefined : false,\n })\n }\n />\n Allow write-in\n </label>\n )}\n </div>\n {question.mode !== \"freeform\" && (\n <div className=\"mt-4 grid gap-3\">\n {options.map((option) => (\n <div\n key={option.id}\n className=\"grid gap-3 rounded-md border border-border/80 bg-background p-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\n >\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Option</span>\n <input\n className={inlineInputClass}\n value={option.label}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n label: event.target.value,\n })\n }\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className={inlineLabelClass}>Detail</span>\n <input\n className={inlineInputClass}\n value={option.detail ?? \"\"}\n disabled={!editable}\n onChange={(event) =>\n updateOption(question.id, option.id, {\n detail: event.target.value || undefined,\n })\n }\n />\n </label>\n <div className=\"flex items-end gap-2\">\n <button\n type=\"button\"\n className={cn(\n \"inline-flex h-9 items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\",\n option.recommended && \"border-ring text-foreground\",\n )}\n disabled={!editable}\n onClick={() =>\n updateOption(question.id, option.id, {\n recommended: !option.recommended,\n })\n }\n >\n {option.recommended && (\n <IconCheck className=\"size-4\" />\n )}\n Recommended\n </button>\n {options.length > 1 && (\n <button\n type=\"button\"\n aria-label={`Delete ${option.label}`}\n className=\"inline-flex size-9 items-center justify-center rounded-md border border-border text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable}\n onClick={() => removeOption(question.id, option.id)}\n >\n <IconTrash className=\"size-4\" />\n </button>\n )}\n </div>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || options.length >= 40}\n onClick={() => addOption(question.id)}\n >\n <IconPlus className=\"size-4\" />\n Add option\n </button>\n </div>\n )}\n </article>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"inline-flex h-9 w-fit items-center gap-1.5 rounded-md border border-border px-3 text-sm font-semibold text-muted-foreground hover:bg-muted hover:text-foreground\"\n disabled={!editable || data.questions.length >= 40}\n onClick={addQuestion}\n >\n <IconPlus className=\"size-4\" />\n Add question\n </button>\n </div>\n );\n}\n\n/**\n * Full client spec for the shared `question-form` block. A respondent-facing\n * intake form edited from the block panel (the schema-ish question shape lives\n * behind the edit surface, not inline).\n */\nexport const questionFormBlock = defineBlock<QuestionFormData>({\n type: \"question-form\",\n schema: questionFormSchema,\n mdx: questionFormMdx,\n Read: QuestionFormRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\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. Edit the question schema from the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"open-question\",\n title: \"What should the agent clarify before revising this plan?\",\n mode: \"freeform\",\n placeholder: \"Add constraints, preferences, or a decision...\",\n },\n ],\n }),\n});\n\n/**\n * Full client spec for the shared `visual-questions` block — the same form UI\n * and data shape as `question-form`, branded for explicit visual intake before a\n * plan. Shares the Read/Edit internals; only the type, MDX tag, label, and seed\n * differ.\n */\nexport const visualQuestionsBlock = defineBlock<VisualQuestionsData>({\n type: \"visual-questions\",\n schema: visualQuestionsSchema,\n mdx: visualQuestionsMdx,\n Read: VisualQuestionsRead,\n Edit: QuestionFormEdit,\n placement: [\"block\"],\n editSurface: \"panel\",\n label: \"Visual questions\",\n description:\n \"A visual-intake question block that renders the respondent-facing question UI (single/multi/freeform, recommended options, inline wireframe/diagram previews) and keeps schema editing in the block panel.\",\n empty: () => ({\n submitLabel: \"Send to agent\",\n questions: [\n {\n id: \"visual-question\",\n title: \"Which direction should this plan take?\",\n mode: \"single\",\n options: [\n {\n id: \"option-a\",\n label: \"Direction A\",\n detail: \"Keep the current shape and refine it.\",\n recommended: true,\n },\n {\n id: \"option-b\",\n label: \"Direction B\",\n detail: \"Try a larger structural revision.\",\n },\n ],\n allowOther: true,\n },\n ],\n }),\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,kBAAkB,CAAC;AAuG1B,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAuC1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgM1B;AAuLD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,2CA0BpB,CAAC"}
1
+ {"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,KAAK,QAAQ,EAGd,MAAM,kBAAkB,CAAC;AAwG1B,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAsD1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,GAAG,GACJ,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgM1B;AAuLD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,2CA0BpB,CAAC"}
@@ -5,6 +5,7 @@ import { cn } from "../../utils.js";
5
5
  import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover.js";
6
6
  import { defineBlock } from "../types.js";
7
7
  import { tabsSchema, tabsMdx, } from "./tabs.config.js";
8
+ import { NarrowContainerProvider } from "./narrow-container.js";
8
9
  /**
9
10
  * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a
10
11
  * list of child blocks. Lives in core so any app (plan today, content later) can
@@ -65,11 +66,16 @@ export function TabsBlockReader({ data, blockId, title, ctx, }) {
65
66
  const orientation = tabOrientation(data);
66
67
  const vertical = orientation === "vertical";
67
68
  return (_jsxs("section", { className: "plan-block", "data-block-id": blockId, children: [title && _jsx("div", { className: "plan-block-label", children: title }), _jsx("div", { className: cn(vertical && "@container/tabs"), children: _jsxs("div", { className: cn(vertical &&
68
- "grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start"), children: [_jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId, orientation: orientation }), active && (_jsx("div", { className: cn(vertical && "min-w-0"), children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
69
- block: child,
70
- editing: false,
71
- compactVisuals: compact,
72
- }) }, child.id))) }))] }) })] }));
69
+ "grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start"), children: [_jsx(TabRail, { tabs: data.tabs, activeId: active?.id, onSelect: setActiveId, orientation: orientation }), active &&
70
+ (vertical ? (_jsx(NarrowContainerProvider, { children: _jsx("div", { className: "min-w-0", children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
71
+ block: child,
72
+ editing: false,
73
+ compactVisuals: compact,
74
+ }) }, child.id))) }) })) : (_jsx("div", { children: active.blocks.map((child) => (_jsx("div", { children: ctx.renderBlock?.({
75
+ block: child,
76
+ editing: false,
77
+ compactVisuals: compact,
78
+ }) }, child.id))) })))] }) })] }));
73
79
  }
74
80
  /**
75
81
  * Editor: pill tabs plus tab management (add/remove/rename), with child blocks
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport {\n IconLayoutNavbar,\n IconPencil,\n IconPlus,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/ui/popover.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockContainerRegion,\n BlockReadProps,\n BlockEditProps,\n NestedBlock,\n} from \"../types.js\";\nimport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsOrientation,\n type TabsTab,\n} from \"./tabs.config.js\";\n\n/**\n * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a\n * list of child blocks. Lives in core so any app (plan today, content later) can\n * register it.\n *\n * `Read`/`Edit` mirror the legacy plan `TabsBlock` markup byte-for-byte (same\n * `plan-block` section, the `inline-flex` pill tab rail with `role=\"tablist\"`/\n * `role=\"tab\"`, the same active-tab `useState`, and the `compactVisuals`\n * heuristic on the block title) so converting the block to the registry does not\n * change rendered output. The block chrome uses semantic shadcn tokens so the\n * same renderer stays quiet in both the plan and content apps.\n *\n * Child rendering flows through `ctx.renderBlock` — the app's own block\n * dispatcher — so registered children render via their spec and unconverted\n * children fall through the app's legacy switch. This is the coexistence seam:\n * the core tabs block never has to know app-specific child block types.\n */\n\n/** Mint a reasonably-unique tab id without pulling a dep into core. */\nfunction newTabId(): string {\n return `tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Compact embedded visuals for dense tab panes, matching legacy behavior. */\nfunction isCompact(title: string | undefined): boolean {\n return /interaction|component|note/i.test(title ?? \"\");\n}\n\nconst tabSettingsInputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction tabOrientation(data: Pick<TabsData, \"orientation\">): TabsOrientation {\n return data.orientation === \"vertical\" ? \"vertical\" : \"horizontal\";\n}\n\nfunction tabsWith(data: TabsData, tabs: TabsTab[]): TabsData {\n return { ...data, tabs };\n}\n\nfunction tabButtonClass(\n selected: boolean,\n orientation: TabsOrientation,\n): string {\n return cn(\n \"rounded-lg border border-transparent text-sm font-semibold transition-colors\",\n orientation === \"vertical\"\n ? \"min-w-0 max-w-72 shrink-0 px-3 py-2 text-left @xl/tabs:w-full @xl/tabs:max-w-none\"\n : \"shrink-0 whitespace-nowrap px-4 py-2\",\n selected\n ? \"bg-primary/5 text-foreground dark:bg-primary/10\"\n : \"text-muted-foreground hover:bg-muted/40 hover:text-foreground\",\n );\n}\n\nfunction tabLabelClass(orientation: TabsOrientation): string | undefined {\n return orientation === \"vertical\" ? \"block min-w-0 truncate\" : undefined;\n}\n\n/** Shared pill-tab rail. */\nfunction TabRail({\n tabs,\n activeId,\n onSelect,\n orientation,\n}: {\n tabs: TabsTab[];\n activeId: string | undefined;\n onSelect: (id: string) => void;\n orientation: TabsOrientation;\n}) {\n const vertical = orientation === \"vertical\";\n return (\n <div\n className={cn(\n vertical\n ? \"mb-5 flex w-full min-w-0 max-w-full flex-nowrap gap-1 overflow-x-auto @xl/tabs:mb-0 @xl/tabs:max-h-[62vh] @xl/tabs:flex-col @xl/tabs:overflow-x-hidden @xl/tabs:overflow-y-auto @xl/tabs:pr-2\"\n : \"mb-8 flex w-full min-w-0 max-w-full flex-nowrap gap-1 overflow-x-auto\",\n )}\n role=\"tablist\"\n aria-orientation={orientation}\n data-plan-interactive\n >\n {tabs.map((tab) => {\n const selected = tab.id === activeId;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onSelect(tab.id)}\n className={tabButtonClass(selected, orientation)}\n >\n <span className={tabLabelClass(orientation)}>{tab.label}</span>\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Read renderer: pill tabs, child blocks rendered read-only via the app. */\nexport function TabsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n const orientation = tabOrientation(data);\n const vertical = orientation === \"vertical\";\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className={cn(vertical && \"@container/tabs\")}>\n <div\n className={cn(\n vertical &&\n \"grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start\",\n )}\n >\n <TabRail\n tabs={data.tabs}\n activeId={active?.id}\n onSelect={setActiveId}\n orientation={orientation}\n />\n {active && (\n <div className={cn(vertical && \"min-w-0\")}>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: false,\n compactVisuals: compact,\n })}\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </section>\n );\n}\n\n/**\n * Editor: pill tabs plus tab management (add/remove/rename), with child blocks\n * rendered editable in place through the app dispatcher. A child change updates\n * that child within its tab and commits the whole tabs block — mirroring the\n * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/\n * `findBlock` (`PlanContentRenderer`) keeps working unchanged.\n */\nexport function TabsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n title,\n ctx,\n}: BlockEditProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n const orientation = tabOrientation(data);\n const vertical = orientation === \"vertical\";\n\n const commit = (tabs: TabsTab[]) => onChange(tabsWith(data, tabs));\n\n const setOrientation = (next: TabsOrientation) =>\n onChange({\n ...data,\n orientation: next === \"vertical\" ? \"vertical\" : undefined,\n });\n\n const renameTab = (id: string, label: string) =>\n commit(data.tabs.map((tab) => (tab.id === id ? { ...tab, label } : tab)));\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newTabId();\n commit([\n ...data.tabs,\n { id, label: `Tab ${data.tabs.length + 1}`, blocks: [] },\n ]);\n setActiveId(id);\n };\n\n const updateChild = (tabId: string, child: NestedBlock) =>\n commit(\n data.tabs.map((tab) =>\n tab.id === tabId\n ? {\n ...tab,\n blocks: tab.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : tab,\n ),\n );\n\n // Renders BARE (no `plan-block` section / title): in edit mode the app's\n // block dispatcher already wraps registered editors in a titled `plan-block`\n // section, so wrapping again here would double-nest. The read renderer\n // (`TabsBlockReader`) owns its own section because read mode renders the spec\n // directly.\n return (\n <div\n className={cn(\"min-w-0\", vertical && \"@container/tabs\")}\n data-tabs-edit-block={blockId}\n >\n <div\n className={cn(\n vertical &&\n \"grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start\",\n )}\n >\n <div\n className={cn(\n \"flex min-w-0 items-start gap-2\",\n vertical ? \"mb-5 @xl/tabs:mb-0\" : \"mb-8 w-full\",\n )}\n >\n <div\n className={cn(\n \"flex min-w-0 flex-1 gap-1\",\n vertical\n ? \"flex-nowrap overflow-x-auto @xl/tabs:max-h-[62vh] @xl/tabs:flex-col @xl/tabs:overflow-x-hidden @xl/tabs:overflow-y-auto @xl/tabs:pr-2\"\n : \"w-full flex-nowrap items-center overflow-x-auto\",\n )}\n role=\"tablist\"\n aria-orientation={orientation}\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n const tabLabel = (\n <span className={tabLabelClass(orientation)}>{tab.label}</span>\n );\n if (!vertical) {\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={tabButtonClass(selected, orientation)}\n >\n {tabLabel}\n </button>\n );\n }\n const tabButton = (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n tabButtonClass(selected, orientation),\n vertical && editable && selected && \"pr-9\",\n )}\n >\n {tabLabel}\n </button>\n );\n return (\n <div\n key={tab.id}\n className=\"group/tab relative flex min-w-0 max-w-72 shrink-0 @xl/tabs:w-full @xl/tabs:max-w-none\"\n >\n {tabButton}\n {editable && selected && (\n <TabsSettingsPopover\n active={active}\n orientation={orientation}\n tabs={data.tabs}\n triggerClassName=\"pointer-events-none absolute right-1.5 top-1/2 -translate-y-1/2 opacity-0 transition-opacity group-hover/tab:pointer-events-auto group-hover/tab:opacity-100 group-focus-within/tab:pointer-events-auto group-focus-within/tab:opacity-100 data-[state=open]:pointer-events-auto data-[state=open]:opacity-100\"\n onRename={renameTab}\n onOrientationChange={setOrientation}\n onAdd={addTab}\n onRemove={removeTab}\n />\n )}\n </div>\n );\n })}\n </div>\n {editable && !vertical && (\n <TabsSettingsPopover\n active={active}\n orientation={orientation}\n tabs={data.tabs}\n onRename={renameTab}\n onOrientationChange={setOrientation}\n onAdd={addTab}\n onRemove={removeTab}\n />\n )}\n </div>\n {active && (\n <div className={cn(vertical && \"min-w-0\")}>\n {ctx.renderBlocksEditor\n ? ctx.renderBlocksEditor({\n blocks: active.blocks,\n onChange: (nextBlocks) =>\n onChange(\n {\n ...data,\n tabs: data.tabs.map((tab) =>\n tab.id === active.id\n ? { ...tab, blocks: nextBlocks }\n : tab,\n ),\n },\n {\n containerRegion: {\n regionId: active.id,\n blocks: nextBlocks,\n },\n },\n ),\n editable,\n containerBlockId: blockId,\n regionId: active.id,\n regionLabel: active.label,\n compactVisuals: compact,\n })\n : active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n compactVisuals: compact,\n onChange: (next) => updateChild(active.id, next),\n })}\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction TabsSettingsPopover({\n active,\n orientation,\n tabs,\n onRename,\n onOrientationChange,\n onAdd,\n onRemove,\n triggerClassName,\n}: {\n active: TabsTab | undefined;\n orientation: TabsOrientation;\n tabs: TabsTab[];\n onRename: (id: string, label: string) => void;\n onOrientationChange: (orientation: TabsOrientation) => void;\n onAdd: () => void;\n onRemove: (id: string) => void;\n triggerClassName?: string;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Edit tabs\"\n className={cn(\n \"flex size-8 shrink-0 items-center justify-center rounded-md text-plan-muted transition-colors hover:text-plan-text focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n triggerClassName,\n )}\n >\n <IconPencil className=\"size-4\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n side=\"bottom\"\n className=\"w-80 p-0\"\n data-plan-interactive\n >\n <div className=\"border-b border-border px-3 py-2\">\n <div className=\"text-sm font-semibold text-foreground\">\n Tab settings\n </div>\n <div className=\"text-xs text-muted-foreground\">\n Rename the active tab, change layout, or manage the tab set.\n </div>\n </div>\n <div className=\"grid gap-3 p-3\">\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Active tab label\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={tabSettingsInputClass}\n value={active?.label ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onRename(active.id, event.target.value);\n }}\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Layout\n </span>\n <div\n className=\"grid grid-cols-2 gap-1 rounded-md border border-border bg-muted/30 p-1\"\n role=\"radiogroup\"\n aria-label=\"Tabs layout\"\n >\n {(\n [\n [\"horizontal\", \"Top\"],\n [\"vertical\", \"Side\"],\n ] satisfies Array<[TabsOrientation, string]>\n ).map(([value, label]) => {\n const selected = orientation === value;\n return (\n <button\n key={value}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n data-plan-interactive\n onClick={() => onOrientationChange(value)}\n className={cn(\n \"h-8 rounded px-2 text-xs font-medium transition-colors\",\n selected\n ? \"bg-background text-foreground\"\n : \"text-muted-foreground hover:bg-background/70 hover:text-foreground\",\n )}\n >\n {label}\n </button>\n );\n })}\n </div>\n </label>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n disabled={tabs.length >= 12}\n onClick={onAdd}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconPlus className=\"size-3.5\" />\n Add tab\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!active || tabs.length <= 1}\n onClick={() => {\n if (!active) return;\n onRemove(active.id);\n }}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-destructive transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconTrash className=\"size-3.5\" />\n Remove current\n </button>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction tabRegions(data: TabsData): BlockContainerRegion[] {\n return data.tabs.map((tab) => ({\n id: tab.id,\n label: tab.label,\n blocks: tab.blocks,\n }));\n}\n\nfunction addTabRegion(data: TabsData, afterRegionId?: string): TabsData {\n if (data.tabs.length >= 12) return data;\n const nextTab: TabsTab = {\n id: newTabId(),\n label: `Tab ${data.tabs.length + 1}`,\n blocks: [],\n };\n if (!afterRegionId) return tabsWith(data, [...data.tabs, nextTab]);\n const afterIndex = data.tabs.findIndex((tab) => tab.id === afterRegionId);\n if (afterIndex < 0) return tabsWith(data, [...data.tabs, nextTab]);\n return tabsWith(data, [\n ...data.tabs.slice(0, afterIndex + 1),\n nextTab,\n ...data.tabs.slice(afterIndex + 1),\n ]);\n}\n\nfunction removeTabRegion(data: TabsData, regionId: string): TabsData {\n if (data.tabs.length <= 1) return data;\n return tabsWith(\n data,\n data.tabs.filter((tab) => tab.id !== regionId),\n );\n}\n\nfunction reorderTabRegion(\n data: TabsData,\n fromRegionId: string,\n toRegionId: string,\n): TabsData {\n const fromIndex = data.tabs.findIndex((tab) => tab.id === fromRegionId);\n const toIndex = data.tabs.findIndex((tab) => tab.id === toRegionId);\n if (fromIndex < 0 || toIndex < 0 || fromIndex === toIndex) return data;\n const next = [...data.tabs];\n const [moved] = next.splice(fromIndex, 1);\n if (!moved) return data;\n next.splice(toIndex, 0, moved);\n return tabsWith(data, next);\n}\n\n/**\n * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in\n * their browser registry. The schema + MDX config come from `./tabs.config.ts`,\n * the exact same object server / agent code registers, so rendering and source\n * round-trip never drift.\n */\nexport const tabsBlock = defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: TabsBlockReader,\n Edit: TabsBlockEditor,\n placement: [\"block\", \"inline\"],\n editSurface: \"container\",\n container: {\n regions: tabRegions,\n updateRegion: (data, regionId, blocks) =>\n tabsWith(\n data,\n data.tabs.map((tab) =>\n tab.id === regionId ? { ...tab, blocks } : tab,\n ),\n ),\n addRegion: addTabRegion,\n removeRegion: removeTabRegion,\n reorderRegion: reorderTabRegion,\n },\n label: \"Tabs\",\n icon: IconLayoutNavbar,\n description:\n \"A top or side tab container; each tab holds its own list of blocks.\",\n empty: () => ({ tabs: [{ id: newTabId(), label: \"Tab 1\", blocks: [] }] }),\n});\n"]}
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../../src/client/blocks/library/tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from \"react\";\nimport {\n IconLayoutNavbar,\n IconPencil,\n IconPlus,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../../components/ui/popover.js\";\nimport { defineBlock } from \"../types.js\";\nimport type {\n BlockContainerRegion,\n BlockReadProps,\n BlockEditProps,\n NestedBlock,\n} from \"../types.js\";\nimport {\n tabsSchema,\n tabsMdx,\n type TabsData,\n type TabsOrientation,\n type TabsTab,\n} from \"./tabs.config.js\";\nimport { NarrowContainerProvider } from \"./narrow-container.js\";\n\n/**\n * Standard `tabs` block: a horizontal pill-tab container whose tabs each hold a\n * list of child blocks. Lives in core so any app (plan today, content later) can\n * register it.\n *\n * `Read`/`Edit` mirror the legacy plan `TabsBlock` markup byte-for-byte (same\n * `plan-block` section, the `inline-flex` pill tab rail with `role=\"tablist\"`/\n * `role=\"tab\"`, the same active-tab `useState`, and the `compactVisuals`\n * heuristic on the block title) so converting the block to the registry does not\n * change rendered output. The block chrome uses semantic shadcn tokens so the\n * same renderer stays quiet in both the plan and content apps.\n *\n * Child rendering flows through `ctx.renderBlock` — the app's own block\n * dispatcher — so registered children render via their spec and unconverted\n * children fall through the app's legacy switch. This is the coexistence seam:\n * the core tabs block never has to know app-specific child block types.\n */\n\n/** Mint a reasonably-unique tab id without pulling a dep into core. */\nfunction newTabId(): string {\n return `tab-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Compact embedded visuals for dense tab panes, matching legacy behavior. */\nfunction isCompact(title: string | undefined): boolean {\n return /interaction|component|note/i.test(title ?? \"\");\n}\n\nconst tabSettingsInputClass =\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction tabOrientation(data: Pick<TabsData, \"orientation\">): TabsOrientation {\n return data.orientation === \"vertical\" ? \"vertical\" : \"horizontal\";\n}\n\nfunction tabsWith(data: TabsData, tabs: TabsTab[]): TabsData {\n return { ...data, tabs };\n}\n\nfunction tabButtonClass(\n selected: boolean,\n orientation: TabsOrientation,\n): string {\n return cn(\n \"rounded-lg border border-transparent text-sm font-semibold transition-colors\",\n orientation === \"vertical\"\n ? \"min-w-0 max-w-72 shrink-0 px-3 py-2 text-left @xl/tabs:w-full @xl/tabs:max-w-none\"\n : \"shrink-0 whitespace-nowrap px-4 py-2\",\n selected\n ? \"bg-primary/5 text-foreground dark:bg-primary/10\"\n : \"text-muted-foreground hover:bg-muted/40 hover:text-foreground\",\n );\n}\n\nfunction tabLabelClass(orientation: TabsOrientation): string | undefined {\n return orientation === \"vertical\" ? \"block min-w-0 truncate\" : undefined;\n}\n\n/** Shared pill-tab rail. */\nfunction TabRail({\n tabs,\n activeId,\n onSelect,\n orientation,\n}: {\n tabs: TabsTab[];\n activeId: string | undefined;\n onSelect: (id: string) => void;\n orientation: TabsOrientation;\n}) {\n const vertical = orientation === \"vertical\";\n return (\n <div\n className={cn(\n vertical\n ? \"mb-5 flex w-full min-w-0 max-w-full flex-nowrap gap-1 overflow-x-auto @xl/tabs:mb-0 @xl/tabs:max-h-[62vh] @xl/tabs:flex-col @xl/tabs:overflow-x-hidden @xl/tabs:overflow-y-auto @xl/tabs:pr-2\"\n : \"mb-8 flex w-full min-w-0 max-w-full flex-nowrap gap-1 overflow-x-auto\",\n )}\n role=\"tablist\"\n aria-orientation={orientation}\n data-plan-interactive\n >\n {tabs.map((tab) => {\n const selected = tab.id === activeId;\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => onSelect(tab.id)}\n className={tabButtonClass(selected, orientation)}\n >\n <span className={tabLabelClass(orientation)}>{tab.label}</span>\n </button>\n );\n })}\n </div>\n );\n}\n\n/** Read renderer: pill tabs, child blocks rendered read-only via the app. */\nexport function TabsBlockReader({\n data,\n blockId,\n title,\n ctx,\n}: BlockReadProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n const orientation = tabOrientation(data);\n const vertical = orientation === \"vertical\";\n return (\n <section className=\"plan-block\" data-block-id={blockId}>\n {title && <div className=\"plan-block-label\">{title}</div>}\n <div className={cn(vertical && \"@container/tabs\")}>\n <div\n className={cn(\n vertical &&\n \"grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start\",\n )}\n >\n <TabRail\n tabs={data.tabs}\n activeId={active?.id}\n onSelect={setActiveId}\n orientation={orientation}\n />\n {active &&\n (vertical ? (\n <NarrowContainerProvider>\n <div className=\"min-w-0\">\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: false,\n compactVisuals: compact,\n })}\n </div>\n ))}\n </div>\n </NarrowContainerProvider>\n ) : (\n <div>\n {active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: false,\n compactVisuals: compact,\n })}\n </div>\n ))}\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n\n/**\n * Editor: pill tabs plus tab management (add/remove/rename), with child blocks\n * rendered editable in place through the app dispatcher. A child change updates\n * that child within its tab and commits the whole tabs block — mirroring the\n * legacy `TabsBlock` onChange bubbling so the plan's recursive `updateBlocks`/\n * `findBlock` (`PlanContentRenderer`) keeps working unchanged.\n */\nexport function TabsBlockEditor({\n data,\n onChange,\n editable,\n blockId,\n title,\n ctx,\n}: BlockEditProps<TabsData>) {\n const [activeId, setActiveId] = useState(data.tabs[0]?.id ?? \"\");\n const active = data.tabs.find((tab) => tab.id === activeId) ?? data.tabs[0];\n const compact = isCompact(title);\n const orientation = tabOrientation(data);\n const vertical = orientation === \"vertical\";\n\n const commit = (tabs: TabsTab[]) => onChange(tabsWith(data, tabs));\n\n const setOrientation = (next: TabsOrientation) =>\n onChange({\n ...data,\n orientation: next === \"vertical\" ? \"vertical\" : undefined,\n });\n\n const renameTab = (id: string, label: string) =>\n commit(data.tabs.map((tab) => (tab.id === id ? { ...tab, label } : tab)));\n\n const removeTab = (id: string) => {\n const next = data.tabs.filter((tab) => tab.id !== id);\n if (next.length === 0) return; // tabs must keep at least one (schema min 1)\n commit(next);\n if (activeId === id) setActiveId(next[0]?.id ?? \"\");\n };\n\n const addTab = () => {\n if (data.tabs.length >= 12) return; // schema max\n const id = newTabId();\n commit([\n ...data.tabs,\n { id, label: `Tab ${data.tabs.length + 1}`, blocks: [] },\n ]);\n setActiveId(id);\n };\n\n const updateChild = (tabId: string, child: NestedBlock) =>\n commit(\n data.tabs.map((tab) =>\n tab.id === tabId\n ? {\n ...tab,\n blocks: tab.blocks.map((existing) =>\n existing.id === child.id ? child : existing,\n ),\n }\n : tab,\n ),\n );\n\n // Renders BARE (no `plan-block` section / title): in edit mode the app's\n // block dispatcher already wraps registered editors in a titled `plan-block`\n // section, so wrapping again here would double-nest. The read renderer\n // (`TabsBlockReader`) owns its own section because read mode renders the spec\n // directly.\n return (\n <div\n className={cn(\"min-w-0\", vertical && \"@container/tabs\")}\n data-tabs-edit-block={blockId}\n >\n <div\n className={cn(\n vertical &&\n \"grid min-w-0 gap-5 @xl/tabs:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)] @xl/tabs:items-start\",\n )}\n >\n <div\n className={cn(\n \"flex min-w-0 items-start gap-2\",\n vertical ? \"mb-5 @xl/tabs:mb-0\" : \"mb-8 w-full\",\n )}\n >\n <div\n className={cn(\n \"flex min-w-0 flex-1 gap-1\",\n vertical\n ? \"flex-nowrap overflow-x-auto @xl/tabs:max-h-[62vh] @xl/tabs:flex-col @xl/tabs:overflow-x-hidden @xl/tabs:overflow-y-auto @xl/tabs:pr-2\"\n : \"w-full flex-nowrap items-center overflow-x-auto\",\n )}\n role=\"tablist\"\n aria-orientation={orientation}\n data-plan-interactive\n >\n {data.tabs.map((tab) => {\n const selected = tab.id === active?.id;\n const tabLabel = (\n <span className={tabLabelClass(orientation)}>{tab.label}</span>\n );\n if (!vertical) {\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={tabButtonClass(selected, orientation)}\n >\n {tabLabel}\n </button>\n );\n }\n const tabButton = (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n onClick={() => setActiveId(tab.id)}\n className={cn(\n tabButtonClass(selected, orientation),\n vertical && editable && selected && \"pr-9\",\n )}\n >\n {tabLabel}\n </button>\n );\n return (\n <div\n key={tab.id}\n className=\"group/tab relative flex min-w-0 max-w-72 shrink-0 @xl/tabs:w-full @xl/tabs:max-w-none\"\n >\n {tabButton}\n {editable && selected && (\n <TabsSettingsPopover\n active={active}\n orientation={orientation}\n tabs={data.tabs}\n triggerClassName=\"pointer-events-none absolute right-1.5 top-1/2 -translate-y-1/2 opacity-0 transition-opacity group-hover/tab:pointer-events-auto group-hover/tab:opacity-100 group-focus-within/tab:pointer-events-auto group-focus-within/tab:opacity-100 data-[state=open]:pointer-events-auto data-[state=open]:opacity-100\"\n onRename={renameTab}\n onOrientationChange={setOrientation}\n onAdd={addTab}\n onRemove={removeTab}\n />\n )}\n </div>\n );\n })}\n </div>\n {editable && !vertical && (\n <TabsSettingsPopover\n active={active}\n orientation={orientation}\n tabs={data.tabs}\n onRename={renameTab}\n onOrientationChange={setOrientation}\n onAdd={addTab}\n onRemove={removeTab}\n />\n )}\n </div>\n {active && (\n <div className={cn(vertical && \"min-w-0\")}>\n {ctx.renderBlocksEditor\n ? ctx.renderBlocksEditor({\n blocks: active.blocks,\n onChange: (nextBlocks) =>\n onChange(\n {\n ...data,\n tabs: data.tabs.map((tab) =>\n tab.id === active.id\n ? { ...tab, blocks: nextBlocks }\n : tab,\n ),\n },\n {\n containerRegion: {\n regionId: active.id,\n blocks: nextBlocks,\n },\n },\n ),\n editable,\n containerBlockId: blockId,\n regionId: active.id,\n regionLabel: active.label,\n compactVisuals: compact,\n })\n : active.blocks.map((child) => (\n <div key={child.id}>\n {ctx.renderBlock?.({\n block: child,\n editing: true,\n compactVisuals: compact,\n onChange: (next) => updateChild(active.id, next),\n })}\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction TabsSettingsPopover({\n active,\n orientation,\n tabs,\n onRename,\n onOrientationChange,\n onAdd,\n onRemove,\n triggerClassName,\n}: {\n active: TabsTab | undefined;\n orientation: TabsOrientation;\n tabs: TabsTab[];\n onRename: (id: string, label: string) => void;\n onOrientationChange: (orientation: TabsOrientation) => void;\n onAdd: () => void;\n onRemove: (id: string) => void;\n triggerClassName?: string;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n data-plan-interactive\n aria-label=\"Edit tabs\"\n className={cn(\n \"flex size-8 shrink-0 items-center justify-center rounded-md text-plan-muted transition-colors hover:text-plan-text focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n triggerClassName,\n )}\n >\n <IconPencil className=\"size-4\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n side=\"bottom\"\n className=\"w-80 p-0\"\n data-plan-interactive\n >\n <div className=\"border-b border-border px-3 py-2\">\n <div className=\"text-sm font-semibold text-foreground\">\n Tab settings\n </div>\n <div className=\"text-xs text-muted-foreground\">\n Rename the active tab, change layout, or manage the tab set.\n </div>\n </div>\n <div className=\"grid gap-3 p-3\">\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Active tab label\n </span>\n <input\n type=\"text\"\n data-plan-interactive\n className={tabSettingsInputClass}\n value={active?.label ?? \"\"}\n disabled={!active}\n onChange={(event) => {\n if (!active) return;\n onRename(active.id, event.target.value);\n }}\n />\n </label>\n <label className=\"grid gap-1.5\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Layout\n </span>\n <div\n className=\"grid grid-cols-2 gap-1 rounded-md border border-border bg-muted/30 p-1\"\n role=\"radiogroup\"\n aria-label=\"Tabs layout\"\n >\n {(\n [\n [\"horizontal\", \"Top\"],\n [\"vertical\", \"Side\"],\n ] satisfies Array<[TabsOrientation, string]>\n ).map(([value, label]) => {\n const selected = orientation === value;\n return (\n <button\n key={value}\n type=\"button\"\n role=\"radio\"\n aria-checked={selected}\n data-plan-interactive\n onClick={() => onOrientationChange(value)}\n className={cn(\n \"h-8 rounded px-2 text-xs font-medium transition-colors\",\n selected\n ? \"bg-background text-foreground\"\n : \"text-muted-foreground hover:bg-background/70 hover:text-foreground\",\n )}\n >\n {label}\n </button>\n );\n })}\n </div>\n </label>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-plan-interactive\n disabled={tabs.length >= 12}\n onClick={onAdd}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition-colors hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconPlus className=\"size-3.5\" />\n Add tab\n </button>\n <button\n type=\"button\"\n data-plan-interactive\n disabled={!active || tabs.length <= 1}\n onClick={() => {\n if (!active) return;\n onRemove(active.id);\n }}\n className=\"inline-flex h-8 items-center gap-1.5 rounded-md border border-border px-2.5 text-xs font-medium text-destructive transition-colors hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <IconTrash className=\"size-3.5\" />\n Remove current\n </button>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction tabRegions(data: TabsData): BlockContainerRegion[] {\n return data.tabs.map((tab) => ({\n id: tab.id,\n label: tab.label,\n blocks: tab.blocks,\n }));\n}\n\nfunction addTabRegion(data: TabsData, afterRegionId?: string): TabsData {\n if (data.tabs.length >= 12) return data;\n const nextTab: TabsTab = {\n id: newTabId(),\n label: `Tab ${data.tabs.length + 1}`,\n blocks: [],\n };\n if (!afterRegionId) return tabsWith(data, [...data.tabs, nextTab]);\n const afterIndex = data.tabs.findIndex((tab) => tab.id === afterRegionId);\n if (afterIndex < 0) return tabsWith(data, [...data.tabs, nextTab]);\n return tabsWith(data, [\n ...data.tabs.slice(0, afterIndex + 1),\n nextTab,\n ...data.tabs.slice(afterIndex + 1),\n ]);\n}\n\nfunction removeTabRegion(data: TabsData, regionId: string): TabsData {\n if (data.tabs.length <= 1) return data;\n return tabsWith(\n data,\n data.tabs.filter((tab) => tab.id !== regionId),\n );\n}\n\nfunction reorderTabRegion(\n data: TabsData,\n fromRegionId: string,\n toRegionId: string,\n): TabsData {\n const fromIndex = data.tabs.findIndex((tab) => tab.id === fromRegionId);\n const toIndex = data.tabs.findIndex((tab) => tab.id === toRegionId);\n if (fromIndex < 0 || toIndex < 0 || fromIndex === toIndex) return data;\n const next = [...data.tabs];\n const [moved] = next.splice(fromIndex, 1);\n if (!moved) return data;\n next.splice(toIndex, 0, moved);\n return tabsWith(data, next);\n}\n\n/**\n * The standard tabs block spec (with React `Read`/`Edit`). Apps register this in\n * their browser registry. The schema + MDX config come from `./tabs.config.ts`,\n * the exact same object server / agent code registers, so rendering and source\n * round-trip never drift.\n */\nexport const tabsBlock = defineBlock<TabsData>({\n type: \"tabs\",\n schema: tabsSchema,\n mdx: tabsMdx,\n Read: TabsBlockReader,\n Edit: TabsBlockEditor,\n placement: [\"block\", \"inline\"],\n editSurface: \"container\",\n container: {\n regions: tabRegions,\n updateRegion: (data, regionId, blocks) =>\n tabsWith(\n data,\n data.tabs.map((tab) =>\n tab.id === regionId ? { ...tab, blocks } : tab,\n ),\n ),\n addRegion: addTabRegion,\n removeRegion: removeTabRegion,\n reorderRegion: reorderTabRegion,\n },\n label: \"Tabs\",\n icon: IconLayoutNavbar,\n description:\n \"A top or side tab container; each tab holds its own list of blocks.\",\n empty: () => ({ tabs: [{ id: newTabId(), label: \"Tab 1\", blocks: [] }] }),\n});\n"]}
@@ -179,6 +179,8 @@ export interface BlockRenderContext {
179
179
  onOpenChange?: (open: boolean) => void;
180
180
  trigger: React.ReactNode;
181
181
  children: React.ReactNode;
182
+ /** Compact action menus omit host block-edit chrome such as edit-by-prompt. */
183
+ variant?: "panel" | "menu";
182
184
  /** Metadata for host-provided contextual controls such as the edit-by-prompt CTA. */
183
185
  blockId?: string;
184
186
  blockType?: string;