@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,761 @@
1
+ import {
2
+ IconArrowBarToDown,
3
+ IconArrowBarToUp,
4
+ IconArrowDown,
5
+ IconArrowUp,
6
+ IconClipboard,
7
+ IconClipboardCopy,
8
+ IconCode,
9
+ IconCopy,
10
+ IconEye,
11
+ IconEyeOff,
12
+ IconHierarchy,
13
+ IconLayersSubtract,
14
+ IconLock,
15
+ IconLockOpen,
16
+ IconPencil,
17
+ IconSelectAll,
18
+ IconTrash,
19
+ IconZoomInArea,
20
+ IconZoomScan,
21
+ type Icon,
22
+ } from "@tabler/icons-react";
23
+ import {
24
+ forwardRef,
25
+ useCallback,
26
+ useImperativeHandle,
27
+ useMemo,
28
+ useState,
29
+ type CSSProperties,
30
+ type ReactNode,
31
+ } from "react";
32
+
33
+ import {
34
+ ContextMenu,
35
+ ContextMenuContent,
36
+ ContextMenuGroup,
37
+ ContextMenuItem,
38
+ ContextMenuSeparator,
39
+ ContextMenuShortcut,
40
+ ContextMenuSub,
41
+ ContextMenuSubContent,
42
+ ContextMenuSubTrigger,
43
+ ContextMenuTrigger,
44
+ } from "@/components/ui/context-menu";
45
+ import { cn } from "@/lib/utils";
46
+
47
+ export type CanvasContextMenuAction =
48
+ | "paste-here"
49
+ | "select-all"
50
+ | "zoom-to-fit"
51
+ | "zoom-to-selection"
52
+ | "copy"
53
+ | "paste"
54
+ | "paste-over"
55
+ | "duplicate"
56
+ | "delete"
57
+ | "bring-forward"
58
+ | "bring-to-front"
59
+ | "send-backward"
60
+ | "send-to-back"
61
+ | "group"
62
+ | "ungroup"
63
+ | "rename"
64
+ | "toggle-lock"
65
+ | "toggle-hide"
66
+ | "copy-props"
67
+ | "paste-props"
68
+ | "copy-as-code";
69
+
70
+ export interface CanvasContextMenuPoint {
71
+ clientX: number;
72
+ clientY: number;
73
+ canvasX?: number;
74
+ canvasY?: number;
75
+ }
76
+
77
+ export interface CanvasContextMenuHandle {
78
+ openAt: (point: CanvasContextMenuPoint) => void;
79
+ close: () => void;
80
+ }
81
+
82
+ export interface CanvasContextMenuActionDetails {
83
+ action: CanvasContextMenuAction;
84
+ point: CanvasContextMenuPoint | null;
85
+ selectedCount: number;
86
+ originalEvent: Event;
87
+ }
88
+
89
+ export type CanvasContextMenuActionHandler = (
90
+ details: CanvasContextMenuActionDetails,
91
+ ) => void;
92
+
93
+ export interface CanvasContextMenuLabels {
94
+ pasteHere: string;
95
+ selectAll: string;
96
+ zoomToFit: string;
97
+ zoomToSelection: string;
98
+ copy: string;
99
+ paste: string;
100
+ pasteOver: string;
101
+ duplicate: string;
102
+ delete: string;
103
+ order: string;
104
+ bringForward: string;
105
+ bringToFront: string;
106
+ sendBackward: string;
107
+ sendToBack: string;
108
+ group: string;
109
+ ungroup: string;
110
+ rename: string;
111
+ lock: string;
112
+ unlock: string;
113
+ hide: string;
114
+ show: string;
115
+ copyProps: string;
116
+ pasteProps: string;
117
+ copyAsCode: string;
118
+ }
119
+
120
+ export interface CanvasContextMenuShortcuts {
121
+ pasteHere: string;
122
+ selectAll: string;
123
+ zoomToFit: string;
124
+ zoomToSelection: string;
125
+ copy: string;
126
+ paste: string;
127
+ pasteOver: string;
128
+ duplicate: string;
129
+ delete: string;
130
+ bringForward: string;
131
+ bringToFront: string;
132
+ sendBackward: string;
133
+ sendToBack: string;
134
+ group: string;
135
+ ungroup: string;
136
+ rename: string;
137
+ copyProps: string;
138
+ pasteProps: string;
139
+ copyAsCode: string;
140
+ }
141
+
142
+ export interface CanvasContextMenuProps {
143
+ children: ReactNode;
144
+ disabled?: boolean;
145
+ className?: string;
146
+ contentClassName?: string;
147
+ selectedCount?: number;
148
+ hasClipboard?: boolean;
149
+ hasPropsClipboard?: boolean;
150
+ isLocked?: boolean;
151
+ isHidden?: boolean;
152
+ canPasteHere?: boolean;
153
+ canSelectAll?: boolean;
154
+ canZoomToFit?: boolean;
155
+ canZoomToSelection?: boolean;
156
+ canCopy?: boolean;
157
+ canPaste?: boolean;
158
+ canPasteOver?: boolean;
159
+ canDuplicate?: boolean;
160
+ canDelete?: boolean;
161
+ canReorder?: boolean;
162
+ canGroup?: boolean;
163
+ canUngroup?: boolean;
164
+ canRename?: boolean;
165
+ canToggleLocked?: boolean;
166
+ canToggleHidden?: boolean;
167
+ canCopyProps?: boolean;
168
+ canPasteProps?: boolean;
169
+ canCopyAsCode?: boolean;
170
+ hiddenActions?: readonly CanvasContextMenuAction[];
171
+ disabledActions?: readonly CanvasContextMenuAction[];
172
+ labels?: Partial<CanvasContextMenuLabels>;
173
+ shortcuts?: Partial<CanvasContextMenuShortcuts>;
174
+ getCanvasPoint?: (point: { clientX: number; clientY: number }) => {
175
+ x: number;
176
+ y: number;
177
+ };
178
+ onOpenChange?: (open: boolean) => void;
179
+ onAction?: (
180
+ action: CanvasContextMenuAction,
181
+ details: CanvasContextMenuActionDetails,
182
+ ) => void;
183
+ onPasteHere?: CanvasContextMenuActionHandler;
184
+ onSelectAll?: CanvasContextMenuActionHandler;
185
+ onZoomToFit?: CanvasContextMenuActionHandler;
186
+ onZoomToSelection?: CanvasContextMenuActionHandler;
187
+ onCopy?: CanvasContextMenuActionHandler;
188
+ onPaste?: CanvasContextMenuActionHandler;
189
+ onPasteOver?: CanvasContextMenuActionHandler;
190
+ onDuplicate?: CanvasContextMenuActionHandler;
191
+ onDelete?: CanvasContextMenuActionHandler;
192
+ onBringForward?: CanvasContextMenuActionHandler;
193
+ onBringToFront?: CanvasContextMenuActionHandler;
194
+ onSendBackward?: CanvasContextMenuActionHandler;
195
+ onSendToBack?: CanvasContextMenuActionHandler;
196
+ onGroup?: CanvasContextMenuActionHandler;
197
+ onUngroup?: CanvasContextMenuActionHandler;
198
+ onRename?: CanvasContextMenuActionHandler;
199
+ onToggleLocked?: CanvasContextMenuActionHandler;
200
+ onToggleHidden?: CanvasContextMenuActionHandler;
201
+ onCopyProps?: CanvasContextMenuActionHandler;
202
+ onPasteProps?: CanvasContextMenuActionHandler;
203
+ onCopyAsCode?: CanvasContextMenuActionHandler;
204
+ }
205
+
206
+ const DEFAULT_LABELS: CanvasContextMenuLabels = {
207
+ pasteHere: "Paste here",
208
+ selectAll: "Select all",
209
+ zoomToFit: "Zoom to fit",
210
+ zoomToSelection: "Zoom to selection",
211
+ copy: "Copy",
212
+ paste: "Paste",
213
+ pasteOver: "Paste over",
214
+ duplicate: "Duplicate",
215
+ delete: "Delete",
216
+ order: "Order",
217
+ bringForward: "Bring forward",
218
+ bringToFront: "Bring to front",
219
+ sendBackward: "Send backward",
220
+ sendToBack: "Send to back",
221
+ group: "Group",
222
+ ungroup: "Ungroup",
223
+ rename: "Rename",
224
+ lock: "Lock",
225
+ unlock: "Unlock",
226
+ hide: "Hide",
227
+ show: "Show",
228
+ copyProps: "Copy properties",
229
+ pasteProps: "Paste properties",
230
+ copyAsCode: "Copy as code",
231
+ };
232
+
233
+ const DEFAULT_SHORTCUTS: CanvasContextMenuShortcuts = {
234
+ pasteHere: "Cmd+V",
235
+ selectAll: "Cmd+A",
236
+ zoomToFit: "Shift+1",
237
+ zoomToSelection: "Shift+2",
238
+ copy: "Cmd+C",
239
+ paste: "Cmd+V",
240
+ pasteOver: "Shift+Cmd+V",
241
+ duplicate: "Cmd+D",
242
+ delete: "Del",
243
+ bringForward: "Cmd+]",
244
+ bringToFront: "Opt+Cmd+]",
245
+ sendBackward: "Cmd+[",
246
+ sendToBack: "Opt+Cmd+[",
247
+ group: "Cmd+G",
248
+ ungroup: "Shift+Cmd+G",
249
+ rename: "Cmd+R",
250
+ copyProps: "Opt+Cmd+C",
251
+ pasteProps: "Opt+Cmd+V",
252
+ copyAsCode: "Shift+Cmd+C",
253
+ };
254
+
255
+ type ActionCallbackMap = Partial<
256
+ Record<CanvasContextMenuAction, CanvasContextMenuActionHandler>
257
+ >;
258
+
259
+ const MENU_CONTENT_CLASS =
260
+ "w-60 rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-panel-bg)] p-1 text-[11px] text-foreground shadow-[0_8px_28px_rgba(0,0,0,0.18)] outline-none animate-none data-[state=open]:animate-none data-[state=closed]:animate-none data-[side=bottom]:slide-in-from-top-0 data-[side=left]:slide-in-from-right-0 data-[side=right]:slide-in-from-left-0 data-[side=top]:slide-in-from-bottom-0";
261
+ const MENU_ITEM_CLASS =
262
+ "h-6 gap-2 rounded-[3px] px-1.5 py-0 text-[11px] leading-none focus:bg-[var(--design-editor-selection-color)] focus:text-foreground data-[disabled]:opacity-40";
263
+ const MENU_ICON_CLASS = "mr-0 size-3.5 shrink-0 text-muted-foreground";
264
+ const MENU_SUB_TRIGGER_CLASS =
265
+ "h-6 rounded-[3px] px-1.5 py-0 text-[11px] leading-none focus:bg-[var(--design-editor-selection-color)] focus:text-foreground data-[state=open]:bg-[var(--design-editor-selection-color)] data-[state=open]:text-foreground [&>svg:last-child]:size-3.5 [&>svg:last-child]:text-muted-foreground";
266
+ const MENU_SEPARATOR_CLASS =
267
+ "-mx-1 my-1 bg-[var(--design-editor-control-border)]";
268
+ const MENU_SHORTCUT_CLASS =
269
+ "ml-auto pl-6 text-[10px] tracking-normal text-muted-foreground";
270
+
271
+ export const CanvasContextMenu = forwardRef<
272
+ CanvasContextMenuHandle,
273
+ CanvasContextMenuProps
274
+ >(function CanvasContextMenu(
275
+ {
276
+ children,
277
+ disabled,
278
+ className,
279
+ contentClassName,
280
+ selectedCount = 0,
281
+ hasClipboard = false,
282
+ hasPropsClipboard = false,
283
+ isLocked = false,
284
+ isHidden = false,
285
+ canPasteHere = hasClipboard,
286
+ canSelectAll = true,
287
+ canZoomToFit = true,
288
+ canZoomToSelection = selectedCount > 0,
289
+ canCopy = selectedCount > 0,
290
+ canPaste = hasClipboard,
291
+ canPasteOver = hasClipboard && selectedCount > 0,
292
+ canDuplicate = selectedCount > 0,
293
+ canDelete = selectedCount > 0,
294
+ canReorder = selectedCount > 0,
295
+ canGroup = selectedCount > 1,
296
+ canUngroup = false,
297
+ canRename = selectedCount === 1,
298
+ canToggleLocked = selectedCount > 0,
299
+ canToggleHidden = selectedCount > 0,
300
+ canCopyProps = selectedCount > 0,
301
+ canPasteProps = hasPropsClipboard && selectedCount > 0,
302
+ canCopyAsCode = selectedCount > 0,
303
+ hiddenActions = [],
304
+ disabledActions = [],
305
+ labels: labelsProp,
306
+ shortcuts: shortcutsProp,
307
+ getCanvasPoint,
308
+ onOpenChange,
309
+ onAction,
310
+ onPasteHere,
311
+ onSelectAll,
312
+ onZoomToFit,
313
+ onZoomToSelection,
314
+ onCopy,
315
+ onPaste,
316
+ onPasteOver,
317
+ onDuplicate,
318
+ onDelete,
319
+ onBringForward,
320
+ onBringToFront,
321
+ onSendBackward,
322
+ onSendToBack,
323
+ onGroup,
324
+ onUngroup,
325
+ onRename,
326
+ onToggleLocked,
327
+ onToggleHidden,
328
+ onCopyProps,
329
+ onPasteProps,
330
+ onCopyAsCode,
331
+ },
332
+ ref,
333
+ ) {
334
+ const labels = useMemo(
335
+ () => ({ ...DEFAULT_LABELS, ...labelsProp }),
336
+ [labelsProp],
337
+ );
338
+ const shortcuts = useMemo(
339
+ () => ({ ...DEFAULT_SHORTCUTS, ...shortcutsProp }),
340
+ [shortcutsProp],
341
+ );
342
+ const hiddenActionSet = useMemo(
343
+ () => new Set(hiddenActions),
344
+ [hiddenActions],
345
+ );
346
+ const disabledActionSet = useMemo(
347
+ () => new Set(disabledActions),
348
+ [disabledActions],
349
+ );
350
+ const [point, setPoint] = useState<CanvasContextMenuPoint | null>(null);
351
+ const [open, setOpen] = useState(false);
352
+ const [manualPoint, setManualPoint] = useState<CanvasContextMenuPoint | null>(
353
+ null,
354
+ );
355
+
356
+ const handleOpenChange = useCallback(
357
+ (nextOpen: boolean) => {
358
+ setOpen(nextOpen);
359
+ if (!nextOpen) setManualPoint(null);
360
+ onOpenChange?.(nextOpen);
361
+ },
362
+ [onOpenChange],
363
+ );
364
+
365
+ useImperativeHandle(
366
+ ref,
367
+ () => ({
368
+ openAt(nextPoint) {
369
+ setPoint(nextPoint);
370
+ setManualPoint(nextPoint);
371
+ setOpen(true);
372
+ },
373
+ close() {
374
+ handleOpenChange(false);
375
+ },
376
+ }),
377
+ [handleOpenChange],
378
+ );
379
+
380
+ const callbacks = useMemo<ActionCallbackMap>(
381
+ () => ({
382
+ "paste-here": onPasteHere,
383
+ "select-all": onSelectAll,
384
+ "zoom-to-fit": onZoomToFit,
385
+ "zoom-to-selection": onZoomToSelection,
386
+ copy: onCopy,
387
+ paste: onPaste,
388
+ "paste-over": onPasteOver,
389
+ duplicate: onDuplicate,
390
+ delete: onDelete,
391
+ "bring-forward": onBringForward,
392
+ "bring-to-front": onBringToFront,
393
+ "send-backward": onSendBackward,
394
+ "send-to-back": onSendToBack,
395
+ group: onGroup,
396
+ ungroup: onUngroup,
397
+ rename: onRename,
398
+ "toggle-lock": onToggleLocked,
399
+ "toggle-hide": onToggleHidden,
400
+ "copy-props": onCopyProps,
401
+ "paste-props": onPasteProps,
402
+ "copy-as-code": onCopyAsCode,
403
+ }),
404
+ [
405
+ onBringForward,
406
+ onBringToFront,
407
+ onCopy,
408
+ onCopyAsCode,
409
+ onCopyProps,
410
+ onDelete,
411
+ onDuplicate,
412
+ onGroup,
413
+ onPaste,
414
+ onPasteHere,
415
+ onPasteOver,
416
+ onPasteProps,
417
+ onRename,
418
+ onSelectAll,
419
+ onSendBackward,
420
+ onSendToBack,
421
+ onToggleHidden,
422
+ onToggleLocked,
423
+ onUngroup,
424
+ onZoomToFit,
425
+ onZoomToSelection,
426
+ ],
427
+ );
428
+
429
+ const runAction = useCallback(
430
+ (action: CanvasContextMenuAction, originalEvent: Event) => {
431
+ const details = {
432
+ action,
433
+ point,
434
+ selectedCount,
435
+ originalEvent,
436
+ };
437
+ onAction?.(action, details);
438
+ callbacks[action]?.(details);
439
+ },
440
+ [callbacks, onAction, point, selectedCount],
441
+ );
442
+
443
+ const canRun = useCallback(
444
+ (action: CanvasContextMenuAction, capability: boolean) =>
445
+ capability &&
446
+ !disabledActionSet.has(action) &&
447
+ Boolean(onAction || callbacks[action]),
448
+ [callbacks, disabledActionSet, onAction],
449
+ );
450
+
451
+ const isHiddenAction = useCallback(
452
+ (action: CanvasContextMenuAction) => hiddenActionSet.has(action),
453
+ [hiddenActionSet],
454
+ );
455
+
456
+ if (disabled) {
457
+ return <>{children}</>;
458
+ }
459
+
460
+ const manualContentStyle = manualPoint
461
+ ? ({
462
+ position: "fixed",
463
+ left: manualPoint.clientX,
464
+ top: manualPoint.clientY,
465
+ transform: "none",
466
+ zIndex: 250,
467
+ } satisfies CSSProperties)
468
+ : undefined;
469
+
470
+ return (
471
+ <ContextMenu open={open} onOpenChange={handleOpenChange}>
472
+ <ContextMenuTrigger asChild>
473
+ <div
474
+ className={cn("contents", className)}
475
+ onContextMenuCapture={(event) => {
476
+ const canvasPoint = getCanvasPoint?.({
477
+ clientX: event.clientX,
478
+ clientY: event.clientY,
479
+ });
480
+ setPoint({
481
+ clientX: event.clientX,
482
+ clientY: event.clientY,
483
+ canvasX: canvasPoint?.x,
484
+ canvasY: canvasPoint?.y,
485
+ });
486
+ }}
487
+ >
488
+ {children}
489
+ </div>
490
+ </ContextMenuTrigger>
491
+ <ContextMenuContent
492
+ className={cn(MENU_CONTENT_CLASS, contentClassName)}
493
+ style={manualContentStyle}
494
+ >
495
+ <ContextMenuGroup>
496
+ <CanvasMenuItem
497
+ hidden={isHiddenAction("paste-here")}
498
+ disabled={!canRun("paste-here", canPasteHere)}
499
+ icon={IconClipboard}
500
+ label={labels.pasteHere}
501
+ shortcut={shortcuts.pasteHere}
502
+ onSelect={(event) => runAction("paste-here", event)}
503
+ />
504
+ <CanvasMenuItem
505
+ hidden={isHiddenAction("select-all")}
506
+ disabled={!canRun("select-all", canSelectAll)}
507
+ icon={IconSelectAll}
508
+ label={labels.selectAll}
509
+ shortcut={shortcuts.selectAll}
510
+ onSelect={(event) => runAction("select-all", event)}
511
+ />
512
+ </ContextMenuGroup>
513
+
514
+ <CanvasMenuSeparator />
515
+
516
+ <ContextMenuGroup>
517
+ <CanvasMenuItem
518
+ hidden={isHiddenAction("zoom-to-fit")}
519
+ disabled={!canRun("zoom-to-fit", canZoomToFit)}
520
+ icon={IconZoomScan}
521
+ label={labels.zoomToFit}
522
+ shortcut={shortcuts.zoomToFit}
523
+ onSelect={(event) => runAction("zoom-to-fit", event)}
524
+ />
525
+ <CanvasMenuItem
526
+ hidden={isHiddenAction("zoom-to-selection")}
527
+ disabled={!canRun("zoom-to-selection", canZoomToSelection)}
528
+ icon={IconZoomInArea}
529
+ label={labels.zoomToSelection}
530
+ shortcut={shortcuts.zoomToSelection}
531
+ onSelect={(event) => runAction("zoom-to-selection", event)}
532
+ />
533
+ </ContextMenuGroup>
534
+
535
+ <CanvasMenuSeparator />
536
+
537
+ <ContextMenuGroup>
538
+ <CanvasMenuItem
539
+ hidden={isHiddenAction("copy")}
540
+ disabled={!canRun("copy", canCopy)}
541
+ icon={IconCopy}
542
+ label={labels.copy}
543
+ shortcut={shortcuts.copy}
544
+ onSelect={(event) => runAction("copy", event)}
545
+ />
546
+ <CanvasMenuItem
547
+ hidden={isHiddenAction("paste")}
548
+ disabled={!canRun("paste", canPaste)}
549
+ icon={IconClipboard}
550
+ label={labels.paste}
551
+ shortcut={shortcuts.paste}
552
+ onSelect={(event) => runAction("paste", event)}
553
+ />
554
+ <CanvasMenuItem
555
+ hidden={isHiddenAction("paste-over")}
556
+ disabled={!canRun("paste-over", canPasteOver)}
557
+ icon={IconClipboardCopy}
558
+ label={labels.pasteOver}
559
+ shortcut={shortcuts.pasteOver}
560
+ onSelect={(event) => runAction("paste-over", event)}
561
+ />
562
+ <CanvasMenuItem
563
+ hidden={isHiddenAction("duplicate")}
564
+ disabled={!canRun("duplicate", canDuplicate)}
565
+ icon={IconCopy}
566
+ label={labels.duplicate}
567
+ shortcut={shortcuts.duplicate}
568
+ onSelect={(event) => runAction("duplicate", event)}
569
+ />
570
+ </ContextMenuGroup>
571
+
572
+ <CanvasMenuSeparator />
573
+
574
+ <ContextMenuGroup>
575
+ {!isHiddenAction("bring-forward") ||
576
+ !isHiddenAction("bring-to-front") ||
577
+ !isHiddenAction("send-backward") ||
578
+ !isHiddenAction("send-to-back") ? (
579
+ <ContextMenuSub>
580
+ <ContextMenuSubTrigger
581
+ disabled={
582
+ !(
583
+ canRun("bring-forward", canReorder) ||
584
+ canRun("bring-to-front", canReorder) ||
585
+ canRun("send-backward", canReorder) ||
586
+ canRun("send-to-back", canReorder)
587
+ )
588
+ }
589
+ className={MENU_SUB_TRIGGER_CLASS}
590
+ >
591
+ <IconArrowUp className={MENU_ICON_CLASS} />
592
+ {labels.order}
593
+ </ContextMenuSubTrigger>
594
+ <ContextMenuSubContent className={cn(MENU_CONTENT_CLASS, "w-56")}>
595
+ <CanvasMenuItem
596
+ hidden={isHiddenAction("bring-forward")}
597
+ disabled={!canRun("bring-forward", canReorder)}
598
+ icon={IconArrowUp}
599
+ label={labels.bringForward}
600
+ shortcut={shortcuts.bringForward}
601
+ onSelect={(event) => runAction("bring-forward", event)}
602
+ />
603
+ <CanvasMenuItem
604
+ hidden={isHiddenAction("bring-to-front")}
605
+ disabled={!canRun("bring-to-front", canReorder)}
606
+ icon={IconArrowBarToUp}
607
+ label={labels.bringToFront}
608
+ shortcut={shortcuts.bringToFront}
609
+ onSelect={(event) => runAction("bring-to-front", event)}
610
+ />
611
+ <CanvasMenuItem
612
+ hidden={isHiddenAction("send-backward")}
613
+ disabled={!canRun("send-backward", canReorder)}
614
+ icon={IconArrowDown}
615
+ label={labels.sendBackward}
616
+ shortcut={shortcuts.sendBackward}
617
+ onSelect={(event) => runAction("send-backward", event)}
618
+ />
619
+ <CanvasMenuItem
620
+ hidden={isHiddenAction("send-to-back")}
621
+ disabled={!canRun("send-to-back", canReorder)}
622
+ icon={IconArrowBarToDown}
623
+ label={labels.sendToBack}
624
+ shortcut={shortcuts.sendToBack}
625
+ onSelect={(event) => runAction("send-to-back", event)}
626
+ />
627
+ </ContextMenuSubContent>
628
+ </ContextMenuSub>
629
+ ) : null}
630
+ <CanvasMenuItem
631
+ hidden={isHiddenAction("group")}
632
+ disabled={!canRun("group", canGroup)}
633
+ icon={IconHierarchy}
634
+ label={labels.group}
635
+ shortcut={shortcuts.group}
636
+ onSelect={(event) => runAction("group", event)}
637
+ />
638
+ <CanvasMenuItem
639
+ hidden={isHiddenAction("ungroup")}
640
+ disabled={!canRun("ungroup", canUngroup)}
641
+ icon={IconLayersSubtract}
642
+ label={labels.ungroup}
643
+ shortcut={shortcuts.ungroup}
644
+ onSelect={(event) => runAction("ungroup", event)}
645
+ />
646
+ </ContextMenuGroup>
647
+
648
+ <CanvasMenuSeparator />
649
+
650
+ <ContextMenuGroup>
651
+ <CanvasMenuItem
652
+ hidden={isHiddenAction("rename")}
653
+ disabled={!canRun("rename", canRename)}
654
+ icon={IconPencil}
655
+ label={labels.rename}
656
+ shortcut={shortcuts.rename}
657
+ onSelect={(event) => runAction("rename", event)}
658
+ />
659
+ <CanvasMenuItem
660
+ hidden={isHiddenAction("toggle-lock")}
661
+ disabled={!canRun("toggle-lock", canToggleLocked)}
662
+ icon={isLocked ? IconLockOpen : IconLock}
663
+ label={isLocked ? labels.unlock : labels.lock}
664
+ onSelect={(event) => runAction("toggle-lock", event)}
665
+ />
666
+ <CanvasMenuItem
667
+ hidden={isHiddenAction("toggle-hide")}
668
+ disabled={!canRun("toggle-hide", canToggleHidden)}
669
+ icon={isHidden ? IconEye : IconEyeOff}
670
+ label={isHidden ? labels.show : labels.hide}
671
+ onSelect={(event) => runAction("toggle-hide", event)}
672
+ />
673
+ </ContextMenuGroup>
674
+
675
+ <CanvasMenuSeparator />
676
+
677
+ <ContextMenuGroup>
678
+ <CanvasMenuItem
679
+ hidden={isHiddenAction("copy-props")}
680
+ disabled={!canRun("copy-props", canCopyProps)}
681
+ icon={IconClipboardCopy}
682
+ label={labels.copyProps}
683
+ shortcut={shortcuts.copyProps}
684
+ onSelect={(event) => runAction("copy-props", event)}
685
+ />
686
+ <CanvasMenuItem
687
+ hidden={isHiddenAction("paste-props")}
688
+ disabled={!canRun("paste-props", canPasteProps)}
689
+ icon={IconClipboard}
690
+ label={labels.pasteProps}
691
+ shortcut={shortcuts.pasteProps}
692
+ onSelect={(event) => runAction("paste-props", event)}
693
+ />
694
+ <CanvasMenuItem
695
+ hidden={isHiddenAction("copy-as-code")}
696
+ disabled={!canRun("copy-as-code", canCopyAsCode)}
697
+ icon={IconCode}
698
+ label={labels.copyAsCode}
699
+ shortcut={shortcuts.copyAsCode}
700
+ onSelect={(event) => runAction("copy-as-code", event)}
701
+ />
702
+ </ContextMenuGroup>
703
+
704
+ <CanvasMenuSeparator />
705
+
706
+ <CanvasMenuItem
707
+ hidden={isHiddenAction("delete")}
708
+ disabled={!canRun("delete", canDelete)}
709
+ icon={IconTrash}
710
+ label={labels.delete}
711
+ shortcut={shortcuts.delete}
712
+ destructive
713
+ onSelect={(event) => runAction("delete", event)}
714
+ />
715
+ </ContextMenuContent>
716
+ </ContextMenu>
717
+ );
718
+ });
719
+
720
+ function CanvasMenuItem({
721
+ hidden,
722
+ disabled,
723
+ destructive,
724
+ icon: Icon,
725
+ label,
726
+ shortcut,
727
+ onSelect,
728
+ }: {
729
+ hidden?: boolean;
730
+ disabled?: boolean;
731
+ destructive?: boolean;
732
+ icon: Icon;
733
+ label: string;
734
+ shortcut?: string;
735
+ onSelect: (event: Event) => void;
736
+ }) {
737
+ if (hidden) return null;
738
+
739
+ return (
740
+ <ContextMenuItem
741
+ disabled={disabled}
742
+ onSelect={onSelect}
743
+ className={cn(
744
+ MENU_ITEM_CLASS,
745
+ destructive && "text-destructive focus:text-destructive",
746
+ )}
747
+ >
748
+ <Icon className={MENU_ICON_CLASS} />
749
+ <span className="truncate">{label}</span>
750
+ {shortcut ? (
751
+ <ContextMenuShortcut className={MENU_SHORTCUT_CLASS}>
752
+ {shortcut}
753
+ </ContextMenuShortcut>
754
+ ) : null}
755
+ </ContextMenuItem>
756
+ );
757
+ }
758
+
759
+ function CanvasMenuSeparator() {
760
+ return <ContextMenuSeparator className={MENU_SEPARATOR_CLASS} />;
761
+ }