@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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +26 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
- package/corpus/core/docs/content/template-design.mdx +45 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/engine/index.ts +1 -0
- package/corpus/core/src/agent/engine/registry.ts +40 -0
- package/corpus/core/src/agent/production-agent.ts +6 -2
- package/corpus/core/src/cli/design-connect.ts +490 -0
- package/corpus/core/src/cli/index.ts +16 -0
- package/corpus/core/src/cli/skills.ts +126 -3
- package/corpus/core/src/client/AssistantChat.tsx +43 -7
- package/corpus/core/src/client/agent-chat.ts +27 -3
- package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
- package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
- package/corpus/core/src/client/chat/message-components.tsx +1 -1
- package/corpus/core/src/client/chat-model-groups.ts +1 -2
- package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
- package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
- package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
- package/corpus/core/src/client/frame-protocol.ts +17 -2
- package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
- package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
- package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
- package/corpus/core/src/server/transcribe-voice.ts +57 -22
- package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
- package/corpus/core/src/styles/agent-native.css +56 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/core/src/vite/client.ts +2 -0
- package/corpus/core/src/voice/index.ts +18 -0
- package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
- package/corpus/core/src/voice/voice-context.ts +217 -0
- package/corpus/core/src/voice/voice-replacements.ts +75 -0
- package/corpus/templates/analytics/AGENTS.md +4 -3
- package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
- package/corpus/templates/analytics/app/global.css +0 -4
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/analytics/app/i18n-data.ts +20 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
- package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
- package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
- package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/brain/app/i18n-data.ts +20 -0
- package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
- package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
- package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
- package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
- package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
- package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
- package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
- package/corpus/templates/design/AGENTS.md +95 -5
- package/corpus/templates/design/DESIGN.md +82 -0
- package/corpus/templates/design/DEVELOPING.md +43 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
- package/corpus/templates/design/actions/apply-shader.ts +277 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
- package/corpus/templates/design/actions/connect-localhost.ts +183 -0
- package/corpus/templates/design/actions/edit-design.ts +195 -42
- package/corpus/templates/design/actions/generate-design.ts +71 -1
- package/corpus/templates/design/actions/generate-screens.ts +193 -0
- package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
- package/corpus/templates/design/actions/get-shader.ts +119 -0
- package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
- package/corpus/templates/design/actions/navigate.ts +55 -2
- package/corpus/templates/design/actions/view-screen.ts +68 -1
- package/corpus/templates/design/agent-native.app-skill.json +10 -0
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
- package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
- package/corpus/templates/design/app/components/design/index.ts +0 -5
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
- package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
- package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
- package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
- package/corpus/templates/design/app/components/design/types.ts +23 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
- package/corpus/templates/design/app/global.css +121 -3
- package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
- package/corpus/templates/design/app/i18n-data.ts +2790 -1
- package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
- package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/server/db/schema.ts +26 -0
- package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
- package/corpus/templates/design/shared/api.ts +27 -0
- package/corpus/templates/design/shared/canvas-frames.ts +103 -0
- package/corpus/templates/design/shared/canvas-math.ts +1058 -0
- package/corpus/templates/design/shared/code-layer.ts +2212 -0
- package/corpus/templates/design/shared/color-utils.ts +180 -0
- package/corpus/templates/design/shared/generation-session.ts +61 -0
- package/corpus/templates/design/shared/shader-presets.ts +782 -0
- package/corpus/templates/design/shared/shader-safety.ts +137 -0
- package/corpus/templates/design/shared/source-mode.ts +237 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
- package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
- package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
- package/corpus/templates/plan/app/global.css +61 -78
- package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
- package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
- package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
- package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
- package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
- package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +9 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +37 -0
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +4 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts +52 -0
- package/dist/cli/design-connect.d.ts.map +1 -0
- package/dist/cli/design-connect.js +409 -0
- package/dist/cli/design-connect.js.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +121 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +17 -3
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.js +1 -1
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/wireframe.js +1 -1
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +1 -2
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
- package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
- package/dist/client/components/LiveCursorOverlay.js +19 -40
- package/dist/client/components/LiveCursorOverlay.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +86 -24
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +9 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +154 -32
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +17 -2
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +2 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -6
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts +5 -0
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +51 -25
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +8 -8
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +40 -24
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -0
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +20 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-native.css +56 -7
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/dist/voice/index.d.ts +5 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +4 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
- package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
- package/dist/voice/voice-cleanup-prompt.js +26 -0
- package/dist/voice/voice-cleanup-prompt.js.map +1 -0
- package/dist/voice/voice-context.d.ts +25 -0
- package/dist/voice/voice-context.d.ts.map +1 -0
- package/dist/voice/voice-context.js +156 -0
- package/dist/voice/voice-context.js.map +1 -0
- package/dist/voice/voice-replacements.d.ts +4 -0
- package/dist/voice/voice-replacements.d.ts.map +1 -0
- package/dist/voice/voice-replacements.js +52 -0
- package/dist/voice/voice-replacements.js.map +1 -0
- package/docs/content/locales/ar-SA/template-design.mdx +41 -0
- package/docs/content/locales/de-DE/template-design.mdx +51 -0
- package/docs/content/locales/es-ES/template-design.mdx +50 -0
- package/docs/content/locales/fr-FR/template-design.mdx +49 -0
- package/docs/content/locales/hi-IN/template-design.mdx +44 -0
- package/docs/content/locales/ja-JP/template-design.mdx +46 -0
- package/docs/content/locales/ko-KR/template-design.mdx +44 -0
- package/docs/content/locales/pt-BR/template-design.mdx +48 -0
- package/docs/content/locales/zh-CN/template-design.mdx +36 -0
- package/docs/content/locales/zh-TW/template-design.mdx +38 -0
- package/docs/content/template-design.mdx +45 -0
- package/package.json +2 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
- package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
- package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
- package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client";
|
|
2
2
|
import type { TweakDefinition } from "@shared/api";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
IconX,
|
|
5
|
+
IconGripHorizontal,
|
|
6
|
+
IconPlus,
|
|
7
|
+
IconAdjustmentsHorizontal,
|
|
8
|
+
} from "@tabler/icons-react";
|
|
4
9
|
import { useState, useRef, useCallback } from "react";
|
|
5
10
|
|
|
6
11
|
import { Button } from "@/components/ui/button";
|
|
@@ -22,6 +27,60 @@ interface TweaksPanelProps {
|
|
|
22
27
|
visible: boolean;
|
|
23
28
|
}
|
|
24
29
|
|
|
30
|
+
interface TweaksPanelContentProps {
|
|
31
|
+
tweaks: TweakDefinition[];
|
|
32
|
+
values: Record<string, string | number | boolean>;
|
|
33
|
+
onChange: (id: string, value: string | number | boolean) => void;
|
|
34
|
+
onRequestTweaks?: (anchor: HTMLElement) => void;
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function TweaksPanelContent({
|
|
39
|
+
tweaks,
|
|
40
|
+
values,
|
|
41
|
+
onChange,
|
|
42
|
+
onRequestTweaks,
|
|
43
|
+
className,
|
|
44
|
+
}: TweaksPanelContentProps) {
|
|
45
|
+
const t = useT();
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className={cn("space-y-1.5", className)}>
|
|
49
|
+
{tweaks.length > 0 ? (
|
|
50
|
+
tweaks.map((tweak) => (
|
|
51
|
+
<TweakControl
|
|
52
|
+
key={tweak.id}
|
|
53
|
+
tweak={tweak}
|
|
54
|
+
value={values[tweak.id] ?? tweak.defaultValue}
|
|
55
|
+
onChange={(v) => onChange(tweak.id, v)}
|
|
56
|
+
/>
|
|
57
|
+
))
|
|
58
|
+
) : (
|
|
59
|
+
<div className="flex flex-col items-center gap-2 py-4 text-center">
|
|
60
|
+
<div className="flex size-8 items-center justify-center rounded-lg bg-muted/60">
|
|
61
|
+
<IconAdjustmentsHorizontal className="size-4 text-muted-foreground/70" />
|
|
62
|
+
</div>
|
|
63
|
+
<p className="text-[11px] leading-snug text-muted-foreground">
|
|
64
|
+
{t("designEditor.noTweakControls")}
|
|
65
|
+
</p>
|
|
66
|
+
{onRequestTweaks && (
|
|
67
|
+
<Button
|
|
68
|
+
type="button"
|
|
69
|
+
variant="outline"
|
|
70
|
+
size="sm"
|
|
71
|
+
className="h-6 cursor-pointer px-2.5 text-[11px]"
|
|
72
|
+
onClick={(e) => onRequestTweaks(e.currentTarget)}
|
|
73
|
+
>
|
|
74
|
+
<IconPlus className="size-3" />
|
|
75
|
+
{t("designEditor.addTweakControls")}
|
|
76
|
+
</Button>
|
|
77
|
+
)}
|
|
78
|
+
</div>
|
|
79
|
+
)}
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
25
84
|
export function TweaksPanel({
|
|
26
85
|
tweaks,
|
|
27
86
|
values,
|
|
@@ -85,18 +144,18 @@ export function TweaksPanel({
|
|
|
85
144
|
className="fixed z-[70] w-60 rounded-xl border border-border bg-card shadow-2xl backdrop-blur-sm"
|
|
86
145
|
style={{ right: position.x, bottom: position.y }}
|
|
87
146
|
>
|
|
88
|
-
{/* Header — drag handle + collapse toggle */}
|
|
147
|
+
{/* Header — drag handle + collapse toggle + actions */}
|
|
89
148
|
<div
|
|
90
|
-
className="flex cursor-grab select-none items-center justify-between px-3
|
|
149
|
+
className="flex min-h-8 cursor-grab select-none items-center justify-between px-3 active:cursor-grabbing"
|
|
91
150
|
onMouseDown={handleMouseDown}
|
|
92
151
|
>
|
|
93
152
|
<div className="flex items-center gap-1.5">
|
|
94
|
-
<IconGripHorizontal className="
|
|
153
|
+
<IconGripHorizontal className="size-3 text-muted-foreground/40" />
|
|
95
154
|
<button
|
|
96
155
|
type="button"
|
|
97
156
|
onMouseDown={(e) => e.stopPropagation()}
|
|
98
157
|
onClick={() => setCollapsed((c) => !c)}
|
|
99
|
-
className="cursor-pointer text-[11px] font-semibold uppercase tracking-wider text-muted-foreground hover:text-
|
|
158
|
+
className="cursor-pointer text-[11px] font-semibold uppercase tracking-wider text-muted-foreground hover:text-foreground"
|
|
100
159
|
>
|
|
101
160
|
{t("designEditor.tweaks")}
|
|
102
161
|
</button>
|
|
@@ -114,10 +173,10 @@ export function TweaksPanel({
|
|
|
114
173
|
e.stopPropagation();
|
|
115
174
|
onRequestTweaks(e.currentTarget);
|
|
116
175
|
}}
|
|
117
|
-
className="size-6 cursor-pointer text-muted-foreground/
|
|
176
|
+
className="size-6 cursor-pointer text-muted-foreground/60 hover:text-foreground"
|
|
118
177
|
aria-label={t("designEditor.addTweaks")}
|
|
119
178
|
>
|
|
120
|
-
<IconPlus className="
|
|
179
|
+
<IconPlus className="size-3" />
|
|
121
180
|
</Button>
|
|
122
181
|
</TooltipTrigger>
|
|
123
182
|
<TooltipContent>{t("designEditor.addTweaks")}</TooltipContent>
|
|
@@ -130,46 +189,26 @@ export function TweaksPanel({
|
|
|
130
189
|
e.stopPropagation();
|
|
131
190
|
onClose();
|
|
132
191
|
}}
|
|
133
|
-
className="flex size-6 cursor-pointer items-center justify-center rounded
|
|
192
|
+
className="flex size-6 cursor-pointer items-center justify-center rounded text-muted-foreground/60 hover:bg-accent hover:text-foreground"
|
|
134
193
|
aria-label={t("designEditor.closeTweaks")}
|
|
135
194
|
>
|
|
136
|
-
<IconX className="
|
|
195
|
+
<IconX className="size-3" />
|
|
137
196
|
</button>
|
|
138
197
|
</div>
|
|
139
198
|
</div>
|
|
140
199
|
|
|
141
200
|
{/* Body */}
|
|
142
201
|
{!collapsed && (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
) : (
|
|
154
|
-
<div className="space-y-2 rounded-lg border border-dashed border-border/80 bg-muted/20 p-3">
|
|
155
|
-
<p className="text-xs leading-relaxed text-muted-foreground">
|
|
156
|
-
{t("designEditor.noTweakControls")}
|
|
157
|
-
</p>
|
|
158
|
-
{onRequestTweaks && (
|
|
159
|
-
<Button
|
|
160
|
-
type="button"
|
|
161
|
-
variant="outline"
|
|
162
|
-
size="sm"
|
|
163
|
-
className="h-8 w-full cursor-pointer text-xs"
|
|
164
|
-
onClick={(e) => onRequestTweaks(e.currentTarget)}
|
|
165
|
-
>
|
|
166
|
-
<IconPlus className="h-3.5 w-3.5" />
|
|
167
|
-
{t("designEditor.addTweakControls")}
|
|
168
|
-
</Button>
|
|
169
|
-
)}
|
|
170
|
-
</div>
|
|
171
|
-
)}
|
|
172
|
-
</div>
|
|
202
|
+
<>
|
|
203
|
+
<div className="mx-3 border-t border-border/60" />
|
|
204
|
+
<TweaksPanelContent
|
|
205
|
+
tweaks={tweaks}
|
|
206
|
+
values={values}
|
|
207
|
+
onChange={onChange}
|
|
208
|
+
onRequestTweaks={onRequestTweaks}
|
|
209
|
+
className="px-3 py-2"
|
|
210
|
+
/>
|
|
211
|
+
</>
|
|
173
212
|
)}
|
|
174
213
|
</div>
|
|
175
214
|
);
|
|
@@ -184,15 +223,27 @@ function TweakControl({
|
|
|
184
223
|
value: string | number | boolean;
|
|
185
224
|
onChange: (v: string | number | boolean) => void;
|
|
186
225
|
}) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
226
|
+
// Toggle gets an inline row; other types get a label above
|
|
227
|
+
if (tweak.type === "toggle") {
|
|
228
|
+
return (
|
|
229
|
+
<div className="flex h-6 items-center justify-between gap-1.5">
|
|
230
|
+
<span className="text-[11px] text-muted-foreground">{tweak.label}</span>
|
|
231
|
+
<Switch
|
|
232
|
+
checked={!!value}
|
|
233
|
+
onCheckedChange={(checked) => onChange(checked)}
|
|
234
|
+
className="scale-75 origin-right"
|
|
235
|
+
/>
|
|
191
236
|
</div>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
<div className="space-y-1">
|
|
242
|
+
<span className="text-[11px] text-muted-foreground">{tweak.label}</span>
|
|
192
243
|
|
|
193
|
-
{(tweak.type as string) === "color-swatch" ||
|
|
194
|
-
|
|
195
|
-
<div className="flex gap-
|
|
244
|
+
{((tweak.type as string) === "color-swatch" ||
|
|
245
|
+
(tweak.type as string) === "color-swatches") && (
|
|
246
|
+
<div className="flex gap-1.5">
|
|
196
247
|
{tweak.options?.map((opt) => (
|
|
197
248
|
<Tooltip key={opt.value}>
|
|
198
249
|
<TooltipTrigger asChild>
|
|
@@ -200,32 +251,32 @@ function TweakControl({
|
|
|
200
251
|
type="button"
|
|
201
252
|
onClick={() => onChange(opt.value)}
|
|
202
253
|
className={cn(
|
|
203
|
-
"
|
|
254
|
+
"size-5 cursor-pointer rounded-full transition-all",
|
|
204
255
|
value === opt.value
|
|
205
|
-
? "ring-2 ring-
|
|
206
|
-
: "ring-1 ring-
|
|
256
|
+
? "ring-2 ring-foreground/80 ring-offset-1 ring-offset-card"
|
|
257
|
+
: "ring-1 ring-border/60 hover:ring-border",
|
|
207
258
|
)}
|
|
208
|
-
style={{ backgroundColor: opt.color
|
|
259
|
+
style={{ backgroundColor: opt.color ?? opt.value }}
|
|
209
260
|
/>
|
|
210
261
|
</TooltipTrigger>
|
|
211
262
|
<TooltipContent>{opt.label}</TooltipContent>
|
|
212
263
|
</Tooltip>
|
|
213
264
|
))}
|
|
214
265
|
</div>
|
|
215
|
-
)
|
|
266
|
+
)}
|
|
216
267
|
|
|
217
268
|
{tweak.type === "segment" && (
|
|
218
|
-
<div className="flex overflow-hidden rounded
|
|
269
|
+
<div className="flex h-6 overflow-hidden rounded border border-border">
|
|
219
270
|
{tweak.options?.map((opt) => (
|
|
220
271
|
<button
|
|
221
272
|
type="button"
|
|
222
273
|
key={opt.value}
|
|
223
274
|
onClick={() => onChange(opt.value)}
|
|
224
275
|
className={cn(
|
|
225
|
-
"flex-1 cursor-pointer px-2
|
|
276
|
+
"flex flex-1 cursor-pointer items-center justify-center px-2 text-[11px] font-medium transition-colors",
|
|
226
277
|
value === opt.value
|
|
227
278
|
? "bg-accent text-foreground"
|
|
228
|
-
: "text-muted-foreground/70 hover:text-
|
|
279
|
+
: "text-muted-foreground/70 hover:bg-accent/50 hover:text-foreground",
|
|
229
280
|
)}
|
|
230
281
|
>
|
|
231
282
|
{opt.label}
|
|
@@ -235,7 +286,7 @@ function TweakControl({
|
|
|
235
286
|
)}
|
|
236
287
|
|
|
237
288
|
{tweak.type === "slider" && (
|
|
238
|
-
<div className="flex items-center gap-2">
|
|
289
|
+
<div className="flex h-6 items-center gap-2">
|
|
239
290
|
<Slider
|
|
240
291
|
min={tweak.min ?? 0}
|
|
241
292
|
max={tweak.max ?? 100}
|
|
@@ -244,19 +295,12 @@ function TweakControl({
|
|
|
244
295
|
onValueChange={([v]) => onChange(v)}
|
|
245
296
|
className="flex-1"
|
|
246
297
|
/>
|
|
247
|
-
<span className="min-w-[
|
|
298
|
+
<span className="min-w-[2ch] text-right text-[11px] tabular-nums text-muted-foreground">
|
|
248
299
|
{typeof value === "number" ? value : 50}
|
|
249
300
|
{tweak.cssVar?.includes("radius") ? "px" : ""}
|
|
250
301
|
</span>
|
|
251
302
|
</div>
|
|
252
303
|
)}
|
|
253
|
-
|
|
254
|
-
{tweak.type === "toggle" && (
|
|
255
|
-
<Switch
|
|
256
|
-
checked={!!value}
|
|
257
|
-
onCheckedChange={(checked) => onChange(checked)}
|
|
258
|
-
/>
|
|
259
|
-
)}
|
|
260
304
|
</div>
|
|
261
305
|
);
|
|
262
306
|
}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
export { DesignCanvas } from "./DesignCanvas";
|
|
2
|
-
export { DesignToolbar } from "./DesignToolbar";
|
|
3
|
-
export type { EditorMode } from "./DesignToolbar";
|
|
4
2
|
export { DeviceFrame } from "./DeviceFrame";
|
|
5
3
|
export { DrawOverlay } from "./DrawOverlay";
|
|
6
4
|
export { EditPanel } from "./EditPanel";
|
|
7
5
|
export { QuestionFlow } from "./QuestionFlow";
|
|
8
6
|
export { TweaksPanel } from "./TweaksPanel";
|
|
9
7
|
export { VariantGrid } from "./VariantGrid";
|
|
10
|
-
export { ViewportTabs } from "./ViewportTabs";
|
|
11
|
-
export { ZoomControls } from "./ZoomControls";
|
|
12
|
-
export { PresentMode } from "./PresentMode";
|
|
13
8
|
export type {
|
|
14
9
|
DrawAnnotation,
|
|
15
10
|
ElementInfo,
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Tooltip,
|
|
5
|
+
TooltipContent,
|
|
6
|
+
TooltipProvider,
|
|
7
|
+
TooltipTrigger,
|
|
8
|
+
} from "@/components/ui/tooltip";
|
|
9
|
+
import { cn } from "@/lib/utils";
|
|
10
|
+
|
|
11
|
+
export type AlignmentHorizontal = "left" | "center" | "right";
|
|
12
|
+
export type AlignmentVertical = "top" | "middle" | "bottom";
|
|
13
|
+
export type DistributionAxis = "horizontal" | "vertical";
|
|
14
|
+
|
|
15
|
+
export interface AlignmentMatrixValue {
|
|
16
|
+
horizontal: AlignmentHorizontal;
|
|
17
|
+
vertical: AlignmentVertical;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AlignmentMatrixLabels {
|
|
21
|
+
title: string;
|
|
22
|
+
alignTopLeft: string;
|
|
23
|
+
alignTopCenter: string;
|
|
24
|
+
alignTopRight: string;
|
|
25
|
+
alignMiddleLeft: string;
|
|
26
|
+
alignCenter: string;
|
|
27
|
+
alignMiddleRight: string;
|
|
28
|
+
alignBottomLeft: string;
|
|
29
|
+
alignBottomCenter: string;
|
|
30
|
+
alignBottomRight: string;
|
|
31
|
+
distributeHorizontal: string;
|
|
32
|
+
distributeVertical: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface AlignmentMatrixProps {
|
|
36
|
+
value: AlignmentMatrixValue;
|
|
37
|
+
onChange: (value: AlignmentMatrixValue) => void;
|
|
38
|
+
onDistribute?: (axis: DistributionAxis) => void;
|
|
39
|
+
labels?: Partial<AlignmentMatrixLabels>;
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
className?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type MatrixIcon = ComponentType<{ className?: string }>;
|
|
45
|
+
|
|
46
|
+
const DEFAULT_LABELS: AlignmentMatrixLabels = {
|
|
47
|
+
title: "Align", // i18n-ignore fallback component label
|
|
48
|
+
alignTopLeft: "Align top left", // i18n-ignore fallback component label
|
|
49
|
+
alignTopCenter: "Align top center", // i18n-ignore fallback component label
|
|
50
|
+
alignTopRight: "Align top right", // i18n-ignore fallback component label
|
|
51
|
+
alignMiddleLeft: "Align middle left", // i18n-ignore fallback component label
|
|
52
|
+
alignCenter: "Align center", // i18n-ignore fallback component label
|
|
53
|
+
alignMiddleRight: "Align middle right", // i18n-ignore fallback component label
|
|
54
|
+
alignBottomLeft: "Align bottom left", // i18n-ignore fallback component label
|
|
55
|
+
alignBottomCenter: "Align bottom center", // i18n-ignore fallback component label
|
|
56
|
+
alignBottomRight: "Align bottom right", // i18n-ignore fallback component label
|
|
57
|
+
distributeHorizontal: "Distribute horizontal spacing", // i18n-ignore fallback component label
|
|
58
|
+
distributeVertical: "Distribute vertical spacing", // i18n-ignore fallback component label
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const MATRIX_OPTIONS: Array<{
|
|
62
|
+
horizontal: AlignmentHorizontal;
|
|
63
|
+
vertical: AlignmentVertical;
|
|
64
|
+
labelKey: keyof AlignmentMatrixLabels;
|
|
65
|
+
}> = [
|
|
66
|
+
{ horizontal: "left", vertical: "top", labelKey: "alignTopLeft" },
|
|
67
|
+
{ horizontal: "center", vertical: "top", labelKey: "alignTopCenter" },
|
|
68
|
+
{ horizontal: "right", vertical: "top", labelKey: "alignTopRight" },
|
|
69
|
+
{ horizontal: "left", vertical: "middle", labelKey: "alignMiddleLeft" },
|
|
70
|
+
{ horizontal: "center", vertical: "middle", labelKey: "alignCenter" },
|
|
71
|
+
{ horizontal: "right", vertical: "middle", labelKey: "alignMiddleRight" },
|
|
72
|
+
{ horizontal: "left", vertical: "bottom", labelKey: "alignBottomLeft" },
|
|
73
|
+
{ horizontal: "center", vertical: "bottom", labelKey: "alignBottomCenter" },
|
|
74
|
+
{ horizontal: "right", vertical: "bottom", labelKey: "alignBottomRight" },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
/** Figma-style alignment cell: blue bars when active, faint dot when inactive. */
|
|
78
|
+
function AlignmentCell({
|
|
79
|
+
horizontal,
|
|
80
|
+
vertical,
|
|
81
|
+
active,
|
|
82
|
+
label,
|
|
83
|
+
disabled,
|
|
84
|
+
onClick,
|
|
85
|
+
}: {
|
|
86
|
+
horizontal: AlignmentHorizontal;
|
|
87
|
+
vertical: AlignmentVertical;
|
|
88
|
+
active: boolean;
|
|
89
|
+
label: string;
|
|
90
|
+
disabled: boolean;
|
|
91
|
+
onClick: () => void;
|
|
92
|
+
}) {
|
|
93
|
+
// The active cell shows blue bars representing the alignment direction.
|
|
94
|
+
// Inactive cells show a small faint dot.
|
|
95
|
+
return (
|
|
96
|
+
<Tooltip>
|
|
97
|
+
<TooltipTrigger asChild>
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
aria-label={label}
|
|
101
|
+
aria-pressed={active}
|
|
102
|
+
disabled={disabled}
|
|
103
|
+
onClick={onClick}
|
|
104
|
+
className={cn(
|
|
105
|
+
"flex size-[26px] items-center justify-center rounded-sm transition-colors",
|
|
106
|
+
"hover:bg-[var(--design-editor-control-bg)]",
|
|
107
|
+
disabled && "pointer-events-none opacity-40",
|
|
108
|
+
)}
|
|
109
|
+
>
|
|
110
|
+
{active ? (
|
|
111
|
+
<AlignmentBars horizontal={horizontal} vertical={vertical} />
|
|
112
|
+
) : (
|
|
113
|
+
<span
|
|
114
|
+
className="block size-1 rounded-full bg-current opacity-25"
|
|
115
|
+
aria-hidden="true"
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
118
|
+
</button>
|
|
119
|
+
</TooltipTrigger>
|
|
120
|
+
<TooltipContent className="text-xs">{label}</TooltipContent>
|
|
121
|
+
</Tooltip>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Renders the Figma-style blue bars for the active alignment cell.
|
|
127
|
+
* The bars are drawn as short lines showing the items packed
|
|
128
|
+
* against the given horizontal + vertical edge.
|
|
129
|
+
*/
|
|
130
|
+
function AlignmentBars({
|
|
131
|
+
horizontal,
|
|
132
|
+
vertical,
|
|
133
|
+
}: {
|
|
134
|
+
horizontal: AlignmentHorizontal;
|
|
135
|
+
vertical: AlignmentVertical;
|
|
136
|
+
}) {
|
|
137
|
+
// We draw 2-3 small bars inside a tiny box to indicate alignment direction.
|
|
138
|
+
// The bars are positioned based on which corner/edge is active.
|
|
139
|
+
const accent = "var(--design-editor-accent-color, #18a0fb)";
|
|
140
|
+
|
|
141
|
+
// Determine the transform for the inner bars container
|
|
142
|
+
// based on alignment position within the 16×16 drawing area
|
|
143
|
+
const justifyClass =
|
|
144
|
+
horizontal === "left"
|
|
145
|
+
? "justify-start"
|
|
146
|
+
: horizontal === "right"
|
|
147
|
+
? "justify-end"
|
|
148
|
+
: "justify-center";
|
|
149
|
+
|
|
150
|
+
const alignClass =
|
|
151
|
+
vertical === "top"
|
|
152
|
+
? "items-start"
|
|
153
|
+
: vertical === "bottom"
|
|
154
|
+
? "items-end"
|
|
155
|
+
: "items-center";
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<svg
|
|
159
|
+
viewBox="0 0 14 14"
|
|
160
|
+
width={14}
|
|
161
|
+
height={14}
|
|
162
|
+
fill="none"
|
|
163
|
+
aria-hidden="true"
|
|
164
|
+
>
|
|
165
|
+
{/* Outer frame (faint) */}
|
|
166
|
+
<rect
|
|
167
|
+
x="0.5"
|
|
168
|
+
y="0.5"
|
|
169
|
+
width="13"
|
|
170
|
+
height="13"
|
|
171
|
+
rx="1"
|
|
172
|
+
stroke={accent}
|
|
173
|
+
strokeWidth="1"
|
|
174
|
+
opacity="0.35"
|
|
175
|
+
/>
|
|
176
|
+
{/* Inner content bars — positioned by alignment */}
|
|
177
|
+
<AlignmentBarsContent
|
|
178
|
+
horizontal={horizontal}
|
|
179
|
+
vertical={vertical}
|
|
180
|
+
accent={accent}
|
|
181
|
+
/>
|
|
182
|
+
</svg>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function AlignmentBarsContent({
|
|
187
|
+
horizontal,
|
|
188
|
+
vertical,
|
|
189
|
+
accent,
|
|
190
|
+
}: {
|
|
191
|
+
horizontal: AlignmentHorizontal;
|
|
192
|
+
vertical: AlignmentVertical;
|
|
193
|
+
accent: string;
|
|
194
|
+
}) {
|
|
195
|
+
// Draw 2 bars (representing child items) packed toward the alignment edge.
|
|
196
|
+
// The bars are thin rectangles with rounded caps.
|
|
197
|
+
const barH = 2; // bar height in px
|
|
198
|
+
const barW = [4, 3]; // varying widths for visual interest
|
|
199
|
+
const gap = 1.5; // gap between bars
|
|
200
|
+
const totalH = barH * 2 + gap;
|
|
201
|
+
const totalW = Math.max(...barW);
|
|
202
|
+
|
|
203
|
+
// Y position based on vertical alignment
|
|
204
|
+
const yStart =
|
|
205
|
+
vertical === "top"
|
|
206
|
+
? 2.5
|
|
207
|
+
: vertical === "bottom"
|
|
208
|
+
? 14 - 2.5 - totalH
|
|
209
|
+
: (14 - totalH) / 2;
|
|
210
|
+
|
|
211
|
+
// X positions for the bars based on horizontal alignment
|
|
212
|
+
const getBarX = (w: number) => {
|
|
213
|
+
if (horizontal === "left") return 2.5;
|
|
214
|
+
if (horizontal === "right") return 14 - 2.5 - w;
|
|
215
|
+
return (14 - w) / 2;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
return (
|
|
219
|
+
<>
|
|
220
|
+
<rect
|
|
221
|
+
x={getBarX(barW[0]!)}
|
|
222
|
+
y={yStart}
|
|
223
|
+
width={barW[0]}
|
|
224
|
+
height={barH}
|
|
225
|
+
rx={0.5}
|
|
226
|
+
fill={accent}
|
|
227
|
+
/>
|
|
228
|
+
<rect
|
|
229
|
+
x={getBarX(barW[1]!)}
|
|
230
|
+
y={yStart + barH + gap}
|
|
231
|
+
width={barW[1]}
|
|
232
|
+
height={barH}
|
|
233
|
+
rx={0.5}
|
|
234
|
+
fill={accent}
|
|
235
|
+
/>
|
|
236
|
+
</>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function AlignmentMatrix({
|
|
241
|
+
value,
|
|
242
|
+
onChange,
|
|
243
|
+
onDistribute,
|
|
244
|
+
labels,
|
|
245
|
+
disabled = false,
|
|
246
|
+
className,
|
|
247
|
+
}: AlignmentMatrixProps) {
|
|
248
|
+
const copy = { ...DEFAULT_LABELS, ...labels };
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<TooltipProvider delayDuration={250}>
|
|
252
|
+
<div className={cn("space-y-0", className)}>
|
|
253
|
+
{/* 3×3 dot grid — Figma style */}
|
|
254
|
+
<div
|
|
255
|
+
className={cn(
|
|
256
|
+
"grid grid-cols-3 rounded-md border border-[var(--design-editor-control-border,hsl(var(--border)))]",
|
|
257
|
+
"bg-[var(--design-editor-control-bg)] p-0.5",
|
|
258
|
+
)}
|
|
259
|
+
style={{ width: 84 }}
|
|
260
|
+
>
|
|
261
|
+
{MATRIX_OPTIONS.map((option) => {
|
|
262
|
+
const active =
|
|
263
|
+
option.horizontal === value.horizontal &&
|
|
264
|
+
option.vertical === value.vertical;
|
|
265
|
+
return (
|
|
266
|
+
<AlignmentCell
|
|
267
|
+
key={`${option.horizontal}-${option.vertical}`}
|
|
268
|
+
horizontal={option.horizontal}
|
|
269
|
+
vertical={option.vertical}
|
|
270
|
+
active={active}
|
|
271
|
+
label={copy[option.labelKey]}
|
|
272
|
+
disabled={disabled}
|
|
273
|
+
onClick={() =>
|
|
274
|
+
onChange({
|
|
275
|
+
horizontal: option.horizontal,
|
|
276
|
+
vertical: option.vertical,
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
})}
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</TooltipProvider>
|
|
285
|
+
);
|
|
286
|
+
}
|