@agent-native/core 0.79.27 → 0.80.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 (346) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +26 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
  4. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
  5. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
  6. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
  7. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
  8. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
  9. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
  10. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
  11. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
  12. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
  13. package/corpus/core/docs/content/template-design.mdx +45 -0
  14. package/corpus/core/package.json +2 -1
  15. package/corpus/core/src/agent/engine/index.ts +1 -0
  16. package/corpus/core/src/agent/engine/registry.ts +40 -0
  17. package/corpus/core/src/agent/production-agent.ts +6 -2
  18. package/corpus/core/src/cli/design-connect.ts +490 -0
  19. package/corpus/core/src/cli/index.ts +16 -0
  20. package/corpus/core/src/cli/skills.ts +126 -3
  21. package/corpus/core/src/client/AssistantChat.tsx +43 -7
  22. package/corpus/core/src/client/agent-chat.ts +27 -3
  23. package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
  24. package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
  25. package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
  26. package/corpus/core/src/client/chat/message-components.tsx +1 -1
  27. package/corpus/core/src/client/chat-model-groups.ts +1 -2
  28. package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
  29. package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
  30. package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
  31. package/corpus/core/src/client/frame-protocol.ts +17 -2
  32. package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
  33. package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
  34. package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
  35. package/corpus/core/src/server/transcribe-voice.ts +57 -22
  36. package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
  37. package/corpus/core/src/styles/agent-native.css +56 -7
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  39. package/corpus/core/src/vite/client.ts +2 -0
  40. package/corpus/core/src/voice/index.ts +18 -0
  41. package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
  42. package/corpus/core/src/voice/voice-context.ts +217 -0
  43. package/corpus/core/src/voice/voice-replacements.ts +75 -0
  44. package/corpus/templates/analytics/AGENTS.md +4 -3
  45. package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
  46. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
  47. package/corpus/templates/analytics/app/global.css +0 -4
  48. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  49. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  50. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
  51. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
  52. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
  53. package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
  54. package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
  55. package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  56. package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
  57. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
  58. package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
  59. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
  60. package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
  61. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
  62. package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  63. package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
  64. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
  65. package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
  66. package/corpus/templates/brain/app/i18n-data.ts +20 -0
  67. package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  68. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
  69. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
  70. package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
  71. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  72. package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  73. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
  74. package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  75. package/corpus/templates/clips/AGENTS.md +4 -0
  76. package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
  77. package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
  78. package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
  79. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  80. package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
  81. package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
  82. package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  83. package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
  84. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
  85. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
  86. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
  87. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
  88. package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  89. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
  90. package/corpus/templates/design/AGENTS.md +95 -5
  91. package/corpus/templates/design/DESIGN.md +82 -0
  92. package/corpus/templates/design/DEVELOPING.md +43 -0
  93. package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
  94. package/corpus/templates/design/actions/apply-shader.ts +277 -0
  95. package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
  96. package/corpus/templates/design/actions/connect-localhost.ts +183 -0
  97. package/corpus/templates/design/actions/edit-design.ts +195 -42
  98. package/corpus/templates/design/actions/generate-design.ts +71 -1
  99. package/corpus/templates/design/actions/generate-screens.ts +193 -0
  100. package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
  101. package/corpus/templates/design/actions/get-shader.ts +119 -0
  102. package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
  103. package/corpus/templates/design/actions/navigate.ts +55 -2
  104. package/corpus/templates/design/actions/view-screen.ts +68 -1
  105. package/corpus/templates/design/agent-native.app-skill.json +10 -0
  106. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
  107. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
  108. package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
  109. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
  110. package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
  111. package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
  112. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
  113. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
  114. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
  115. package/corpus/templates/design/app/components/design/index.ts +0 -5
  116. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
  117. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
  118. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
  119. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
  120. package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
  121. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
  122. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
  123. package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
  124. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
  125. package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
  126. package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
  127. package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
  128. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
  129. package/corpus/templates/design/app/components/design/types.ts +23 -0
  130. package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
  131. package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
  132. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
  133. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
  134. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
  135. package/corpus/templates/design/app/global.css +121 -3
  136. package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
  137. package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
  138. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
  139. package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
  140. package/corpus/templates/design/app/i18n-data.ts +2790 -1
  141. package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
  142. package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
  144. package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
  145. package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
  146. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
  147. package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
  148. package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
  149. package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  150. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
  151. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
  152. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
  153. package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
  154. package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
  155. package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
  156. package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
  157. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
  158. package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
  159. package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
  160. package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
  161. package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
  162. package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
  163. package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
  164. package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
  165. package/corpus/templates/design/package.json +1 -0
  166. package/corpus/templates/design/server/db/schema.ts +26 -0
  167. package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
  168. package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
  169. package/corpus/templates/design/shared/api.ts +27 -0
  170. package/corpus/templates/design/shared/canvas-frames.ts +103 -0
  171. package/corpus/templates/design/shared/canvas-math.ts +1058 -0
  172. package/corpus/templates/design/shared/code-layer.ts +2212 -0
  173. package/corpus/templates/design/shared/color-utils.ts +180 -0
  174. package/corpus/templates/design/shared/generation-session.ts +61 -0
  175. package/corpus/templates/design/shared/shader-presets.ts +782 -0
  176. package/corpus/templates/design/shared/shader-safety.ts +137 -0
  177. package/corpus/templates/design/shared/source-mode.ts +237 -0
  178. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
  179. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  180. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  181. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  182. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  183. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  184. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  185. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  186. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  187. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  188. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  189. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  190. package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  191. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
  192. package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
  193. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
  194. package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
  195. package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
  196. package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
  197. package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
  198. package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
  199. package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
  200. package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
  201. package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
  202. package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
  203. package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
  204. package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
  205. package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  206. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
  207. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
  208. package/corpus/templates/plan/app/global.css +61 -78
  209. package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
  210. package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  211. package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
  212. package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
  213. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
  214. package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  215. package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
  216. package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
  217. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
  218. package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
  219. package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
  220. package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
  221. package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
  222. package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
  223. package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
  224. package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
  225. package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
  226. package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
  227. package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
  228. package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
  229. package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
  230. package/dist/agent/engine/index.d.ts +1 -1
  231. package/dist/agent/engine/index.d.ts.map +1 -1
  232. package/dist/agent/engine/index.js +1 -1
  233. package/dist/agent/engine/index.js.map +1 -1
  234. package/dist/agent/engine/registry.d.ts +9 -0
  235. package/dist/agent/engine/registry.d.ts.map +1 -1
  236. package/dist/agent/engine/registry.js +37 -0
  237. package/dist/agent/engine/registry.js.map +1 -1
  238. package/dist/agent/production-agent.d.ts.map +1 -1
  239. package/dist/agent/production-agent.js +4 -3
  240. package/dist/agent/production-agent.js.map +1 -1
  241. package/dist/cli/design-connect.d.ts +52 -0
  242. package/dist/cli/design-connect.d.ts.map +1 -0
  243. package/dist/cli/design-connect.js +409 -0
  244. package/dist/cli/design-connect.js.map +1 -0
  245. package/dist/cli/index.js +15 -0
  246. package/dist/cli/index.js.map +1 -1
  247. package/dist/cli/skills.d.ts +3 -0
  248. package/dist/cli/skills.d.ts.map +1 -1
  249. package/dist/cli/skills.js +121 -3
  250. package/dist/cli/skills.js.map +1 -1
  251. package/dist/client/AssistantChat.d.ts.map +1 -1
  252. package/dist/client/AssistantChat.js +38 -8
  253. package/dist/client/AssistantChat.js.map +1 -1
  254. package/dist/client/agent-chat.d.ts +6 -0
  255. package/dist/client/agent-chat.d.ts.map +1 -1
  256. package/dist/client/agent-chat.js +17 -3
  257. package/dist/client/agent-chat.js.map +1 -1
  258. package/dist/client/blocks/library/MermaidBlock.js +1 -1
  259. package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
  260. package/dist/client/blocks/library/diagram.js +1 -1
  261. package/dist/client/blocks/library/diagram.js.map +1 -1
  262. package/dist/client/blocks/library/wireframe.js +1 -1
  263. package/dist/client/blocks/library/wireframe.js.map +1 -1
  264. package/dist/client/chat/message-components.js +1 -1
  265. package/dist/client/chat/message-components.js.map +1 -1
  266. package/dist/client/chat-model-groups.d.ts.map +1 -1
  267. package/dist/client/chat-model-groups.js +1 -2
  268. package/dist/client/chat-model-groups.js.map +1 -1
  269. package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
  270. package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
  271. package/dist/client/components/LiveCursorOverlay.js +19 -40
  272. package/dist/client/components/LiveCursorOverlay.js.map +1 -1
  273. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  274. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  275. package/dist/client/composer/TiptapComposer.js +86 -24
  276. package/dist/client/composer/TiptapComposer.js.map +1 -1
  277. package/dist/client/composer/useVoiceDictation.d.ts +9 -0
  278. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  279. package/dist/client/composer/useVoiceDictation.js +154 -32
  280. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  281. package/dist/client/frame-protocol.d.ts +17 -2
  282. package/dist/client/frame-protocol.d.ts.map +1 -1
  283. package/dist/client/frame-protocol.js.map +1 -1
  284. package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
  285. package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
  286. package/dist/client/sharing/ShareButton.d.ts +2 -0
  287. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  288. package/dist/client/sharing/ShareButton.js +7 -6
  289. package/dist/client/sharing/ShareButton.js.map +1 -1
  290. package/dist/client/use-agent-engine-configured.d.ts +5 -0
  291. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  292. package/dist/client/use-agent-engine-configured.js +51 -25
  293. package/dist/client/use-agent-engine-configured.js.map +1 -1
  294. package/dist/collab/awareness.d.ts +2 -2
  295. package/dist/collab/awareness.d.ts.map +1 -1
  296. package/dist/collab/routes.d.ts +1 -1
  297. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  298. package/dist/notifications/routes.d.ts +3 -3
  299. package/dist/observability/routes.d.ts +8 -8
  300. package/dist/progress/routes.d.ts +1 -1
  301. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  302. package/dist/server/transcribe-voice.d.ts.map +1 -1
  303. package/dist/server/transcribe-voice.js +40 -24
  304. package/dist/server/transcribe-voice.js.map +1 -1
  305. package/dist/shared/mcp-embed-headers.d.ts +1 -0
  306. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  307. package/dist/shared/mcp-embed-headers.js +20 -1
  308. package/dist/shared/mcp-embed-headers.js.map +1 -1
  309. package/dist/styles/agent-native.css +56 -7
  310. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  311. package/dist/vite/client.d.ts.map +1 -1
  312. package/dist/vite/client.js +2 -0
  313. package/dist/vite/client.js.map +1 -1
  314. package/dist/voice/index.d.ts +5 -0
  315. package/dist/voice/index.d.ts.map +1 -0
  316. package/dist/voice/index.js +4 -0
  317. package/dist/voice/index.js.map +1 -0
  318. package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
  319. package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
  320. package/dist/voice/voice-cleanup-prompt.js +26 -0
  321. package/dist/voice/voice-cleanup-prompt.js.map +1 -0
  322. package/dist/voice/voice-context.d.ts +25 -0
  323. package/dist/voice/voice-context.d.ts.map +1 -0
  324. package/dist/voice/voice-context.js +156 -0
  325. package/dist/voice/voice-context.js.map +1 -0
  326. package/dist/voice/voice-replacements.d.ts +4 -0
  327. package/dist/voice/voice-replacements.d.ts.map +1 -0
  328. package/dist/voice/voice-replacements.js +52 -0
  329. package/dist/voice/voice-replacements.js.map +1 -0
  330. package/docs/content/locales/ar-SA/template-design.mdx +41 -0
  331. package/docs/content/locales/de-DE/template-design.mdx +51 -0
  332. package/docs/content/locales/es-ES/template-design.mdx +50 -0
  333. package/docs/content/locales/fr-FR/template-design.mdx +49 -0
  334. package/docs/content/locales/hi-IN/template-design.mdx +44 -0
  335. package/docs/content/locales/ja-JP/template-design.mdx +46 -0
  336. package/docs/content/locales/ko-KR/template-design.mdx +44 -0
  337. package/docs/content/locales/pt-BR/template-design.mdx +48 -0
  338. package/docs/content/locales/zh-CN/template-design.mdx +36 -0
  339. package/docs/content/locales/zh-TW/template-design.mdx +38 -0
  340. package/docs/content/template-design.mdx +45 -0
  341. package/package.json +2 -1
  342. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
  343. package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
  344. package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
  345. package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
  346. package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
