@agent-native/core 0.92.10 → 0.92.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +23 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +181 -15
- package/corpus/core/src/agent/run-manager.ts +31 -4
- package/corpus/core/src/agent/run-store.ts +80 -0
- package/corpus/core/src/cli/design-connect.ts +433 -151
- package/corpus/core/src/cli/skills.ts +14 -0
- package/corpus/core/src/client/AssistantChat.tsx +25 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +40 -6
- package/corpus/core/src/client/agent-chat.ts +165 -1
- package/corpus/core/src/client/chat/index.ts +9 -1
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
- package/corpus/core/src/client/index.ts +5 -0
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
- package/corpus/core/src/collab/awareness-store.ts +23 -12
- package/corpus/core/src/collab/client.ts +16 -5
- package/corpus/core/src/collab/index.ts +4 -0
- package/corpus/core/src/collab/recent-edits.ts +65 -2
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
- package/corpus/core/src/server/builder-design-systems.ts +30 -4
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/create-recording.ts +2 -0
- package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
- package/corpus/templates/clips/actions/request-transcript.ts +102 -33
- package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +48 -4
- package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
- package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
- package/corpus/templates/clips/app/routes/record.tsx +17 -4
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +12 -2
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
- package/corpus/templates/clips/desktop/src/styles.css +6 -3
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
- package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
- package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
- package/corpus/templates/clips/shared/recording-core.ts +12 -0
- package/corpus/templates/content/AGENTS.md +7 -6
- package/corpus/templates/content/actions/_document-flush.ts +132 -17
- package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
- package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/pull-document.ts +5 -7
- package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
- package/corpus/templates/content/actions/push-notion-page.ts +10 -0
- package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
- package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
- package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/content/app/i18n-data.ts +18 -0
- package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
- package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
- package/corpus/templates/design/AGENTS.md +45 -10
- package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
- package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
- package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
- package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
- package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
- package/corpus/templates/design/actions/generate-design.ts +79 -12
- package/corpus/templates/design/actions/generate-screens.ts +57 -12
- package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
- package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
- package/corpus/templates/design/actions/import-design-source.ts +4 -31
- package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
- package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/design/actions/list-design-components.ts +104 -0
- package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
- package/corpus/templates/design/actions/open-component-source.ts +2 -4
- package/corpus/templates/design/actions/present-design-variants.ts +412 -16
- package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
- package/corpus/templates/design/actions/run-design-audit.ts +25 -3
- package/corpus/templates/design/actions/show-design-questions.ts +10 -0
- package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
- package/corpus/templates/design/actions/write-local-file.ts +25 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
- package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
- package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
- package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
- package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
- package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
- package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
- package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
- package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
- package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
- package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
- package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
- package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
- package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
- package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
- package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
- package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
- package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
- package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
- package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
- package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
- package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
- package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
- package/corpus/templates/design/app/components/design/types.ts +33 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
- package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
- package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
- package/corpus/templates/design/app/i18n-data.ts +1217 -10
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
- package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
- package/corpus/templates/design/app/lib/design-import.ts +24 -0
- package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
- package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
- package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
- package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
- package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
- package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +3 -6
- package/corpus/templates/design/e2e/helpers.ts +27 -6
- package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
- package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
- package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
- package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
- package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
- package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
- package/corpus/templates/design/server/plugins/db.ts +41 -0
- package/corpus/templates/design/server/source-workspace.ts +64 -0
- package/corpus/templates/design/shared/board-file.ts +13 -2
- package/corpus/templates/design/shared/canvas-math.ts +231 -33
- package/corpus/templates/design/shared/code-layer.ts +122 -8
- package/corpus/templates/design/shared/component-library.ts +161 -0
- package/corpus/templates/design/shared/db-conflict.ts +27 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
- package/corpus/templates/design/shared/figma-url.ts +149 -0
- package/corpus/templates/design/shared/pen-path.ts +16 -7
- package/corpus/templates/design/shared/source-mode.ts +1 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
- package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
- package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
- package/dist/agent/production-agent.d.ts +79 -6
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +161 -14
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +29 -5
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +46 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +61 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/design-connect.d.ts +6 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +336 -139
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +14 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +19 -3
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +38 -18
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +60 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +122 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +36 -2
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/collab/awareness-store.d.ts +5 -0
- package/dist/collab/awareness-store.d.ts.map +1 -1
- package/dist/collab/awareness-store.js +19 -12
- package/dist/collab/awareness-store.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +13 -5
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.d.ts +1 -0
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +1 -0
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/recent-edits.d.ts +3 -1
- package/dist/collab/recent-edits.d.ts.map +1 -1
- package/dist/collab/recent-edits.js +57 -2
- package/dist/collab/recent-edits.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +87 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/builder-design-systems.d.ts +15 -0
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +9 -4
- package/dist/server/builder-design-systems.js.map +1 -1
- package/package.json +1 -1
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
type GlslShaderPanelContext,
|
|
38
38
|
} from "../inspector/GlslShaderPanel";
|
|
39
39
|
import type { ElementInfo } from "../types";
|
|
40
|
-
import {
|
|
40
|
+
import { elementStableKey } from "./element-identity";
|
|
41
41
|
import { FieldTrailer } from "./field-primitives";
|
|
42
42
|
import { splitCssLayers } from "./fill-gradient-helpers";
|
|
43
43
|
import {
|
|
@@ -50,8 +50,10 @@ import {
|
|
|
50
50
|
colorHasVisibleAlpha,
|
|
51
51
|
compactCssValue,
|
|
52
52
|
cssColorOrFallback,
|
|
53
|
+
roundToOneDecimal,
|
|
53
54
|
swatchStyle,
|
|
54
55
|
} from "./position-helpers";
|
|
56
|
+
import { isMixedValue } from "./selection-helpers";
|
|
55
57
|
import type {
|
|
56
58
|
MotionKeyframeFieldContext,
|
|
57
59
|
StyleChangeHandler,
|
|
@@ -59,7 +61,7 @@ import type {
|
|
|
59
61
|
StylesChangeHandler,
|
|
60
62
|
} from "./style-change-types";
|
|
61
63
|
|
|
62
|
-
interface ShadowLayer {
|
|
64
|
+
export interface ShadowLayer {
|
|
63
65
|
id: string;
|
|
64
66
|
x: number;
|
|
65
67
|
y: number;
|
|
@@ -81,7 +83,7 @@ function defaultDropShadowLayer(index: number): ShadowLayer {
|
|
|
81
83
|
};
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
function parseShadowLayers(value: string | undefined): ShadowLayer[] {
|
|
86
|
+
export function parseShadowLayers(value: string | undefined): ShadowLayer[] {
|
|
85
87
|
return splitCssLayers(value || "")
|
|
86
88
|
.filter((layer) => layer && layer !== "none")
|
|
87
89
|
.map((layer, index) => parseShadowLayer(layer, index));
|
|
@@ -133,18 +135,18 @@ function splitCssTokens(value: string): string[] {
|
|
|
133
135
|
return tokens;
|
|
134
136
|
}
|
|
135
137
|
|
|
136
|
-
function serializeShadowLayers(layers: ShadowLayer[]) {
|
|
138
|
+
export function serializeShadowLayers(layers: ShadowLayer[]) {
|
|
137
139
|
if (!layers.length) return "none";
|
|
138
140
|
return layers
|
|
139
141
|
.map((layer) =>
|
|
140
142
|
[
|
|
141
143
|
layer.inset ? "inset" : "",
|
|
142
|
-
`${
|
|
143
|
-
`${
|
|
144
|
-
`${Math.max(0,
|
|
144
|
+
`${roundToOneDecimal(layer.x)}px`,
|
|
145
|
+
`${roundToOneDecimal(layer.y)}px`,
|
|
146
|
+
`${Math.max(0, roundToOneDecimal(layer.blur))}px`,
|
|
145
147
|
// Spread radius may legitimately be negative for either inset or
|
|
146
148
|
// drop shadows — only blur-radius is clamped to >= 0 in CSS.
|
|
147
|
-
`${
|
|
149
|
+
`${roundToOneDecimal(layer.spread)}px`,
|
|
148
150
|
layer.color,
|
|
149
151
|
]
|
|
150
152
|
.filter(Boolean)
|
|
@@ -153,8 +155,8 @@ function serializeShadowLayers(layers: ShadowLayer[]) {
|
|
|
153
155
|
.join(", ");
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
function readBlurFilter(value: string | undefined): number {
|
|
157
|
-
const match = value?.match(/blur\((
|
|
158
|
+
export function readBlurFilter(value: string | undefined): number {
|
|
159
|
+
const match = value?.match(/blur\((-?(?:\d+(?:\.\d+)?|\.\d+))px\)/);
|
|
158
160
|
return match ? Math.max(0, Number(match[1])) : 0;
|
|
159
161
|
}
|
|
160
162
|
|
|
@@ -162,12 +164,62 @@ function hasBlurFilter(value: string | undefined): boolean {
|
|
|
162
164
|
return /blur\(/.test(value || "");
|
|
163
165
|
}
|
|
164
166
|
|
|
165
|
-
function setBlurFilterValue(
|
|
166
|
-
|
|
167
|
+
export function setBlurFilterValue(
|
|
168
|
+
value: string | undefined,
|
|
169
|
+
blur: number,
|
|
170
|
+
): string {
|
|
171
|
+
const blurFn = `blur(${Math.max(0, roundToOneDecimal(blur))}px)`;
|
|
167
172
|
const existing = compactCssValue(value, "");
|
|
168
173
|
return existing.includes("blur(")
|
|
169
174
|
? existing.replace(/blur\([^)]*\)/, blurFn)
|
|
170
|
-
:
|
|
175
|
+
: existing && existing !== "none"
|
|
176
|
+
? `${existing} ${blurFn}`
|
|
177
|
+
: blurFn;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Remove only the layer/background blur function, preserving every sibling
|
|
181
|
+
* CSS filter (brightness, contrast, drop-shadow, etc.). Figma models layer
|
|
182
|
+
* blur as one effect row; deleting that row must not delete the other effects
|
|
183
|
+
* that happen to share CSS's `filter`/`backdrop-filter` declaration. */
|
|
184
|
+
export function removeBlurFilterValue(value: string | undefined): string {
|
|
185
|
+
const existing = compactCssValue(value, "");
|
|
186
|
+
if (!existing || existing === "none") return "none";
|
|
187
|
+
const remaining = existing
|
|
188
|
+
.replace(/blur\([^)]*\)/g, " ")
|
|
189
|
+
.replace(/\s+/g, " ")
|
|
190
|
+
.trim();
|
|
191
|
+
return remaining || "none";
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Keep the transient original-opacity stash attached to the same shadow when
|
|
195
|
+
* positional CSS layers are reordered or removed. Parsed shadow ids are
|
|
196
|
+
* necessarily index-based (`shadow-0`, `shadow-1`, …); after a reorder the
|
|
197
|
+
* next computed-style read regenerates those ids in the new order. Without
|
|
198
|
+
* remapping, a hidden shadow's saved alpha stays at its old index and the eye
|
|
199
|
+
* button restores the wrong layer (or falls back to 25%). */
|
|
200
|
+
export function remapIndexedShadowStash(
|
|
201
|
+
stash: Record<string, string>,
|
|
202
|
+
elementKey: string,
|
|
203
|
+
nextLayers: readonly Pick<ShadowLayer, "id">[],
|
|
204
|
+
): Record<string, string> {
|
|
205
|
+
const prefix = `${elementKey}:shadow:`;
|
|
206
|
+
const moved = nextLayers.flatMap((layer, index) => {
|
|
207
|
+
const value = stash[`${prefix}${layer.id}`];
|
|
208
|
+
return value === undefined ? [] : [[`${prefix}shadow-${index}`, value]];
|
|
209
|
+
});
|
|
210
|
+
if (!Object.keys(stash).some((key) => key.startsWith(prefix))) return stash;
|
|
211
|
+
const next = Object.fromEntries(
|
|
212
|
+
Object.entries(stash).filter(([key]) => !key.startsWith(prefix)),
|
|
213
|
+
);
|
|
214
|
+
for (const [key, value] of moved) next[key] = value;
|
|
215
|
+
const stashEntries = Object.entries(stash);
|
|
216
|
+
if (
|
|
217
|
+
stashEntries.length === Object.keys(next).length &&
|
|
218
|
+
stashEntries.every(([key, value]) => next[key] === value)
|
|
219
|
+
) {
|
|
220
|
+
return stash;
|
|
221
|
+
}
|
|
222
|
+
return next;
|
|
171
223
|
}
|
|
172
224
|
|
|
173
225
|
function shadowColorWithOpacity(color: string, opacity: number): string {
|
|
@@ -179,6 +231,33 @@ function shadowColorWithOpacity(color: string, opacity: number): string {
|
|
|
179
231
|
: color;
|
|
180
232
|
}
|
|
181
233
|
|
|
234
|
+
/**
|
|
235
|
+
* True when the current multi-selection has differing box-shadow, filter,
|
|
236
|
+
* or backdrop-filter values (the synthetic mixed-selection ElementInfo
|
|
237
|
+
* reports the `MIXED_VALUE`/"Mixed" sentinel for any style property that
|
|
238
|
+
* disagrees across the selection — see selection-helpers.ts). Effects had no
|
|
239
|
+
* mixed-selection handling at all: `parseShadowLayers("Mixed")` would parse
|
|
240
|
+
* the literal sentinel string as a bogus single shadow layer (color:
|
|
241
|
+
* "Mixed", the rest defaulted), and editing any of its fields would commit
|
|
242
|
+
* an invalid `box-shadow: ... Mixed` to every selected element. Fill and
|
|
243
|
+
* Stroke both already gate their sections on an equivalent mixed check and
|
|
244
|
+
* show a "Click + to replace" hint instead of rendering broken per-field
|
|
245
|
+
* controls; Effects needs the same gate.
|
|
246
|
+
*/
|
|
247
|
+
export function effectsSelectionIsMixed(styles: {
|
|
248
|
+
boxShadow?: string;
|
|
249
|
+
filter?: string;
|
|
250
|
+
backdropFilter?: string;
|
|
251
|
+
webkitBackdropFilter?: string;
|
|
252
|
+
}): boolean {
|
|
253
|
+
return [
|
|
254
|
+
styles.boxShadow,
|
|
255
|
+
styles.filter,
|
|
256
|
+
styles.backdropFilter,
|
|
257
|
+
styles.webkitBackdropFilter,
|
|
258
|
+
].some(isMixedValue);
|
|
259
|
+
}
|
|
260
|
+
|
|
182
261
|
function ShadowEffectRow({
|
|
183
262
|
layer,
|
|
184
263
|
index,
|
|
@@ -376,22 +455,37 @@ export function EffectsProperties({
|
|
|
376
455
|
const t = useT();
|
|
377
456
|
const [shaderPickerOpen, setShaderPickerOpen] = useState(false);
|
|
378
457
|
const styles = element.computedStyles;
|
|
379
|
-
const blurValue = readBlurFilter(styles.filter);
|
|
380
|
-
const filterHasBlur = hasBlurFilter(styles.filter);
|
|
381
458
|
// M5 · Background (backdrop) blur is a distinct design effect type, backed by
|
|
382
459
|
// CSS `backdrop-filter: blur()` (vs layer blur's `filter: blur()`).
|
|
383
460
|
const backdropFilterValue =
|
|
384
461
|
styles.backdropFilter || styles.webkitBackdropFilter;
|
|
385
|
-
|
|
462
|
+
// Differing box-shadow/filter/backdrop-filter across a multi-selection —
|
|
463
|
+
// gates the whole section to a "Click + to replace" hint below, same as
|
|
464
|
+
// Fill/Stroke, instead of parsing the "Mixed" sentinel as real CSS.
|
|
465
|
+
const effectsAreMixed = effectsSelectionIsMixed({
|
|
466
|
+
boxShadow: styles.boxShadow,
|
|
467
|
+
filter: styles.filter,
|
|
468
|
+
backdropFilter: styles.backdropFilter,
|
|
469
|
+
webkitBackdropFilter: styles.webkitBackdropFilter,
|
|
470
|
+
});
|
|
471
|
+
const blurValue = readBlurFilter(styles.filter);
|
|
472
|
+
const filterHasBlur = !effectsAreMixed && hasBlurFilter(styles.filter);
|
|
473
|
+
const backdropFilterHasBlur =
|
|
474
|
+
!effectsAreMixed && hasBlurFilter(backdropFilterValue);
|
|
386
475
|
const backdropBlurValue = readBlurFilter(backdropFilterValue);
|
|
387
476
|
const [hiddenEffectStash, setHiddenEffectStash] = useState<
|
|
388
477
|
Record<string, string>
|
|
389
478
|
>({});
|
|
390
|
-
const effectStashKey =
|
|
479
|
+
const effectStashKey = elementStableKey(element);
|
|
391
480
|
const layerBlurStashKey = `${effectStashKey}:filter:blur`;
|
|
392
481
|
const backdropBlurStashKey = `${effectStashKey}:backdrop-filter:blur`;
|
|
393
|
-
const shadowLayers =
|
|
482
|
+
const shadowLayers = effectsAreMixed
|
|
483
|
+
? []
|
|
484
|
+
: parseShadowLayers(styles.boxShadow);
|
|
394
485
|
const setShadowLayers = (layers: ShadowLayer[], meta?: StyleChangeMeta) => {
|
|
486
|
+
setHiddenEffectStash((stash) =>
|
|
487
|
+
remapIndexedShadowStash(stash, effectStashKey, layers),
|
|
488
|
+
);
|
|
395
489
|
const boxShadow = serializeShadowLayers(layers);
|
|
396
490
|
if (onStylesChange) onStylesChange({ boxShadow }, meta);
|
|
397
491
|
else onStyleChange("boxShadow", boxShadow, meta);
|
|
@@ -401,8 +495,10 @@ export function EffectsProperties({
|
|
|
401
495
|
...shadowLayers,
|
|
402
496
|
defaultDropShadowLayer(shadowLayers.length),
|
|
403
497
|
]);
|
|
404
|
-
const addLayerBlur = () =>
|
|
405
|
-
|
|
498
|
+
const addLayerBlur = () =>
|
|
499
|
+
onStyleChange("filter", setBlurFilterValue(styles.filter, 4));
|
|
500
|
+
const addBackgroundBlur = () =>
|
|
501
|
+
onStyleChange("backdropFilter", setBlurFilterValue(backdropFilterValue, 8));
|
|
406
502
|
const reorderShadowLayers = (from: number, to: number) => {
|
|
407
503
|
const next = [...shadowLayers];
|
|
408
504
|
const [moved] = next.splice(from, 1);
|
|
@@ -443,6 +539,7 @@ export function EffectsProperties({
|
|
|
443
539
|
// `!effectMount && !pickerOpen` early-return so opening the picker doesn't
|
|
444
540
|
// get swallowed by this outer gate before it can render itself.
|
|
445
541
|
const hasEffectsContent =
|
|
542
|
+
effectsAreMixed ||
|
|
446
543
|
shadowLayers.length > 0 ||
|
|
447
544
|
filterHasBlur ||
|
|
448
545
|
backdropFilterHasBlur ||
|
|
@@ -506,262 +603,291 @@ export function EffectsProperties({
|
|
|
506
603
|
>
|
|
507
604
|
{hasEffectsContent ? (
|
|
508
605
|
<>
|
|
509
|
-
{
|
|
510
|
-
<
|
|
511
|
-
{
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
606
|
+
{effectsAreMixed ? (
|
|
607
|
+
<p className="px-1.5 py-2 !text-[11px] text-muted-foreground">
|
|
608
|
+
{
|
|
609
|
+
"Click + to replace mixed content" /* i18n-ignore figma mixed effects hint */
|
|
610
|
+
}
|
|
611
|
+
</p>
|
|
612
|
+
) : (
|
|
613
|
+
<>
|
|
614
|
+
{shadowLayers.length ? (
|
|
615
|
+
<div className="space-y-1.5">
|
|
616
|
+
{shadowLayers.map((layer, index) => (
|
|
617
|
+
<ShadowEffectRow
|
|
618
|
+
key={layer.id}
|
|
619
|
+
layer={layer}
|
|
620
|
+
index={index}
|
|
621
|
+
dragHandleLabel={t("editPanel.labels.reorderLayer")}
|
|
622
|
+
dropIndicator={
|
|
623
|
+
shadowDrag.dragIndex != null &&
|
|
624
|
+
shadowDrag.overIndex === index
|
|
625
|
+
? shadowDrag.overIndex > shadowDrag.dragIndex
|
|
626
|
+
? "after"
|
|
627
|
+
: "before"
|
|
628
|
+
: null
|
|
629
|
+
}
|
|
630
|
+
rowProps={shadowDrag.getRowProps(index)}
|
|
631
|
+
handleProps={shadowDrag.getHandleProps(index)}
|
|
632
|
+
onChange={(patch, meta) => {
|
|
633
|
+
const next = shadowLayers.map((candidate) =>
|
|
634
|
+
candidate.id === layer.id
|
|
635
|
+
? { ...candidate, ...patch }
|
|
636
|
+
: candidate,
|
|
637
|
+
);
|
|
638
|
+
setShadowLayers(next, meta);
|
|
639
|
+
}}
|
|
640
|
+
onToggleVisibility={() => {
|
|
641
|
+
const visible = colorHasVisibleAlpha(layer.color);
|
|
642
|
+
const shadowStashKey = `${effectStashKey}:shadow:${layer.id}`;
|
|
643
|
+
if (visible) {
|
|
644
|
+
setHiddenEffectStash((prev) => ({
|
|
645
|
+
...prev,
|
|
646
|
+
[shadowStashKey]: layer.color,
|
|
647
|
+
}));
|
|
648
|
+
const next = shadowLayers.map((candidate) =>
|
|
649
|
+
candidate.id === layer.id
|
|
650
|
+
? {
|
|
651
|
+
...candidate,
|
|
652
|
+
color: shadowColorWithOpacity(
|
|
653
|
+
candidate.color,
|
|
654
|
+
0,
|
|
655
|
+
),
|
|
656
|
+
}
|
|
657
|
+
: candidate,
|
|
658
|
+
);
|
|
659
|
+
setShadowLayers(next);
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
554
662
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
663
|
+
const restored =
|
|
664
|
+
hiddenEffectStash[shadowStashKey] ??
|
|
665
|
+
shadowColorWithOpacity(layer.color, 25);
|
|
666
|
+
setHiddenEffectStash((prev) => {
|
|
667
|
+
const next = { ...prev };
|
|
668
|
+
delete next[shadowStashKey];
|
|
669
|
+
return next;
|
|
670
|
+
});
|
|
671
|
+
const next = shadowLayers.map((candidate) =>
|
|
672
|
+
candidate.id === layer.id
|
|
673
|
+
? { ...candidate, color: restored }
|
|
674
|
+
: candidate,
|
|
675
|
+
);
|
|
676
|
+
setShadowLayers(next);
|
|
677
|
+
}}
|
|
678
|
+
onRemove={() =>
|
|
679
|
+
setShadowLayers(
|
|
680
|
+
shadowLayers.filter(
|
|
681
|
+
(candidate) => candidate.id !== layer.id,
|
|
682
|
+
),
|
|
683
|
+
)
|
|
684
|
+
}
|
|
685
|
+
element={element}
|
|
686
|
+
motionKeyframeContext={motionKeyframeContext}
|
|
687
|
+
/>
|
|
688
|
+
))}
|
|
689
|
+
</div>
|
|
690
|
+
) : null}
|
|
691
|
+
{filterHasBlur ? (
|
|
692
|
+
/* design effect row for layer blur: flat row matching shadow rows */
|
|
693
|
+
<Popover>
|
|
694
|
+
<div className="group flex items-center gap-1.5">
|
|
695
|
+
<PopoverTrigger asChild>
|
|
696
|
+
<button
|
|
697
|
+
type="button"
|
|
698
|
+
className="flex h-6 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-1.5 text-left !text-[11px] hover:bg-[var(--design-editor-panel-raised-bg)]"
|
|
699
|
+
>
|
|
700
|
+
<span className="min-w-0 flex-1 truncate font-medium text-foreground">
|
|
701
|
+
{t("editPanel.labels.layerBlur")}
|
|
702
|
+
</span>
|
|
703
|
+
<span className="shrink-0 tabular-nums text-muted-foreground">
|
|
704
|
+
{roundToOneDecimal(blurValue)}px
|
|
705
|
+
</span>
|
|
706
|
+
</button>
|
|
707
|
+
</PopoverTrigger>
|
|
708
|
+
<SectionIconButton
|
|
709
|
+
label={
|
|
710
|
+
blurValue > 0
|
|
711
|
+
? t("editPanel.labels.hideLayer")
|
|
712
|
+
: t("editPanel.labels.showLayer")
|
|
713
|
+
}
|
|
714
|
+
onClick={() => {
|
|
715
|
+
if (blurValue > 0) {
|
|
716
|
+
setHiddenEffectStash((prev) => ({
|
|
717
|
+
...prev,
|
|
718
|
+
[layerBlurStashKey]: String(blurValue),
|
|
719
|
+
}));
|
|
720
|
+
onStyleChange(
|
|
721
|
+
"filter",
|
|
722
|
+
setBlurFilterValue(styles.filter, 0),
|
|
723
|
+
);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
618
726
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
setBlurFilterValue(styles.filter, value),
|
|
662
|
-
meta,
|
|
663
|
-
)
|
|
664
|
-
}
|
|
665
|
-
unit="px"
|
|
666
|
-
min={0}
|
|
667
|
-
precision={1}
|
|
668
|
-
labelClassName="w-16"
|
|
669
|
-
inputClassName="h-6"
|
|
670
|
-
/>
|
|
671
|
-
</PopoverContent>
|
|
672
|
-
</Popover>
|
|
673
|
-
) : null}
|
|
674
|
-
{backdropFilterHasBlur ? (
|
|
675
|
-
/* M5 · Background (backdrop) blur effect row — mirrors the layer-blur row */
|
|
676
|
-
<Popover>
|
|
677
|
-
<div className="group flex items-center gap-1.5">
|
|
678
|
-
<PopoverTrigger asChild>
|
|
679
|
-
<button
|
|
680
|
-
type="button"
|
|
681
|
-
className="flex h-6 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-1.5 text-left !text-[11px] hover:bg-[var(--design-editor-panel-raised-bg)]"
|
|
727
|
+
const restored = Number(
|
|
728
|
+
hiddenEffectStash[layerBlurStashKey],
|
|
729
|
+
);
|
|
730
|
+
const nextBlur =
|
|
731
|
+
Number.isFinite(restored) && restored > 0
|
|
732
|
+
? restored
|
|
733
|
+
: 4;
|
|
734
|
+
setHiddenEffectStash((prev) => {
|
|
735
|
+
const next = { ...prev };
|
|
736
|
+
delete next[layerBlurStashKey];
|
|
737
|
+
return next;
|
|
738
|
+
});
|
|
739
|
+
onStyleChange(
|
|
740
|
+
"filter",
|
|
741
|
+
setBlurFilterValue(styles.filter, nextBlur),
|
|
742
|
+
);
|
|
743
|
+
}}
|
|
744
|
+
>
|
|
745
|
+
{blurValue > 0 ? (
|
|
746
|
+
<IconEye className="size-3.5" />
|
|
747
|
+
) : (
|
|
748
|
+
<IconEyeOff className="size-3.5" />
|
|
749
|
+
)}
|
|
750
|
+
</SectionIconButton>
|
|
751
|
+
<SectionIconButton
|
|
752
|
+
label={t("editPanel.labels.removeLayer")}
|
|
753
|
+
onClick={() =>
|
|
754
|
+
onStyleChange(
|
|
755
|
+
"filter",
|
|
756
|
+
removeBlurFilterValue(styles.filter),
|
|
757
|
+
)
|
|
758
|
+
}
|
|
759
|
+
disabled={!filterHasBlur}
|
|
760
|
+
>
|
|
761
|
+
<IconMinus className="size-3.5" />
|
|
762
|
+
</SectionIconButton>
|
|
763
|
+
</div>
|
|
764
|
+
<PopoverContent
|
|
765
|
+
side="left"
|
|
766
|
+
align="start"
|
|
767
|
+
sideOffset={8}
|
|
768
|
+
className="w-56 p-3"
|
|
682
769
|
>
|
|
683
|
-
<
|
|
684
|
-
{"
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
770
|
+
<ScrubInput
|
|
771
|
+
label={t("editPanel.labels.blur")}
|
|
772
|
+
value={blurValue}
|
|
773
|
+
onChange={(value, meta) =>
|
|
774
|
+
onStyleChange(
|
|
775
|
+
"filter",
|
|
776
|
+
setBlurFilterValue(styles.filter, value),
|
|
777
|
+
meta,
|
|
778
|
+
)
|
|
779
|
+
}
|
|
780
|
+
unit="px"
|
|
781
|
+
min={0}
|
|
782
|
+
precision={1}
|
|
783
|
+
labelClassName="w-16"
|
|
784
|
+
inputClassName="h-6"
|
|
785
|
+
/>
|
|
786
|
+
</PopoverContent>
|
|
787
|
+
</Popover>
|
|
788
|
+
) : null}
|
|
789
|
+
{backdropFilterHasBlur ? (
|
|
790
|
+
/* M5 · Background (backdrop) blur effect row — mirrors the layer-blur row */
|
|
791
|
+
<Popover>
|
|
792
|
+
<div className="group flex items-center gap-1.5">
|
|
793
|
+
<PopoverTrigger asChild>
|
|
794
|
+
<button
|
|
795
|
+
type="button"
|
|
796
|
+
className="flex h-6 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-1.5 text-left !text-[11px] hover:bg-[var(--design-editor-panel-raised-bg)]"
|
|
797
|
+
>
|
|
798
|
+
<span className="min-w-0 flex-1 truncate font-medium text-foreground">
|
|
799
|
+
{
|
|
800
|
+
"Background blur" /* i18n-ignore design effect type */
|
|
801
|
+
}
|
|
802
|
+
</span>
|
|
803
|
+
<span className="shrink-0 tabular-nums text-muted-foreground">
|
|
804
|
+
{roundToOneDecimal(backdropBlurValue)}px
|
|
805
|
+
</span>
|
|
806
|
+
</button>
|
|
807
|
+
</PopoverTrigger>
|
|
808
|
+
<SectionIconButton
|
|
809
|
+
label={
|
|
810
|
+
backdropBlurValue > 0
|
|
811
|
+
? t("editPanel.labels.hideLayer")
|
|
812
|
+
: t("editPanel.labels.showLayer")
|
|
813
|
+
}
|
|
814
|
+
onClick={() => {
|
|
815
|
+
if (backdropBlurValue > 0) {
|
|
816
|
+
setHiddenEffectStash((prev) => ({
|
|
817
|
+
...prev,
|
|
818
|
+
[backdropBlurStashKey]: String(backdropBlurValue),
|
|
819
|
+
}));
|
|
820
|
+
onStyleChange(
|
|
821
|
+
"backdropFilter",
|
|
822
|
+
setBlurFilterValue(backdropFilterValue, 0),
|
|
823
|
+
);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
709
826
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
827
|
+
const restored = Number(
|
|
828
|
+
hiddenEffectStash[backdropBlurStashKey],
|
|
829
|
+
);
|
|
830
|
+
const nextBlur =
|
|
831
|
+
Number.isFinite(restored) && restored > 0
|
|
832
|
+
? restored
|
|
833
|
+
: 8;
|
|
834
|
+
setHiddenEffectStash((prev) => {
|
|
835
|
+
const next = { ...prev };
|
|
836
|
+
delete next[backdropBlurStashKey];
|
|
837
|
+
return next;
|
|
838
|
+
});
|
|
839
|
+
onStyleChange(
|
|
840
|
+
"backdropFilter",
|
|
841
|
+
setBlurFilterValue(backdropFilterValue, nextBlur),
|
|
842
|
+
);
|
|
843
|
+
}}
|
|
844
|
+
>
|
|
845
|
+
{backdropBlurValue > 0 ? (
|
|
846
|
+
<IconEye className="size-3.5" />
|
|
847
|
+
) : (
|
|
848
|
+
<IconEyeOff className="size-3.5" />
|
|
849
|
+
)}
|
|
850
|
+
</SectionIconButton>
|
|
851
|
+
<SectionIconButton
|
|
852
|
+
label={t("editPanel.labels.removeLayer")}
|
|
853
|
+
onClick={() =>
|
|
854
|
+
onStyleChange(
|
|
855
|
+
"backdropFilter",
|
|
856
|
+
removeBlurFilterValue(backdropFilterValue),
|
|
857
|
+
)
|
|
858
|
+
}
|
|
859
|
+
disabled={!backdropFilterHasBlur}
|
|
860
|
+
>
|
|
861
|
+
<IconMinus className="size-3.5" />
|
|
862
|
+
</SectionIconButton>
|
|
863
|
+
</div>
|
|
864
|
+
<PopoverContent
|
|
865
|
+
side="left"
|
|
866
|
+
align="start"
|
|
867
|
+
sideOffset={8}
|
|
868
|
+
className="w-56 p-3"
|
|
869
|
+
>
|
|
870
|
+
<ScrubInput
|
|
871
|
+
label={t("editPanel.labels.blur")}
|
|
872
|
+
value={backdropBlurValue}
|
|
873
|
+
onChange={(value, meta) =>
|
|
874
|
+
onStyleChange(
|
|
875
|
+
"backdropFilter",
|
|
876
|
+
setBlurFilterValue(backdropFilterValue, value),
|
|
877
|
+
meta,
|
|
878
|
+
)
|
|
879
|
+
}
|
|
880
|
+
unit="px"
|
|
881
|
+
min={0}
|
|
882
|
+
precision={1}
|
|
883
|
+
labelClassName="w-16"
|
|
884
|
+
inputClassName="h-6"
|
|
885
|
+
/>
|
|
886
|
+
</PopoverContent>
|
|
887
|
+
</Popover>
|
|
888
|
+
) : null}
|
|
889
|
+
</>
|
|
890
|
+
)}
|
|
765
891
|
{glslShaderContext?.nodeId ? (
|
|
766
892
|
/* Code-backed GLSL shader effect — overlay canvas above the
|
|
767
893
|
element's content, persisted as editable GLSL in the screen HTML
|