@agent-native/core 0.92.10 → 0.92.12
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 +29 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +214 -17
- package/corpus/core/src/agent/run-manager.ts +72 -14
- package/corpus/core/src/agent/run-store.ts +152 -27
- 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-adapter.ts +56 -12
- 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 +75 -9
- package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
- package/corpus/templates/clips/app/hooks/use-player-shortcuts.ts +1 -0
- 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/changelog/2026-07-10-fixed-copying-agent-responses-and-transcript-text-from-recor.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/_builder-cms-read-client.ts +82 -7
- package/corpus/templates/content/actions/_database-source-utils.ts +149 -30
- 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/add-content-database-source-field-property.ts +4 -7
- package/corpus/templates/content/actions/attach-content-database-source.ts +41 -17
- package/corpus/templates/content/actions/change-content-database-source-role.ts +46 -8
- 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/actions/suggest-source-join-key.ts +8 -1
- 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-builder-source-refreshes-now-keep-mapped-fields-such-as-topi.md +6 -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/content/shared/api.ts +1 -0
- 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 +82 -7
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +180 -17
- 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 +63 -14
- 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 +129 -22
- 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-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +48 -12
- package/dist/client/agent-chat-adapter.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/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.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/collab/struct-routes.d.ts +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/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- 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
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
IconMinus,
|
|
13
13
|
IconPlus,
|
|
14
14
|
} from "@tabler/icons-react";
|
|
15
|
+
import { useState } from "react";
|
|
15
16
|
|
|
16
17
|
import {
|
|
17
18
|
Popover,
|
|
@@ -24,16 +25,19 @@ import type { GlslShaderPanelContext } from "../inspector/GlslShaderPanel";
|
|
|
24
25
|
import type { ElementInfo } from "../types";
|
|
25
26
|
import { selectionColorValues } from "./document-colors";
|
|
26
27
|
import { isTextElement } from "./element-classification";
|
|
28
|
+
import { elementStableKey } from "./element-identity";
|
|
27
29
|
import { commitStylePatch, FieldTrailer } from "./field-primitives";
|
|
28
30
|
import {
|
|
31
|
+
addFillLayerPatch,
|
|
29
32
|
averageGradientOpacity,
|
|
30
33
|
buildGradientLayer,
|
|
31
|
-
defaultGradientLayer,
|
|
32
34
|
gradientLabel,
|
|
33
35
|
isLayerHiddenBySize,
|
|
34
36
|
joinCssLayers,
|
|
35
37
|
parseGradientLayer,
|
|
38
|
+
removeBaseFillPatch,
|
|
36
39
|
removeFillLayerAtIndex,
|
|
40
|
+
setImageFillLayerPatch,
|
|
37
41
|
splitCssLayers,
|
|
38
42
|
withLayerSizeMarker,
|
|
39
43
|
} from "./fill-gradient-helpers";
|
|
@@ -45,7 +49,6 @@ import {
|
|
|
45
49
|
import { ColorInput, PanelSection } from "./panel-primitives";
|
|
46
50
|
import {
|
|
47
51
|
colorHasVisibleAlpha,
|
|
48
|
-
compactCssValue,
|
|
49
52
|
cssColorOrFallback,
|
|
50
53
|
swatchStyle,
|
|
51
54
|
} from "./position-helpers";
|
|
@@ -57,6 +60,50 @@ import type {
|
|
|
57
60
|
StylesChangeHandler,
|
|
58
61
|
} from "./style-change-types";
|
|
59
62
|
|
|
63
|
+
/**
|
|
64
|
+
* The four `backgroundImage`/`backgroundSize`/`backgroundRepeat`/
|
|
65
|
+
* `backgroundPosition` prop values fed to the base fill row's `<ColorInput>`.
|
|
66
|
+
* Text fills ("color") can't hold a layered paint at all, so every value
|
|
67
|
+
* collapses to "" for them.
|
|
68
|
+
*
|
|
69
|
+
* Factored out (rather than inlined ternaries in the JSX below) as a
|
|
70
|
+
* regression guard: `ColorInput.onImageFillLayerChange` builds its commit
|
|
71
|
+
* patch from whatever it computes internally from these four props (see
|
|
72
|
+
* `imageFillChangePatch` in fill-gradient-helpers.ts). Previously only
|
|
73
|
+
* `backgroundImage` was passed here, so ColorInput treated every sibling
|
|
74
|
+
* layer as having no size/repeat/position of its own — switching this base
|
|
75
|
+
* swatch to Image then rebuilt backgroundSize/backgroundRepeat/
|
|
76
|
+
* backgroundPosition as a single-entry list against the real N+1-layer
|
|
77
|
+
* backgroundImage stack, corrupting every existing layer's size/repeat/
|
|
78
|
+
* position via CSS background-layer-list cycling (e.g. an existing "cover"
|
|
79
|
+
* silently became "auto"). All four must always be sourced together, exactly
|
|
80
|
+
* like PageProperties' background row in EditPanel.tsx.
|
|
81
|
+
*/
|
|
82
|
+
export function baseFillLayerSourceProps(
|
|
83
|
+
styles: Record<string, string>,
|
|
84
|
+
isTextFillElement: boolean,
|
|
85
|
+
): {
|
|
86
|
+
backgroundImage: string;
|
|
87
|
+
backgroundSize: string;
|
|
88
|
+
backgroundRepeat: string;
|
|
89
|
+
backgroundPosition: string;
|
|
90
|
+
} {
|
|
91
|
+
if (isTextFillElement) {
|
|
92
|
+
return {
|
|
93
|
+
backgroundImage: "",
|
|
94
|
+
backgroundSize: "",
|
|
95
|
+
backgroundRepeat: "",
|
|
96
|
+
backgroundPosition: "",
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
backgroundImage: styles.backgroundImage || "",
|
|
101
|
+
backgroundSize: styles.backgroundSize || "",
|
|
102
|
+
backgroundRepeat: styles.backgroundRepeat || "",
|
|
103
|
+
backgroundPosition: styles.backgroundPosition || "",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
60
107
|
export function FillProperties({
|
|
61
108
|
element,
|
|
62
109
|
onStyleChange,
|
|
@@ -87,6 +134,16 @@ export function FillProperties({
|
|
|
87
134
|
const styles = element.computedStyles;
|
|
88
135
|
const isTextFillElement = isTextElement(element);
|
|
89
136
|
const fillProperty = isTextFillElement ? "color" : "backgroundColor";
|
|
137
|
+
// Stash for a hidden layer's real pre-hide backgroundSize (e.g. a custom
|
|
138
|
+
// cover/contain/percentage) so re-showing it restores that value instead
|
|
139
|
+
// of permanently discarding it for "auto" — the same React-state stash
|
|
140
|
+
// pattern effects-properties.tsx uses for hidden shadow/blur effects (see
|
|
141
|
+
// `hiddenEffectStash` there), keyed by element + layer index so unrelated
|
|
142
|
+
// elements/layers never collide.
|
|
143
|
+
const [hiddenFillSizeStash, setHiddenFillSizeStash] = useState<
|
|
144
|
+
Record<string, string>
|
|
145
|
+
>({});
|
|
146
|
+
const fillStashKey = elementStableKey(element);
|
|
90
147
|
const fillValue = isTextFillElement
|
|
91
148
|
? styles.color || ""
|
|
92
149
|
: styles.backgroundColor || "";
|
|
@@ -102,6 +159,10 @@ export function FillProperties({
|
|
|
102
159
|
const backgroundPositionLayers = isTextFillElement
|
|
103
160
|
? []
|
|
104
161
|
: splitCssLayers(styles.backgroundPosition || "");
|
|
162
|
+
const baseFillLayerProps = baseFillLayerSourceProps(
|
|
163
|
+
styles,
|
|
164
|
+
isTextFillElement,
|
|
165
|
+
);
|
|
105
166
|
const fillIsMixed =
|
|
106
167
|
isMixedValue(fillValue) ||
|
|
107
168
|
isMixedValue(styles.backgroundImage) ||
|
|
@@ -239,50 +300,16 @@ export function FillProperties({
|
|
|
239
300
|
);
|
|
240
301
|
return;
|
|
241
302
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
styles.backgroundColor || "#ffffff",
|
|
253
|
-
);
|
|
254
|
-
if (!current) {
|
|
255
|
-
onStyleChange("backgroundImage", nextLayer);
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
// Prepending a layer without also prepending matching entries
|
|
259
|
-
// to the other three index-aligned parallel arrays
|
|
260
|
-
// (size/repeat/position) would shift every existing layer's
|
|
261
|
-
// index by one, silently re-pairing each of them with the
|
|
262
|
-
// *previous* layer's size/repeat/position (same class of bug
|
|
263
|
-
// as the removeLayer fix above). Commit a default entry for
|
|
264
|
-
// the new layer in all four arrays together, in one patch.
|
|
265
|
-
const patch = {
|
|
266
|
-
backgroundImage: `${nextLayer}, ${current}`,
|
|
267
|
-
backgroundSize: joinCssLayers([
|
|
268
|
-
"auto",
|
|
269
|
-
...backgroundSizeLayers,
|
|
270
|
-
]),
|
|
271
|
-
backgroundRepeat: joinCssLayers([
|
|
272
|
-
"no-repeat",
|
|
273
|
-
...backgroundRepeatLayers,
|
|
274
|
-
]),
|
|
275
|
-
backgroundPosition: joinCssLayers([
|
|
276
|
-
"0% 0%",
|
|
277
|
-
...backgroundPositionLayers,
|
|
278
|
-
]),
|
|
279
|
-
};
|
|
280
|
-
if (onStylesChange) {
|
|
281
|
-
onStylesChange(patch);
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
Object.entries(patch).forEach(([property, value]) =>
|
|
285
|
-
onStyleChange(property, value),
|
|
303
|
+
commitStylePatch(
|
|
304
|
+
addFillLayerPatch({
|
|
305
|
+
backgroundColor: styles.backgroundColor,
|
|
306
|
+
backgroundLayers,
|
|
307
|
+
backgroundSizeLayers,
|
|
308
|
+
backgroundRepeatLayers,
|
|
309
|
+
backgroundPositionLayers,
|
|
310
|
+
}),
|
|
311
|
+
onStyleChange,
|
|
312
|
+
onStylesChange,
|
|
286
313
|
);
|
|
287
314
|
}}
|
|
288
315
|
>
|
|
@@ -312,10 +339,11 @@ export function FillProperties({
|
|
|
312
339
|
// layer on top of any existing backgroundImage layers
|
|
313
340
|
// (rendered as their own rows below) instead of clobbering
|
|
314
341
|
// them — ColorInput derives its add/replace-layer logic
|
|
315
|
-
// from this prop.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
342
|
+
// from this prop. The size/repeat/position siblings must
|
|
343
|
+
// come along too (same as PageProperties' background row in
|
|
344
|
+
// EditPanel.tsx) — see `baseFillLayerSourceProps` above for
|
|
345
|
+
// why all four are sourced together.
|
|
346
|
+
{...baseFillLayerProps}
|
|
319
347
|
blendMode={
|
|
320
348
|
isTextFillElement
|
|
321
349
|
? undefined
|
|
@@ -342,15 +370,19 @@ export function FillProperties({
|
|
|
342
370
|
? undefined
|
|
343
371
|
: (v) => onStyleChange("backgroundImage", v)
|
|
344
372
|
}
|
|
345
|
-
|
|
373
|
+
// Layer-index-aware: ColorInput merges the edited image
|
|
374
|
+
// into the correct backgroundImage/backgroundSize/
|
|
375
|
+
// backgroundRepeat/backgroundPosition index and hands back
|
|
376
|
+
// the full four-property patch here, already preserving
|
|
377
|
+
// every other stacked gradient/image layer (see
|
|
378
|
+
// `imageFillChangePatch`) — commit it as-is instead of
|
|
379
|
+
// rebuilding a single-layer patch that would silently wipe
|
|
380
|
+
// those siblings.
|
|
381
|
+
onImageFillLayerChange={
|
|
346
382
|
isTextFillElement
|
|
347
383
|
? undefined
|
|
348
|
-
: (
|
|
349
|
-
commitStylePatch(
|
|
350
|
-
imageFillToBackgroundStyles(value),
|
|
351
|
-
onStyleChange,
|
|
352
|
-
onStylesChange,
|
|
353
|
-
)
|
|
384
|
+
: (patch) =>
|
|
385
|
+
commitStylePatch(patch, onStyleChange, onStylesChange)
|
|
354
386
|
}
|
|
355
387
|
documentColors={documentColors}
|
|
356
388
|
pickerKey={[
|
|
@@ -384,20 +416,13 @@ export function FillProperties({
|
|
|
384
416
|
</SectionIconButton>
|
|
385
417
|
<SectionIconButton
|
|
386
418
|
label={t("editPanel.labels.removeLayer")}
|
|
387
|
-
onClick={() =>
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
backgroundColor: "transparent",
|
|
395
|
-
backgroundImage: "none",
|
|
396
|
-
});
|
|
397
|
-
} else {
|
|
398
|
-
onStyleChange(fillProperty, "transparent");
|
|
399
|
-
}
|
|
400
|
-
}}
|
|
419
|
+
onClick={() =>
|
|
420
|
+
commitStylePatch(
|
|
421
|
+
removeBaseFillPatch(fillProperty),
|
|
422
|
+
onStyleChange,
|
|
423
|
+
onStylesChange,
|
|
424
|
+
)
|
|
425
|
+
}
|
|
401
426
|
>
|
|
402
427
|
<IconMinus className="size-3.5" />
|
|
403
428
|
</SectionIconButton>
|
|
@@ -415,12 +440,18 @@ export function FillProperties({
|
|
|
415
440
|
{!isTextFillElement
|
|
416
441
|
? backgroundLayers.map((layer, index) => {
|
|
417
442
|
const gradient = parseGradientLayer(layer);
|
|
418
|
-
// Hidden state lives in the real, persisted
|
|
419
|
-
// marker (see withLayerSizeMarker) rather than
|
|
420
|
-
// so it survives deselect/reselect. Opacity
|
|
421
|
-
// the gradient's own stop opacities for
|
|
422
|
-
// longer drives hide/show — a layer can be a
|
|
423
|
-
// gradient and still be hidden via zero-size.
|
|
443
|
+
// Hidden state itself lives in the real, persisted
|
|
444
|
+
// backgroundSize marker (see withLayerSizeMarker) rather than
|
|
445
|
+
// React state, so it survives deselect/reselect. Opacity
|
|
446
|
+
// still reflects the gradient's own stop opacities for
|
|
447
|
+
// display, but no longer drives hide/show — a layer can be a
|
|
448
|
+
// fully-opaque gradient and still be hidden via zero-size.
|
|
449
|
+
// The layer's *original* size (a custom cover/contain/
|
|
450
|
+
// percentage) can't be recovered from the marker itself once
|
|
451
|
+
// overwritten, so it's separately stashed in component state
|
|
452
|
+
// for the round trip (see hiddenFillSizeStash below) —
|
|
453
|
+
// same pattern as effects-properties.tsx's hiddenEffectStash
|
|
454
|
+
// for hidden shadow/blur effects.
|
|
424
455
|
const hidden = isLayerHiddenBySize(backgroundSizeLayers[index]);
|
|
425
456
|
const opacity = gradient
|
|
426
457
|
? averageGradientOpacity(gradient.stops)
|
|
@@ -463,14 +494,47 @@ export function FillProperties({
|
|
|
463
494
|
onStyleChange(property, value),
|
|
464
495
|
);
|
|
465
496
|
};
|
|
497
|
+
const sizeStashKey = `${fillStashKey}:fill-size:${index}`;
|
|
466
498
|
const setLayerHidden = (nextHidden: boolean) => {
|
|
499
|
+
if (nextHidden) {
|
|
500
|
+
// Stash the real pre-hide size (a custom cover/contain/
|
|
501
|
+
// percentage — see withLayerSizeMarker) so re-showing
|
|
502
|
+
// can restore it instead of permanently discarding it
|
|
503
|
+
// for "auto". Skip stashing if the layer is somehow
|
|
504
|
+
// already hidden (nothing real to preserve).
|
|
505
|
+
const current = backgroundSizeLayers[index];
|
|
506
|
+
if (current && !isLayerHiddenBySize(current)) {
|
|
507
|
+
setHiddenFillSizeStash((prev) => ({
|
|
508
|
+
...prev,
|
|
509
|
+
[sizeStashKey]: current,
|
|
510
|
+
}));
|
|
511
|
+
}
|
|
512
|
+
onStyleChange(
|
|
513
|
+
"backgroundSize",
|
|
514
|
+
withLayerSizeMarker(
|
|
515
|
+
backgroundSizeLayers,
|
|
516
|
+
backgroundLayers.length,
|
|
517
|
+
index,
|
|
518
|
+
true,
|
|
519
|
+
),
|
|
520
|
+
);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const restored = hiddenFillSizeStash[sizeStashKey];
|
|
525
|
+
setHiddenFillSizeStash((prev) => {
|
|
526
|
+
const next = { ...prev };
|
|
527
|
+
delete next[sizeStashKey];
|
|
528
|
+
return next;
|
|
529
|
+
});
|
|
467
530
|
onStyleChange(
|
|
468
531
|
"backgroundSize",
|
|
469
532
|
withLayerSizeMarker(
|
|
470
533
|
backgroundSizeLayers,
|
|
471
534
|
backgroundLayers.length,
|
|
472
535
|
index,
|
|
473
|
-
|
|
536
|
+
false,
|
|
537
|
+
restored,
|
|
474
538
|
),
|
|
475
539
|
);
|
|
476
540
|
};
|
|
@@ -536,6 +600,35 @@ export function FillProperties({
|
|
|
536
600
|
),
|
|
537
601
|
);
|
|
538
602
|
}}
|
|
603
|
+
// Editing an existing image layer's URL/fit
|
|
604
|
+
// through its own row popover previously had no
|
|
605
|
+
// `onImageFillChange` wired at all, so it fell
|
|
606
|
+
// through to `emitPaintValue(imageFillToCss(...))`
|
|
607
|
+
// — a single-property `background` SHORTHAND
|
|
608
|
+
// string (e.g. `url(...) center / cover no-repeat`)
|
|
609
|
+
// written into `backgroundImage` alone, which is
|
|
610
|
+
// invalid CSS for that longhand and left
|
|
611
|
+
// backgroundSize/backgroundRepeat/backgroundPosition
|
|
612
|
+
// untouched. Merge into this layer's own index
|
|
613
|
+
// across all four parallel arrays instead (same
|
|
614
|
+
// helper the base-row fix uses — see
|
|
615
|
+
// `imageFillChangePatch` in panel-primitives.tsx).
|
|
616
|
+
onImageFillChange={(value) =>
|
|
617
|
+
commitStylePatch(
|
|
618
|
+
setImageFillLayerPatch(
|
|
619
|
+
{
|
|
620
|
+
backgroundImage: backgroundLayers,
|
|
621
|
+
backgroundSize: backgroundSizeLayers,
|
|
622
|
+
backgroundRepeat: backgroundRepeatLayers,
|
|
623
|
+
backgroundPosition: backgroundPositionLayers,
|
|
624
|
+
},
|
|
625
|
+
index,
|
|
626
|
+
imageFillToBackgroundStyles(value),
|
|
627
|
+
),
|
|
628
|
+
onStyleChange,
|
|
629
|
+
onStylesChange,
|
|
630
|
+
)
|
|
631
|
+
}
|
|
539
632
|
paintType={gradient?.type ?? "image"}
|
|
540
633
|
backgroundImage={layer}
|
|
541
634
|
backgroundSize={backgroundSizeLayers[index]}
|
|
@@ -103,6 +103,46 @@ export function SectionIconToggle({
|
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Compute the next `overIndex` for a dragover event on `hoverIndex`, given the
|
|
108
|
+
* index of the row currently being dragged. Hovering back over the dragged
|
|
109
|
+
* row itself has no meaningful drop position (dropping there is always a
|
|
110
|
+
* no-op — see `resolveRowDrop`), so this returns `null` to clear the
|
|
111
|
+
* indicator rather than echoing back `hoverIndex`, which would otherwise
|
|
112
|
+
* render a stray "before" drop-indicator line on the dragged row itself.
|
|
113
|
+
*
|
|
114
|
+
* Pure — exported for tests.
|
|
115
|
+
*/
|
|
116
|
+
export function nextRowDragOverIndex(
|
|
117
|
+
hoverIndex: number,
|
|
118
|
+
dragIndex: number,
|
|
119
|
+
): number | null {
|
|
120
|
+
return hoverIndex === dragIndex ? null : hoverIndex;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Resolve a drop into a `{ from, to }` pair, or `null` for a no-op drop.
|
|
125
|
+
*
|
|
126
|
+
* Both `from` (the row that started the drag) and `to` (the row dropped on)
|
|
127
|
+
* are re-validated against `count` — the CURRENT live row count at drop time
|
|
128
|
+
* — rather than trusted from the drag-start snapshot. The underlying array
|
|
129
|
+
* can shrink mid-drag (e.g. an external update removes rows while the
|
|
130
|
+
* pointer is still down); re-checking only `to` and not `from` would let a
|
|
131
|
+
* stale drag-start index (captured before the shrink) reach the caller's
|
|
132
|
+
* `onReorder` out of bounds.
|
|
133
|
+
*
|
|
134
|
+
* Pure — exported for tests.
|
|
135
|
+
*/
|
|
136
|
+
export function resolveRowDrop(
|
|
137
|
+
from: number | null,
|
|
138
|
+
to: number,
|
|
139
|
+
count: number,
|
|
140
|
+
): { from: number; to: number } | null {
|
|
141
|
+
if (from == null || from === to) return null;
|
|
142
|
+
if (from < 0 || from >= count || to < 0 || to >= count) return null;
|
|
143
|
+
return { from, to };
|
|
144
|
+
}
|
|
145
|
+
|
|
106
146
|
/**
|
|
107
147
|
* Minimal pointer-based reorder for a flat row list (fill layers, shadow
|
|
108
148
|
* layers). Deliberately not shared with LayersPanel.tsx's tree-drag logic —
|
|
@@ -127,17 +167,17 @@ export function useRowDragReorder(
|
|
|
127
167
|
if (dragIndex == null) return;
|
|
128
168
|
event.preventDefault();
|
|
129
169
|
event.dataTransfer.dropEffect = "move";
|
|
130
|
-
|
|
170
|
+
const next = nextRowDragOverIndex(index, dragIndex);
|
|
171
|
+
if (next !== overIndex) setOverIndex(next);
|
|
131
172
|
},
|
|
132
173
|
onDrop: (event: DragEvent<HTMLDivElement>) => {
|
|
133
174
|
event.preventDefault();
|
|
134
175
|
const from = dragIndex;
|
|
135
176
|
setDragIndex(null);
|
|
136
177
|
setOverIndex(null);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
liveOnReorder(from, index);
|
|
178
|
+
const resolved = resolveRowDrop(from, index, liveRef.current.count);
|
|
179
|
+
if (!resolved) return;
|
|
180
|
+
liveRef.current.onReorder(resolved.from, resolved.to);
|
|
141
181
|
},
|
|
142
182
|
});
|
|
143
183
|
|