@@ -0,0 +1,699 @@
1
+ import {
2
+ IconArrowBackUp,
3
+ IconArrowsDiagonal,
4
+ IconLink,
5
+ IconUnlink,
6
+ } from "@tabler/icons-react";
7
+ import type { ReactNode } from "react";
8
+
9
+ import { Button } from "@/components/ui/button";
10
+ import { Checkbox } from "@/components/ui/checkbox";
11
+ import {
12
+ DropdownMenu,
13
+ DropdownMenuContent,
14
+ DropdownMenuItem,
15
+ DropdownMenuTrigger,
16
+ } from "@/components/ui/dropdown-menu";
17
+ import {
18
+ Tooltip,
19
+ TooltipContent,
20
+ TooltipProvider,
21
+ TooltipTrigger,
22
+ } from "@/components/ui/tooltip";
23
+ import { cn } from "@/lib/utils";
24
+
25
+ import {
26
+ AlignmentMatrix,
27
+ type AlignmentMatrixValue,
28
+ type DistributionAxis,
29
+ } from "./AlignmentMatrix";
30
+ import {
31
+ IconFlowGrid,
32
+ IconFlowHorizontal,
33
+ IconFlowVertical,
34
+ IconFlowWrap,
35
+ IconGap,
36
+ IconLayoutSettings,
37
+ IconPaddingHorizontal,
38
+ IconPaddingVertical,
39
+ } from "./figma-icons";
40
+ import { ScrubInput } from "./ScrubInput";
41
+
42
+ export type AutoLayoutDirection = "horizontal" | "vertical";
43
+ export type AutoLayoutWrap = "nowrap" | "wrap";
44
+ export type AutoLayoutSizing = "hug" | "fill" | "fixed";
45
+ export type AutoLayoutSizingAxis = "horizontal" | "vertical";
46
+
47
+ export interface AutoLayoutPadding {
48
+ top: number;
49
+ right: number;
50
+ bottom: number;
51
+ left: number;
52
+ }
53
+
54
+ export interface AutoLayoutMatrixValue {
55
+ direction: AutoLayoutDirection;
56
+ wrap: AutoLayoutWrap;
57
+ alignment: AlignmentMatrixValue;
58
+ gap: number;
59
+ padding: AutoLayoutPadding;
60
+ paddingLinked: boolean;
61
+ clipContent?: boolean;
62
+ resolvedSize?: {
63
+ horizontal?: number;
64
+ vertical?: number;
65
+ };
66
+ childSizing: {
67
+ horizontal: AutoLayoutSizing;
68
+ vertical: AutoLayoutSizing;
69
+ };
70
+ }
71
+
72
+ export interface AutoLayoutMatrixLabels {
73
+ title: string;
74
+ alignment: string;
75
+ direction: string;
76
+ horizontal: string;
77
+ vertical: string;
78
+ wrap: string;
79
+ noWrap: string;
80
+ gap: string;
81
+ padding: string;
82
+ linkPadding: string;
83
+ unlinkPadding: string;
84
+ paddingTop: string;
85
+ paddingRight: string;
86
+ paddingBottom: string;
87
+ paddingLeft: string;
88
+ childSizing: string;
89
+ hug: string;
90
+ fill: string;
91
+ fixed: string;
92
+ clipContent: string;
93
+ }
94
+
95
+ export interface AutoLayoutMatrixProps {
96
+ value: AutoLayoutMatrixValue;
97
+ onDirectionChange: (direction: AutoLayoutDirection) => void;
98
+ onWrapChange: (wrap: AutoLayoutWrap) => void;
99
+ onAlignmentChange: (alignment: AlignmentMatrixValue) => void;
100
+ onGapChange: (gap: number) => void;
101
+ onPaddingChange: (padding: AutoLayoutPadding) => void;
102
+ onPaddingLinkedChange: (linked: boolean) => void;
103
+ onClipContentChange?: (clipContent: boolean) => void;
104
+ onDistribute?: (axis: DistributionAxis) => void;
105
+ onChildSizingChange: (
106
+ axis: AutoLayoutSizingAxis,
107
+ sizing: AutoLayoutSizing,
108
+ ) => void;
109
+ availableChildSizing?: Partial<
110
+ Record<AutoLayoutSizingAxis, AutoLayoutSizing[]>
111
+ >;
112
+ labels?: Partial<AutoLayoutMatrixLabels>;
113
+ disabled?: boolean;
114
+ className?: string;
115
+ }
116
+
117
+ const DEFAULT_LABELS: AutoLayoutMatrixLabels = {
118
+ title: "Auto layout", // i18n-ignore fallback component label
119
+ alignment: "Alignment", // i18n-ignore fallback component label
120
+ direction: "Direction", // i18n-ignore fallback component label
121
+ horizontal: "Horizontal", // i18n-ignore fallback component label
122
+ vertical: "Vertical", // i18n-ignore fallback component label
123
+ wrap: "Wrap", // i18n-ignore fallback component label
124
+ noWrap: "No wrap", // i18n-ignore fallback component label
125
+ gap: "Gap", // i18n-ignore fallback component label
126
+ padding: "Padding", // i18n-ignore fallback component label
127
+ linkPadding: "Link padding", // i18n-ignore fallback component label
128
+ unlinkPadding: "Unlink padding", // i18n-ignore fallback component label
129
+ paddingTop: "Top", // i18n-ignore fallback component label
130
+ paddingRight: "Right", // i18n-ignore fallback component label
131
+ paddingBottom: "Bottom", // i18n-ignore fallback component label
132
+ paddingLeft: "Left", // i18n-ignore fallback component label
133
+ childSizing: "Child sizing", // i18n-ignore fallback component label
134
+ hug: "Hug", // i18n-ignore fallback component label
135
+ fill: "Fill", // i18n-ignore fallback component label
136
+ fixed: "Fixed", // i18n-ignore fallback component label
137
+ clipContent: "Clip content", // i18n-ignore fallback component label
138
+ };
139
+
140
+ const SIZING_OPTIONS: AutoLayoutSizing[] = ["hug", "fill", "fixed"];
141
+
142
+ /** Derive the "active flow" option from direction + wrap state. */
143
+ function getFlowOption(
144
+ direction: AutoLayoutDirection,
145
+ wrap: AutoLayoutWrap,
146
+ ): "horizontal" | "vertical" | "wrap" | "grid" {
147
+ if (wrap === "wrap") return "wrap";
148
+ if (direction === "vertical") return "vertical";
149
+ return "horizontal";
150
+ }
151
+
152
+ export function AutoLayoutMatrix({
153
+ value,
154
+ onDirectionChange,
155
+ onWrapChange,
156
+ onAlignmentChange,
157
+ onGapChange,
158
+ onPaddingChange,
159
+ onPaddingLinkedChange,
160
+ onClipContentChange,
161
+ onDistribute,
162
+ onChildSizingChange,
163
+ availableChildSizing,
164
+ labels,
165
+ disabled = false,
166
+ className,
167
+ }: AutoLayoutMatrixProps) {
168
+ const copy = { ...DEFAULT_LABELS, ...labels };
169
+
170
+ const horizontalPaddingValue = Math.round(
171
+ (value.padding.left + value.padding.right) / 2,
172
+ );
173
+ const verticalPaddingValue = Math.round(
174
+ (value.padding.top + value.padding.bottom) / 2,
175
+ );
176
+
177
+ const activeFlow = getFlowOption(value.direction, value.wrap);
178
+
179
+ return (
180
+ <TooltipProvider delayDuration={250}>
181
+ <div className={cn("space-y-2", className)}>
182
+ {/* ── Flow ── */}
183
+ <div className="space-y-1.5">
184
+ <span className="text-[11px] font-medium text-muted-foreground">
185
+ {"Flow" /* i18n-ignore Figma inspector label */}
186
+ </span>
187
+ <div className="flex items-center gap-1.5">
188
+ {/* 4-segment flow bar: horizontal / vertical / wrap / grid */}
189
+ <div className="flex h-6 flex-1 overflow-hidden rounded-md bg-[var(--design-editor-control-bg)]">
190
+ <FlowButton
191
+ label={copy.horizontal}
192
+ active={activeFlow === "horizontal"}
193
+ disabled={disabled}
194
+ onClick={() => {
195
+ onDirectionChange("horizontal");
196
+ onWrapChange("nowrap");
197
+ }}
198
+ position="first"
199
+ >
200
+ <IconFlowHorizontal className="size-3.5" />
201
+ </FlowButton>
202
+ <FlowButton
203
+ label={copy.vertical}
204
+ active={activeFlow === "vertical"}
205
+ disabled={disabled}
206
+ onClick={() => {
207
+ onDirectionChange("vertical");
208
+ onWrapChange("nowrap");
209
+ }}
210
+ >
211
+ <IconFlowVertical className="size-3.5" />
212
+ </FlowButton>
213
+ <FlowButton
214
+ label={copy.wrap}
215
+ active={activeFlow === "wrap"}
216
+ disabled={disabled}
217
+ onClick={() => {
218
+ onDirectionChange("horizontal");
219
+ onWrapChange("wrap");
220
+ }}
221
+ >
222
+ <IconFlowWrap className="size-3.5" />
223
+ </FlowButton>
224
+ <FlowButton
225
+ label={"Grid" /* i18n-ignore Figma inspector label */}
226
+ active={activeFlow === "grid"}
227
+ disabled={disabled}
228
+ onClick={() => {
229
+ onDirectionChange("horizontal");
230
+ onWrapChange("wrap");
231
+ }}
232
+ position="last"
233
+ >
234
+ <IconFlowGrid className="size-3.5" />
235
+ </FlowButton>
236
+ </div>
237
+ {/* Reset button — same slot as before */}
238
+ <Tooltip>
239
+ <TooltipTrigger asChild>
240
+ <Button
241
+ type="button"
242
+ variant="ghost"
243
+ size="icon"
244
+ disabled={disabled}
245
+ aria-label={
246
+ "Reset auto layout flow" /* i18n-ignore inspector tooltip */
247
+ }
248
+ onClick={() => {
249
+ onDirectionChange("horizontal");
250
+ onWrapChange("nowrap");
251
+ }}
252
+ className="size-6 shrink-0 rounded-md text-muted-foreground hover:bg-[var(--design-editor-control-bg)] hover:text-foreground"
253
+ >
254
+ <IconArrowBackUp className="size-3.5" />
255
+ </Button>
256
+ </TooltipTrigger>
257
+ <TooltipContent>
258
+ {"Reset auto layout flow" /* i18n-ignore inspector tooltip */}
259
+ </TooltipContent>
260
+ </Tooltip>
261
+ </div>
262
+ </div>
263
+
264
+ {/* ── Resizing ── */}
265
+ <div className="space-y-1.5">
266
+ <span className="text-[11px] font-medium text-muted-foreground">
267
+ {"Resizing" /* i18n-ignore Figma inspector label */}
268
+ </span>
269
+ <div className="grid grid-cols-[1fr_1fr_1.5rem] items-center gap-1">
270
+ <SizingField
271
+ axis="W"
272
+ value={value.childSizing.horizontal}
273
+ resolvedSize={value.resolvedSize?.horizontal}
274
+ options={availableChildSizing?.horizontal ?? SIZING_OPTIONS}
275
+ labels={copy}
276
+ disabled={disabled}
277
+ onChange={(next) => onChildSizingChange("horizontal", next)}
278
+ />
279
+ <SizingField
280
+ axis="H"
281
+ value={value.childSizing.vertical}
282
+ resolvedSize={value.resolvedSize?.vertical}
283
+ options={availableChildSizing?.vertical ?? SIZING_OPTIONS}
284
+ labels={copy}
285
+ disabled={disabled}
286
+ onChange={(next) => onChildSizingChange("vertical", next)}
287
+ />
288
+ {/* Resize-to-fit icon button */}
289
+ <Tooltip>
290
+ <TooltipTrigger asChild>
291
+ <Button
292
+ type="button"
293
+ variant="ghost"
294
+ size="icon"
295
+ disabled={disabled}
296
+ aria-label={
297
+ "Resize to fit" /* i18n-ignore inspector tooltip */
298
+ }
299
+ onClick={() => {
300
+ onChildSizingChange("horizontal", "hug");
301
+ onChildSizingChange("vertical", "hug");
302
+ }}
303
+ className="size-6 rounded-md text-muted-foreground hover:bg-[var(--design-editor-control-bg)] hover:text-foreground"
304
+ >
305
+ <IconArrowsDiagonal className="size-3.5" />
306
+ </Button>
307
+ </TooltipTrigger>
308
+ <TooltipContent>
309
+ {"Resize to fit" /* i18n-ignore inspector tooltip */}
310
+ </TooltipContent>
311
+ </Tooltip>
312
+ </div>
313
+ </div>
314
+
315
+ {/* ── Alignment + Gap (two-column row) ── */}
316
+ <div className="grid grid-cols-[84px_1fr] items-start gap-2">
317
+ {/* Left: Alignment label + 3×3 matrix */}
318
+ <div className="space-y-1.5">
319
+ <span className="text-[11px] font-medium text-muted-foreground">
320
+ {"Alignment" /* i18n-ignore Figma inspector label */}
321
+ </span>
322
+ <AlignmentMatrix
323
+ value={value.alignment}
324
+ onChange={onAlignmentChange}
325
+ onDistribute={onDistribute}
326
+ disabled={disabled}
327
+ />
328
+ </div>
329
+
330
+ {/* Right: Gap label + input */}
331
+ <div className="space-y-1.5">
332
+ <span className="text-[11px] font-medium text-muted-foreground">
333
+ {copy.gap}
334
+ </span>
335
+ <div className="flex items-center gap-1">
336
+ {/* Gap scrub input with ]·[ icon */}
337
+ <div className="min-w-0 flex-1">
338
+ <ScrubInput
339
+ label={copy.gap}
340
+ ariaLabel={copy.gap}
341
+ value={value.gap}
342
+ onChange={(next) => onGapChange(next)}
343
+ icon={IconGap}
344
+ unit="px"
345
+ min={0}
346
+ step={1}
347
+ precision={1}
348
+ disabled={disabled}
349
+ labelClassName="w-5 shrink-0 [&>span]:hidden"
350
+ inputClassName="h-6 text-[11px]"
351
+ />
352
+ </div>
353
+ {/* Gap options / layout settings button */}
354
+ <Tooltip>
355
+ <TooltipTrigger asChild>
356
+ <Button
357
+ type="button"
358
+ variant="ghost"
359
+ size="icon"
360
+ disabled={disabled}
361
+ aria-label={
362
+ "Layout settings" /* i18n-ignore inspector tooltip */
363
+ }
364
+ className="size-6 shrink-0 rounded-md text-muted-foreground hover:bg-[var(--design-editor-control-bg)] hover:text-foreground"
365
+ >
366
+ <IconLayoutSettings className="size-3.5" />
367
+ </Button>
368
+ </TooltipTrigger>
369
+ <TooltipContent>
370
+ {"Layout settings" /* i18n-ignore inspector tooltip */}
371
+ </TooltipContent>
372
+ </Tooltip>
373
+ </div>
374
+ </div>
375
+ </div>
376
+
377
+ {/* ── Padding ── */}
378
+ <div className="space-y-1.5">
379
+ <span className="text-[11px] font-medium text-muted-foreground">
380
+ {copy.padding}
381
+ </span>
382
+ <div className="grid grid-cols-[1fr_1fr_1.5rem] items-center gap-1">
383
+ {/* Horizontal padding (left + right) */}
384
+ <ScrubInput
385
+ label={copy.padding}
386
+ ariaLabel={copy.paddingLeft + " / " + copy.paddingRight}
387
+ value={
388
+ value.paddingLinked ? value.padding.top : horizontalPaddingValue
389
+ }
390
+ onChange={(next) => {
391
+ if (value.paddingLinked) {
392
+ onPaddingChange({
393
+ top: next,
394
+ right: next,
395
+ bottom: next,
396
+ left: next,
397
+ });
398
+ return;
399
+ }
400
+ onPaddingChange({
401
+ ...value.padding,
402
+ left: next,
403
+ right: next,
404
+ });
405
+ }}
406
+ icon={IconPaddingHorizontal}
407
+ unit="px"
408
+ min={0}
409
+ step={1}
410
+ precision={1}
411
+ disabled={disabled}
412
+ labelClassName="w-5 shrink-0 [&>span]:hidden"
413
+ inputClassName="h-6 text-[11px]"
414
+ />
415
+ {/* Vertical padding (top + bottom) */}
416
+ <ScrubInput
417
+ label={copy.padding}
418
+ ariaLabel={copy.paddingTop + " / " + copy.paddingBottom}
419
+ value={
420
+ value.paddingLinked ? value.padding.top : verticalPaddingValue
421
+ }
422
+ onChange={(next) => {
423
+ if (value.paddingLinked) {
424
+ onPaddingChange({
425
+ top: next,
426
+ right: next,
427
+ bottom: next,
428
+ left: next,
429
+ });
430
+ return;
431
+ }
432
+ onPaddingChange({
433
+ ...value.padding,
434
+ top: next,
435
+ bottom: next,
436
+ });
437
+ }}
438
+ icon={IconPaddingVertical}
439
+ unit="px"
440
+ min={0}
441
+ step={1}
442
+ precision={1}
443
+ disabled={disabled}
444
+ labelClassName="w-5 shrink-0 [&>span]:hidden"
445
+ inputClassName="h-6 text-[11px]"
446
+ />
447
+ {/* Link/unlink independent padding */}
448
+ <Tooltip>
449
+ <TooltipTrigger asChild>
450
+ <Button
451
+ type="button"
452
+ variant="ghost"
453
+ size="icon"
454
+ disabled={disabled}
455
+ aria-label={
456
+ value.paddingLinked ? copy.unlinkPadding : copy.linkPadding
457
+ }
458
+ onClick={() => onPaddingLinkedChange(!value.paddingLinked)}
459
+ className="size-6 rounded-md text-muted-foreground hover:bg-[var(--design-editor-control-bg)] hover:text-foreground"
460
+ >
461
+ {value.paddingLinked ? (
462
+ <IconLink className="size-3.5" />
463
+ ) : (
464
+ <IconUnlink className="size-3.5" />
465
+ )}
466
+ </Button>
467
+ </TooltipTrigger>
468
+ <TooltipContent>
469
+ {value.paddingLinked ? copy.unlinkPadding : copy.linkPadding}
470
+ </TooltipContent>
471
+ </Tooltip>
472
+ </div>
473
+
474
+ {/* Expanded 4-field padding when unlinked */}
475
+ {!value.paddingLinked && (
476
+ <div className="mt-1 grid grid-cols-2 gap-1.5">
477
+ <ScrubInput
478
+ label={copy.paddingTop}
479
+ value={value.padding.top}
480
+ onChange={(next) =>
481
+ onPaddingChange({ ...value.padding, top: next })
482
+ }
483
+ unit="px"
484
+ min={0}
485
+ step={1}
486
+ precision={1}
487
+ disabled={disabled}
488
+ labelClassName="w-8"
489
+ inputClassName="h-6 text-[11px]"
490
+ />
491
+ <ScrubInput
492
+ label={copy.paddingRight}
493
+ value={value.padding.right}
494
+ onChange={(next) =>
495
+ onPaddingChange({ ...value.padding, right: next })
496
+ }
497
+ unit="px"
498
+ min={0}
499
+ step={1}
500
+ precision={1}
501
+ disabled={disabled}
502
+ labelClassName="w-8"
503
+ inputClassName="h-6 text-[11px]"
504
+ />
505
+ <ScrubInput
506
+ label={copy.paddingBottom}
507
+ value={value.padding.bottom}
508
+ onChange={(next) =>
509
+ onPaddingChange({ ...value.padding, bottom: next })
510
+ }
511
+ unit="px"
512
+ min={0}
513
+ step={1}
514
+ precision={1}
515
+ disabled={disabled}
516
+ labelClassName="w-8"
517
+ inputClassName="h-6 text-[11px]"
518
+ />
519
+ <ScrubInput
520
+ label={copy.paddingLeft}
521
+ value={value.padding.left}
522
+ onChange={(next) =>
523
+ onPaddingChange({ ...value.padding, left: next })
524
+ }
525
+ unit="px"
526
+ min={0}
527
+ step={1}
528
+ precision={1}
529
+ disabled={disabled}
530
+ labelClassName="w-8"
531
+ inputClassName="h-6 text-[11px]"
532
+ />
533
+ </div>
534
+ )}
535
+ </div>
536
+
537
+ {/* ── Clip content ── */}
538
+ <label className="flex h-6 cursor-pointer items-center gap-2 text-[11px] text-foreground">
539
+ <Checkbox
540
+ checked={Boolean(value.clipContent)}
541
+ disabled={disabled}
542
+ onCheckedChange={(checked) =>
543
+ onClipContentChange?.(checked === true)
544
+ }
545
+ className="size-4 rounded-sm"
546
+ />
547
+ <span>{copy.clipContent}</span>
548
+ </label>
549
+ </div>
550
+ </TooltipProvider>
551
+ );
552
+ }
553
+
554
+ // ─────────────────────────────────────────────────
555
+ // Sub-components
556
+ // ─────────────────────────────────────────────────
557
+
558
+ /** A single segment in the flow segmented control. */
559
+ function FlowButton({
560
+ label,
561
+ active,
562
+ disabled,
563
+ onClick,
564
+ children,
565
+ position,
566
+ }: {
567
+ label: string;
568
+ active: boolean;
569
+ disabled: boolean;
570
+ onClick: () => void;
571
+ children: ReactNode;
572
+ position?: "first" | "last";
573
+ }) {
574
+ return (
575
+ <Tooltip>
576
+ <TooltipTrigger asChild>
577
+ <button
578
+ type="button"
579
+ aria-label={label}
580
+ aria-pressed={active}
581
+ disabled={disabled}
582
+ onClick={onClick}
583
+ className={cn(
584
+ "flex flex-1 items-center justify-center transition-colors",
585
+ "border-r border-[var(--design-editor-control-border,hsl(var(--border)/0.5))]",
586
+ "text-muted-foreground hover:bg-[var(--design-editor-panel-raised-bg)] hover:text-foreground",
587
+ "disabled:pointer-events-none disabled:opacity-40",
588
+ position === "last" && "border-r-0",
589
+ active && [
590
+ "bg-[var(--design-editor-panel-bg)]",
591
+ "text-foreground",
592
+ "shadow-[inset_0_0_0_1px_var(--design-editor-control-border,hsl(var(--border)))]",
593
+ ],
594
+ )}
595
+ >
596
+ {children}
597
+ </button>
598
+ </TooltipTrigger>
599
+ <TooltipContent>{label}</TooltipContent>
600
+ </Tooltip>
601
+ );
602
+ }
603
+
604
+ /** Figma-style sizing field: [axis | resolved-size | mode ▾] as a dropdown trigger. */
605
+ function SizingField({
606
+ axis,
607
+ value,
608
+ resolvedSize,
609
+ options = SIZING_OPTIONS,
610
+ labels,
611
+ disabled,
612
+ onChange,
613
+ }: {
614
+ axis: string;
615
+ value: AutoLayoutSizing;
616
+ resolvedSize?: number;
617
+ options?: AutoLayoutSizing[];
618
+ labels: AutoLayoutMatrixLabels;
619
+ disabled: boolean;
620
+ onChange: (value: AutoLayoutSizing) => void;
621
+ }) {
622
+ // Ensure current value is in list (guard against stale state)
623
+ const validOptions: AutoLayoutSizing[] = options.includes(value)
624
+ ? options
625
+ : [...options, value];
626
+
627
+ return (
628
+ <DropdownMenu>
629
+ <Tooltip>
630
+ <TooltipTrigger asChild>
631
+ <DropdownMenuTrigger asChild>
632
+ <button
633
+ type="button"
634
+ aria-label={`${axis} ${labels[value]}`}
635
+ disabled={disabled}
636
+ className={cn(
637
+ "flex h-6 w-full items-center overflow-hidden rounded-md",
638
+ "bg-[var(--design-editor-control-bg)] text-[11px]",
639
+ "hover:bg-[var(--design-editor-panel-raised-bg)]",
640
+ "disabled:pointer-events-none disabled:opacity-40",
641
+ "focus:outline-none focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]",
642
+ )}
643
+ >
644
+ {/* Axis letter */}
645
+ <span className="flex h-full w-4 shrink-0 items-center justify-center border-r border-[var(--design-editor-control-border,hsl(var(--border)/0.6))] text-muted-foreground">
646
+ {axis}
647
+ </span>
648
+ {/* Resolved size */}
649
+ <span className="min-w-0 flex-1 truncate px-0.5 text-center tabular-nums text-foreground">
650
+ {Math.round(resolvedSize ?? 0)}
651
+ </span>
652
+ {/* Mode word + caret */}
653
+ <span className="flex h-full shrink-0 items-center gap-0 border-l border-[var(--design-editor-control-border,hsl(var(--border)/0.6))] px-0.5 text-muted-foreground">
654
+ {labels[value]}
655
+ <svg
656
+ viewBox="0 0 8 8"
657
+ width={8}
658
+ height={8}
659
+ fill="currentColor"
660
+ aria-hidden="true"
661
+ className="opacity-60"
662
+ >
663
+ <path
664
+ d="M1.5 3 L4 5.5 L6.5 3"
665
+ fill="none"
666
+ stroke="currentColor"
667
+ strokeWidth="1.2"
668
+ strokeLinecap="round"
669
+ strokeLinejoin="round"
670
+ />
671
+ </svg>
672
+ </span>
673
+ </button>
674
+ </DropdownMenuTrigger>
675
+ </TooltipTrigger>
676
+ <TooltipContent>{`${axis} ${labels[value]}`}</TooltipContent>
677
+ </Tooltip>
678
+ <DropdownMenuContent
679
+ align="start"
680
+ className="min-w-[100px] text-[12px]"
681
+ sideOffset={4}
682
+ >
683
+ {validOptions.map((opt) => (
684
+ <DropdownMenuItem
685
+ key={opt}
686
+ onSelect={() => onChange(opt)}
687
+ className={cn(
688
+ "text-[12px]",
689
+ opt === value &&
690
+ "font-medium text-[var(--design-editor-accent-color)]",
691
+ )}
692
+ >
693
+ {labels[opt]}
694
+ </DropdownMenuItem>
695
+ ))}
696
+ </DropdownMenuContent>
697
+ </DropdownMenu>
698
+ );
699
+ }