entangle-ui 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +145 -0
- package/README.md +7 -5
- package/dist/esm/assets/src/components/controls/Select/{Select.css.ts.vanilla-oZnFUorL.css → Select.css.ts.vanilla-Cpu2BvWL.css} +3 -0
- package/dist/esm/assets/src/components/controls/Slider/{Slider.css.ts.vanilla-Cqm3fQ0S.css → Slider.css.ts.vanilla-CLf_RC0A.css} +50 -47
- package/dist/esm/assets/src/components/editor/PropertyInspector/{PropertyPanel.css.ts.vanilla-RYv_XgOu.css → PropertyPanel.css.ts.vanilla-Dpr_k5I3.css} +4 -1
- package/dist/esm/assets/src/components/editor/PropertyInspector/{PropertyRow.css.ts.vanilla-C3YZnnHb.css → PropertyRow.css.ts.vanilla-pq1Uhd2a.css} +15 -8
- package/dist/esm/assets/src/components/editor/PropertyInspector/{PropertySection.css.ts.vanilla-DK12opZc.css → PropertySection.css.ts.vanilla-6MWWAqyd.css} +50 -32
- package/dist/esm/assets/src/components/navigation/Menu/{Menu.css.ts.vanilla-B5iVe5S2.css → Menu.css.ts.vanilla-Bhh1L5yl.css} +14 -11
- package/dist/esm/assets/src/components/primitives/Tooltip/{Tooltip.css.ts.vanilla-CrEFoLBX.css → Tooltip.css.ts.vanilla-BqaiGrFQ.css} +12 -9
- package/dist/esm/assets/src/components/shell/AppShell/{AppShell.css.ts.vanilla-BYmtU0O_.css → AppShell.css.ts.vanilla-BLK2-DRL.css} +1 -0
- package/dist/esm/assets/src/components/shell/MenuBar/{MenuBar.css.ts.vanilla-TgPcl4yA.css → MenuBar.css.ts.vanilla-Dt3w4f-q.css} +18 -6
- package/dist/esm/components/Icons/AddIcon.js.map +1 -1
- package/dist/esm/components/Icons/AiChatIcon.js.map +1 -1
- package/dist/esm/components/Icons/AiSparklesIcon.js.map +1 -1
- package/dist/esm/components/Icons/ArchiveIcon.js.map +1 -1
- package/dist/esm/components/Icons/ArrowDownIcon.js.map +1 -1
- package/dist/esm/components/Icons/ArrowLeftIcon.js.map +1 -1
- package/dist/esm/components/Icons/ArrowRightIcon.js.map +1 -1
- package/dist/esm/components/Icons/ArrowUpIcon.js.map +1 -1
- package/dist/esm/components/Icons/BookmarkIcon.js.map +1 -1
- package/dist/esm/components/Icons/BugIcon.js.map +1 -1
- package/dist/esm/components/Icons/BuildingIcon.js.map +1 -1
- package/dist/esm/components/Icons/CalendarIcon.js.map +1 -1
- package/dist/esm/components/Icons/CameraIcon.js +31 -0
- package/dist/esm/components/Icons/CameraIcon.js.map +1 -0
- package/dist/esm/components/Icons/CheckIcon.js.map +1 -1
- package/dist/esm/components/Icons/ChevronDownIcon.js.map +1 -1
- package/dist/esm/components/Icons/ChevronLeftIcon.js.map +1 -1
- package/dist/esm/components/Icons/ChevronRightIcon.js.map +1 -1
- package/dist/esm/components/Icons/ChevronUpIcon.js.map +1 -1
- package/dist/esm/components/Icons/CircleIcon.js.map +1 -1
- package/dist/esm/components/Icons/ClockIcon.js.map +1 -1
- package/dist/esm/components/Icons/CloseIcon.js.map +1 -1
- package/dist/esm/components/Icons/CloudUploadIcon.js.map +1 -1
- package/dist/esm/components/Icons/CodeIcon.js.map +1 -1
- package/dist/esm/components/Icons/CopyIcon.js.map +1 -1
- package/dist/esm/components/Icons/CubeIcon.js +31 -0
- package/dist/esm/components/Icons/CubeIcon.js.map +1 -0
- package/dist/esm/components/Icons/CutIcon.js.map +1 -1
- package/dist/esm/components/Icons/DotsHorizontalIcon.js.map +1 -1
- package/dist/esm/components/Icons/DotsVerticalIcon.js.map +1 -1
- package/dist/esm/components/Icons/DownloadIcon.js.map +1 -1
- package/dist/esm/components/Icons/EditIcon.js.map +1 -1
- package/dist/esm/components/Icons/ErrorIcon.js.map +1 -1
- package/dist/esm/components/Icons/ExternalLinkIcon.js.map +1 -1
- package/dist/esm/components/Icons/EyeDropperIcon.js.map +1 -1
- package/dist/esm/components/Icons/EyeIcon.js.map +1 -1
- package/dist/esm/components/Icons/FileTextIcon.js.map +1 -1
- package/dist/esm/components/Icons/FilterIcon.js.map +1 -1
- package/dist/esm/components/Icons/FirstIcon.js.map +1 -1
- package/dist/esm/components/Icons/FolderCogIcon.js.map +1 -1
- package/dist/esm/components/Icons/FolderIcon.js.map +1 -1
- package/dist/esm/components/Icons/FolderOpenIcon.js.map +1 -1
- package/dist/esm/components/Icons/FullscreenIcon.js.map +1 -1
- package/dist/esm/components/Icons/GitBranchIcon.js.map +1 -1
- package/dist/esm/components/Icons/GridIcon.js.map +1 -1
- package/dist/esm/components/Icons/HeartIcon.js.map +1 -1
- package/dist/esm/components/Icons/HelpIcon.js.map +1 -1
- package/dist/esm/components/Icons/HomeIcon.js.map +1 -1
- package/dist/esm/components/Icons/ImageIcon.js.map +1 -1
- package/dist/esm/components/Icons/InfoIcon.js.map +1 -1
- package/dist/esm/components/Icons/LastIcon.js.map +1 -1
- package/dist/esm/components/Icons/LinkIcon.js.map +1 -1
- package/dist/esm/components/Icons/ListIcon.js.map +1 -1
- package/dist/esm/components/Icons/LockIcon.js.map +1 -1
- package/dist/esm/components/Icons/MaximizeIcon.js.map +1 -1
- package/dist/esm/components/Icons/MenuIcon.js.map +1 -1
- package/dist/esm/components/Icons/MinimizeIcon.js.map +1 -1
- package/dist/esm/components/Icons/MinusIcon.js.map +1 -1
- package/dist/esm/components/Icons/OrbitIcon.js +31 -0
- package/dist/esm/components/Icons/OrbitIcon.js.map +1 -0
- package/dist/esm/components/Icons/PasteIcon.js.map +1 -1
- package/dist/esm/components/Icons/PauseIcon.js.map +1 -1
- package/dist/esm/components/Icons/PinIcon.js.map +1 -1
- package/dist/esm/components/Icons/PlayIcon.js.map +1 -1
- package/dist/esm/components/Icons/RedoIcon.js.map +1 -1
- package/dist/esm/components/Icons/RefreshIcon.js.map +1 -1
- package/dist/esm/components/Icons/RobotIcon.js.map +1 -1
- package/dist/esm/components/Icons/RotateIcon.js +32 -0
- package/dist/esm/components/Icons/RotateIcon.js.map +1 -0
- package/dist/esm/components/Icons/SaveIcon.js.map +1 -1
- package/dist/esm/components/Icons/SearchIcon.js.map +1 -1
- package/dist/esm/components/Icons/SendIcon.js.map +1 -1
- package/dist/esm/components/Icons/SettingsIcon.js.map +1 -1
- package/dist/esm/components/Icons/SortIcon.js.map +1 -1
- package/dist/esm/components/Icons/SpinIcon.js +32 -0
- package/dist/esm/components/Icons/SpinIcon.js.map +1 -0
- package/dist/esm/components/Icons/StarIcon.js.map +1 -1
- package/dist/esm/components/Icons/StopIcon.js.map +1 -1
- package/dist/esm/components/Icons/SuccessIcon.js.map +1 -1
- package/dist/esm/components/Icons/TagIcon.js.map +1 -1
- package/dist/esm/components/Icons/TangentAlignedIcon.js.map +1 -1
- package/dist/esm/components/Icons/TangentAutoIcon.js.map +1 -1
- package/dist/esm/components/Icons/TangentFreeIcon.js.map +1 -1
- package/dist/esm/components/Icons/TangentLinearIcon.js.map +1 -1
- package/dist/esm/components/Icons/TangentMirroredIcon.js.map +1 -1
- package/dist/esm/components/Icons/TangentStepIcon.js.map +1 -1
- package/dist/esm/components/Icons/TerminalIcon.js.map +1 -1
- package/dist/esm/components/Icons/TrashIcon.js.map +1 -1
- package/dist/esm/components/Icons/UndoIcon.js.map +1 -1
- package/dist/esm/components/Icons/UnlinkIcon.js.map +1 -1
- package/dist/esm/components/Icons/UnlockIcon.js.map +1 -1
- package/dist/esm/components/Icons/UploadIcon.js.map +1 -1
- package/dist/esm/components/Icons/UserIcon.js.map +1 -1
- package/dist/esm/components/Icons/UsersIcon.js.map +1 -1
- package/dist/esm/components/Icons/WarningIcon.js.map +1 -1
- package/dist/esm/components/Icons/ZoomFitIcon.js +32 -0
- package/dist/esm/components/Icons/ZoomFitIcon.js.map +1 -0
- package/dist/esm/components/Icons/ZoomInIcon.js.map +1 -1
- package/dist/esm/components/Icons/ZoomOutIcon.js.map +1 -1
- package/dist/esm/components/controls/CartesianPicker/CartesianPicker.js.map +1 -1
- package/dist/esm/components/controls/CartesianPicker/useCartesianInteraction.js.map +1 -1
- package/dist/esm/components/controls/CartesianPicker/useCartesianRenderer.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/AlphaSlider.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/ColorArea.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/ColorInputs.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/ColorPalette.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/ColorPicker.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/ColorPresets.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/ColorSwatch.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/EyeDropper.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/HueSlider.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/colorUtils.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/palettes/material.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/palettes/professional.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/palettes/tailwind.js.map +1 -1
- package/dist/esm/components/controls/ColorPicker/useColor.js.map +1 -1
- package/dist/esm/components/controls/Combobox/Combobox.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/CurveCanvas.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/CurveEditor.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/CurveToolbar.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/curvePresets.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/curveUtils.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/useCurveInteraction.js.map +1 -1
- package/dist/esm/components/controls/CurveEditor/useCurveRenderer.js.map +1 -1
- package/dist/esm/components/controls/FileTree/FileTree.js +7 -1
- package/dist/esm/components/controls/FileTree/FileTree.js.map +1 -1
- package/dist/esm/components/controls/FileTree/fileTreeIcons.js.map +1 -1
- package/dist/esm/components/controls/FileTree/fileTreeLabels.js.map +1 -1
- package/dist/esm/components/controls/FileTree/useFileTreeDrop.js +1 -1
- package/dist/esm/components/controls/FileTree/useFileTreeDrop.js.map +1 -1
- package/dist/esm/components/controls/FileUploader/FileUploader.js.map +1 -1
- package/dist/esm/components/controls/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/esm/components/controls/NumberInput/NumberInput.js.map +1 -1
- package/dist/esm/components/controls/NumberInput/useNumberInput.js.map +1 -1
- package/dist/esm/components/controls/Select/Select.css.js +1 -1
- package/dist/esm/components/controls/Select/Select.js +15 -7
- package/dist/esm/components/controls/Select/Select.js.map +1 -1
- package/dist/esm/components/controls/Slider/Slider.css.js +10 -11
- package/dist/esm/components/controls/Slider/Slider.css.js.map +1 -1
- package/dist/esm/components/controls/Slider/Slider.js +40 -7
- package/dist/esm/components/controls/Slider/Slider.js.map +1 -1
- package/dist/esm/components/controls/TagInput/TagInput.js.map +1 -1
- package/dist/esm/components/controls/TreeView/TreeNode.js +6 -0
- package/dist/esm/components/controls/TreeView/TreeNode.js.map +1 -1
- package/dist/esm/components/controls/TreeView/TreeView.js.map +1 -1
- package/dist/esm/components/controls/TreeView/useTreeState.js.map +1 -1
- package/dist/esm/components/controls/VectorInput/VectorInput.js +6 -0
- package/dist/esm/components/controls/VectorInput/VectorInput.js.map +1 -1
- package/dist/esm/components/data/DataTable/DataTable.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowser.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserAnnouncementLive.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserBreadcrumbs.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserContent.js +6 -0
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserContent.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserContext.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserContextMenu.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserDefaultMenus.js +6 -0
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserDefaultMenus.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserGrid.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserGrid.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserGridItem.js +6 -0
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserGridItem.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserList.js +6 -0
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserList.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserRenameField.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserSidebar.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserStatusBar.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserStore.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserSurface.js +6 -0
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserSurface.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserToolbar.js +6 -0
- package/dist/esm/components/editor/AssetBrowser/AssetBrowserToolbar.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/assetBrowserFilter.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/assetBrowserFormat.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/assetBrowserGeometry.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/assetBrowserKeyboard.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/assetBrowserLabels.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/slots.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetBrowserAnnouncement.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetBrowserHandle.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetBrowserHandle.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetBrowserViewState.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetBrowserViewState.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetDnd.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetDnd.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetGridKeyboardNav.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetGridVirtualizer.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetGridVirtualizer.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetMarqueeGesture.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetMarqueeGesture.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetMutationKeyboard.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetMutationKeyboard.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetMutations.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetMutations.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetNavigation.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetNavigation.js.map +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetSelectionController.js +1 -1
- package/dist/esm/components/editor/AssetBrowser/useAssetSelectionController.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatActionBar.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatAttachment.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatBubble.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatCodeBlock.js +6 -0
- package/dist/esm/components/editor/ChatPanel/ChatCodeBlock.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatContextChip.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatEmptyState.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatIcons.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatInput.js +6 -0
- package/dist/esm/components/editor/ChatPanel/ChatInput.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatInputToolbar.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatMarkdownRenderer.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatMessage.js +6 -0
- package/dist/esm/components/editor/ChatPanel/ChatMessage.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatMessageList.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatPanel.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatToolCall.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatTypingIndicator.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/useChatInput.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/useChatMessages.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/useChatScroll.js.map +1 -1
- package/dist/esm/components/editor/Minimap/Minimap.js +1 -1
- package/dist/esm/components/editor/Minimap/Minimap.js.map +1 -1
- package/dist/esm/components/editor/Minimap/Minimap.types.js.map +1 -1
- package/dist/esm/components/editor/Minimap/MinimapContext.js.map +1 -1
- package/dist/esm/components/editor/Minimap/MinimapCorner.js.map +1 -1
- package/dist/esm/components/editor/Minimap/MinimapFooter.js.map +1 -1
- package/dist/esm/components/editor/Minimap/MinimapStore.js.map +1 -1
- package/dist/esm/components/editor/Minimap/MinimapTitle.js.map +1 -1
- package/dist/esm/components/editor/Minimap/ViewportMinimap.js +1 -1
- package/dist/esm/components/editor/Minimap/ViewportMinimap.js.map +1 -1
- package/dist/esm/components/editor/Minimap/computeBoundsFromItems.js.map +1 -1
- package/dist/esm/components/editor/Minimap/index.js.map +1 -1
- package/dist/esm/components/editor/Minimap/minimapCoords.js.map +1 -1
- package/dist/esm/components/editor/Minimap/minimapDrawing.js.map +1 -1
- package/dist/esm/components/editor/Minimap/minimapHitTest.js.map +1 -1
- package/dist/esm/components/editor/Minimap/useMinimapGestures.js +1 -1
- package/dist/esm/components/editor/Minimap/useMinimapGestures.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraph.js +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraph.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraph.types.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphContext.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphEdgeLabels.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphGroup.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphMinimap.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNode.js +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNode.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNodeContext.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNodeParts.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNodeSection.js +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNodeSection.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphNodeSectionContext.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphPin.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphPort.js +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphPort.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphPortVisual.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphSlots.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphSpawnPalette.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphStore.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/NodeGraphToolbar.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/createTypeMatchValidator.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/nodeGraphActions.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/nodeGraphDrawing.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/nodeGraphIds.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/nodeGraphMath.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/sortSlots.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useDragGesture.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraph.js +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraph.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphConnection.js +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphConnection.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphEdgeInteraction.js +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphEdgeInteraction.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphGroupDrag.js +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphGroupDrag.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphKeyboard.js +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphKeyboard.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphNodeDrag.js +1 -1
- package/dist/esm/components/editor/NodeGraph/useNodeGraphNodeDrag.js.map +1 -1
- package/dist/esm/components/editor/NodeGraph/useStoreSlice.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertyGroup.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertyPanel.css.js +4 -3
- package/dist/esm/components/editor/PropertyInspector/PropertyPanel.css.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertyPanel.js +5 -4
- package/dist/esm/components/editor/PropertyInspector/PropertyPanel.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertyRow.css.js +7 -6
- package/dist/esm/components/editor/PropertyInspector/PropertyRow.css.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertyRow.js +18 -3
- package/dist/esm/components/editor/PropertyInspector/PropertyRow.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertySection.css.js +11 -10
- package/dist/esm/components/editor/PropertyInspector/PropertySection.css.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertySection.js +29 -21
- package/dist/esm/components/editor/PropertyInspector/PropertySection.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/usePropertyUndo.js.map +1 -1
- package/dist/esm/components/editor/Timeline/Timeline.js +1 -1
- package/dist/esm/components/editor/Timeline/Timeline.js.map +1 -1
- package/dist/esm/components/editor/Timeline/Timeline.types.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineContext.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineFooter.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineMinimap.js +1 -1
- package/dist/esm/components/editor/Timeline/TimelineMinimap.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineStore.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineToolbar.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineTrackHeaders.js +1 -1
- package/dist/esm/components/editor/Timeline/TimelineTrackHeaders.js.map +1 -1
- package/dist/esm/components/editor/Timeline/TimelineTrackScale.js.map +1 -1
- package/dist/esm/components/editor/Timeline/index.js.map +1 -1
- package/dist/esm/components/editor/Timeline/timelineCoords.js.map +1 -1
- package/dist/esm/components/editor/Timeline/timelineDrawing.js.map +1 -1
- package/dist/esm/components/editor/Timeline/timelineEdits.js.map +1 -1
- package/dist/esm/components/editor/Timeline/timelineHitTest.js.map +1 -1
- package/dist/esm/components/editor/Timeline/timelineLayout.js.map +1 -1
- package/dist/esm/components/editor/Timeline/timelineSelection.js.map +1 -1
- package/dist/esm/components/editor/Timeline/useTimelineDraw.js +1 -1
- package/dist/esm/components/editor/Timeline/useTimelineDraw.js.map +1 -1
- package/dist/esm/components/editor/Timeline/useTimelineGestures.js +1 -1
- package/dist/esm/components/editor/Timeline/useTimelineGestures.js.map +1 -1
- package/dist/esm/components/editor/Timeline/useTimelinePlayback.js.map +1 -1
- package/dist/esm/components/editor/TransformControl/TransformControl.js.map +1 -1
- package/dist/esm/components/editor/ViewportGizmo/ViewportGizmo.js.map +1 -1
- package/dist/esm/components/editor/ViewportGizmo/gizmoMath.js.map +1 -1
- package/dist/esm/components/editor/ViewportGizmo/useGizmoInteraction.js.map +1 -1
- package/dist/esm/components/editor/ViewportGizmo/useGizmoRenderer.js.map +1 -1
- package/dist/esm/components/feedback/Alert/Alert.js.map +1 -1
- package/dist/esm/components/feedback/Alert/AlertActions.js.map +1 -1
- package/dist/esm/components/feedback/Alert/AlertDescription.js.map +1 -1
- package/dist/esm/components/feedback/Alert/AlertTitle.js.map +1 -1
- package/dist/esm/components/feedback/CommandPalette/CommandPalette.js.map +1 -1
- package/dist/esm/components/feedback/CommandPalette/fuzzySearch.js.map +1 -1
- package/dist/esm/components/feedback/CommandPalette/useRecentItems.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/Dialog.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/DialogBody.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/DialogClose.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/DialogFooter.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/DialogHeader.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/useDialogAnimation.js.map +1 -1
- package/dist/esm/components/feedback/Drawer/Drawer.js.map +1 -1
- package/dist/esm/components/feedback/Drawer/useDrawerAnimation.js.map +1 -1
- package/dist/esm/components/feedback/EmptyState/EmptyState.js.map +1 -1
- package/dist/esm/components/feedback/LogView/LogView.js.map +1 -1
- package/dist/esm/components/feedback/LogView/LogViewBody.js.map +1 -1
- package/dist/esm/components/feedback/LogView/LogViewContext.js.map +1 -1
- package/dist/esm/components/feedback/LogView/LogViewParts.js.map +1 -1
- package/dist/esm/components/feedback/LogView/LogViewStore.js.map +1 -1
- package/dist/esm/components/feedback/LogView/logViewLabels.js.map +1 -1
- package/dist/esm/components/feedback/LogView/logViewLevels.js.map +1 -1
- package/dist/esm/components/feedback/LogView/logViewUtils.js.map +1 -1
- package/dist/esm/components/feedback/LogView/useFollowTail.js.map +1 -1
- package/dist/esm/components/feedback/LogView/useLogSelection.js.map +1 -1
- package/dist/esm/components/feedback/ProgressBar/CircularProgress.js.map +1 -1
- package/dist/esm/components/feedback/ProgressBar/ProgressBar.js.map +1 -1
- package/dist/esm/components/feedback/Skeleton/Skeleton.js.map +1 -1
- package/dist/esm/components/feedback/Skeleton/SkeletonGroup.js.map +1 -1
- package/dist/esm/components/feedback/Skeleton/SkeletonLayout.js.map +1 -1
- package/dist/esm/components/feedback/Spinner/Spinner.js +12 -3
- package/dist/esm/components/feedback/Spinner/Spinner.js.map +1 -1
- package/dist/esm/components/feedback/Stat/Stat.js.map +1 -1
- package/dist/esm/components/feedback/Toast/ToastContainer.js.map +1 -1
- package/dist/esm/components/feedback/Toast/ToastItem.js.map +1 -1
- package/dist/esm/components/feedback/Toast/ToastProvider.js.map +1 -1
- package/dist/esm/components/feedback/Toast/useToast.js.map +1 -1
- package/dist/esm/components/form/FormHelperText.js.map +1 -1
- package/dist/esm/components/form/FormLabel.js.map +1 -1
- package/dist/esm/components/form/InputWrapper.js.map +1 -1
- package/dist/esm/components/layout/Accordion/Accordion.js.map +1 -1
- package/dist/esm/components/layout/Accordion/AccordionContent.js.map +1 -1
- package/dist/esm/components/layout/Accordion/AccordionItem.js.map +1 -1
- package/dist/esm/components/layout/Accordion/AccordionTrigger.js.map +1 -1
- package/dist/esm/components/layout/Card/Card.js.map +1 -1
- package/dist/esm/components/layout/Divider/Divider.js.map +1 -1
- package/dist/esm/components/layout/Flex/Flex.js.map +1 -1
- package/dist/esm/components/layout/Grid/Grid.js.map +1 -1
- package/dist/esm/components/layout/ListItem/ListItem.js.map +1 -1
- package/dist/esm/components/layout/PageHeader/PageHeader.js.map +1 -1
- package/dist/esm/components/layout/PanelSurface/PanelSurface.js.map +1 -1
- package/dist/esm/components/layout/ScrollArea/ScrollArea.js.map +1 -1
- package/dist/esm/components/layout/Spacer/Spacer.js.map +1 -1
- package/dist/esm/components/layout/SplitPane/SplitPane.js.map +1 -1
- package/dist/esm/components/layout/SplitPane/SplitPanePanel.js.map +1 -1
- package/dist/esm/components/layout/Stack/Stack.js.map +1 -1
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbEllipsis.js.map +1 -1
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbItem.js.map +1 -1
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbSeparator.js.map +1 -1
- package/dist/esm/components/navigation/Breadcrumbs/Breadcrumbs.js +6 -0
- package/dist/esm/components/navigation/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/esm/components/navigation/ContextMenu/ContextMenu.js +2 -2
- package/dist/esm/components/navigation/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/esm/components/navigation/Menu/Menu.css.js +11 -10
- package/dist/esm/components/navigation/Menu/Menu.css.js.map +1 -1
- package/dist/esm/components/navigation/Menu/Menu.js +2 -2
- package/dist/esm/components/navigation/Menu/Menu.js.map +1 -1
- package/dist/esm/components/navigation/Menu/MenuGapContext.js.map +1 -1
- package/dist/esm/components/navigation/Pagination/Pagination.js.map +1 -1
- package/dist/esm/components/navigation/Pagination/usePagination.js.map +1 -1
- package/dist/esm/components/navigation/PathBar/PathBar.js +7 -1
- package/dist/esm/components/navigation/PathBar/PathBar.js.map +1 -1
- package/dist/esm/components/navigation/PathBar/PathBarSiblingMenu.js +6 -0
- package/dist/esm/components/navigation/PathBar/PathBarSiblingMenu.js.map +1 -1
- package/dist/esm/components/navigation/PathBar/pathUtils.js.map +1 -1
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControlItem.js.map +1 -1
- package/dist/esm/components/navigation/Tabs/Tab.js.map +1 -1
- package/dist/esm/components/navigation/Tabs/TabList.js.map +1 -1
- package/dist/esm/components/navigation/Tabs/TabPanel.js.map +1 -1
- package/dist/esm/components/navigation/Tabs/Tabs.js.map +1 -1
- package/dist/esm/components/primitives/Avatar/Avatar.js +6 -0
- package/dist/esm/components/primitives/Avatar/Avatar.js.map +1 -1
- package/dist/esm/components/primitives/Avatar/AvatarGroup.js.map +1 -1
- package/dist/esm/components/primitives/Badge/Badge.js +6 -0
- package/dist/esm/components/primitives/Badge/Badge.js.map +1 -1
- package/dist/esm/components/primitives/Button/Button.js.map +1 -1
- package/dist/esm/components/primitives/Checkbox/Checkbox.js.map +1 -1
- package/dist/esm/components/primitives/Checkbox/CheckboxGroup.js.map +1 -1
- package/dist/esm/components/primitives/Code/Code.js.map +1 -1
- package/dist/esm/components/primitives/Collapsible/Collapsible.js.map +1 -1
- package/dist/esm/components/primitives/HoverCard/HoverCard.js.map +1 -1
- package/dist/esm/components/primitives/Icon/Icon.js.map +1 -1
- package/dist/esm/components/primitives/IconButton/IconButton.js +4 -2
- package/dist/esm/components/primitives/IconButton/IconButton.js.map +1 -1
- package/dist/esm/components/primitives/Input/Input.js.map +1 -1
- package/dist/esm/components/primitives/Kbd/Kbd.js.map +1 -1
- package/dist/esm/components/primitives/Link/Link.js.map +1 -1
- package/dist/esm/components/primitives/Paper/Paper.js.map +1 -1
- package/dist/esm/components/primitives/Popover/Popover.js.map +1 -1
- package/dist/esm/components/primitives/Popover/PopoverClose.js.map +1 -1
- package/dist/esm/components/primitives/Popover/PopoverContent.js.map +1 -1
- package/dist/esm/components/primitives/Popover/PopoverTrigger.js.map +1 -1
- package/dist/esm/components/primitives/Radio/Radio.js.map +1 -1
- package/dist/esm/components/primitives/Radio/RadioGroup.js.map +1 -1
- package/dist/esm/components/primitives/Switch/Switch.js.map +1 -1
- package/dist/esm/components/primitives/Text/Text.js.map +1 -1
- package/dist/esm/components/primitives/TextArea/TextArea.js.map +1 -1
- package/dist/esm/components/primitives/Tooltip/Arrow.js.map +1 -1
- package/dist/esm/components/primitives/Tooltip/Tooltip.css.js +6 -5
- package/dist/esm/components/primitives/Tooltip/Tooltip.css.js.map +1 -1
- package/dist/esm/components/primitives/Tooltip/Tooltip.js +12 -2
- package/dist/esm/components/primitives/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/components/primitives/Tooltip/utils.js.map +1 -1
- package/dist/esm/components/primitives/VisuallyHidden/VisuallyHidden.js.map +1 -1
- package/dist/esm/components/primitives/canvas/CanvasContainer.js.map +1 -1
- package/dist/esm/components/primitives/canvas/canvasCoords.js.map +1 -1
- package/dist/esm/components/primitives/canvas/canvasDrawing.js.map +1 -1
- package/dist/esm/components/primitives/canvas/canvasTheme.js.map +1 -1
- package/dist/esm/components/primitives/canvas/useCanvasRenderer.js.map +1 -1
- package/dist/esm/components/primitives/viewport/Viewport.js +6 -3
- package/dist/esm/components/primitives/viewport/Viewport.js.map +1 -1
- package/dist/esm/components/primitives/viewport/ViewportContext.js.map +1 -1
- package/dist/esm/components/primitives/viewport/ViewportLayer.js +1 -1
- package/dist/esm/components/primitives/viewport/ViewportLayer.js.map +1 -1
- package/dist/esm/components/primitives/viewport/ViewportOverlay.js.map +1 -1
- package/dist/esm/components/primitives/viewport/ViewportStore.js.map +1 -1
- package/dist/esm/components/primitives/viewport/ViewportWorld.js.map +1 -1
- package/dist/esm/components/primitives/viewport/useViewportGestures.js +1 -1
- package/dist/esm/components/primitives/viewport/useViewportGestures.js.map +1 -1
- package/dist/esm/components/primitives/viewport/viewportCoords.js.map +1 -1
- package/dist/esm/components/primitives/viewport/viewportMath.js.map +1 -1
- package/dist/esm/components/shell/AppShell/AppShell.css.js +1 -1
- package/dist/esm/components/shell/AppShell/AppShell.js.map +1 -1
- package/dist/esm/components/shell/FloatingPanel/FloatingPanel.js.map +1 -1
- package/dist/esm/components/shell/MenuBar/MenuBar.css.js +7 -6
- package/dist/esm/components/shell/MenuBar/MenuBar.css.js.map +1 -1
- package/dist/esm/components/shell/MenuBar/MenuBar.js +52 -3
- package/dist/esm/components/shell/MenuBar/MenuBar.js.map +1 -1
- package/dist/esm/components/shell/StatusBar/StatusBar.js.map +1 -1
- package/dist/esm/components/shell/Toolbar/Toolbar.js.map +1 -1
- package/dist/esm/context/KeyboardContext.js.map +1 -1
- package/dist/esm/hooks/useBreakpoint/useBreakpoint.js.map +1 -1
- package/dist/esm/hooks/useClickOutside/useClickOutside.js.map +1 -1
- package/dist/esm/hooks/useClipboard/useClipboard.js.map +1 -1
- package/dist/esm/hooks/useControlledState/useControlledState.js.map +1 -1
- package/dist/esm/hooks/useDebounced/useDebouncedCallback.js.map +1 -1
- package/dist/esm/hooks/useDebounced/useDebouncedValue.js.map +1 -1
- package/dist/esm/hooks/useDisclosure/useDisclosure.js.map +1 -1
- package/dist/esm/hooks/useEventCallback/useEventCallback.js.map +1 -1
- package/dist/esm/hooks/useFocusTrap/useFocusTrap.js.map +1 -1
- package/dist/esm/hooks/useHotkey/useHotkey.js.map +1 -1
- package/dist/esm/hooks/useIntersectionObserver/useIntersectionObserver.js.map +1 -1
- package/dist/esm/hooks/useIsMounted/useIsMounted.js.map +1 -1
- package/dist/esm/hooks/useKeyboard/useKeyboard.js.map +1 -1
- package/dist/esm/hooks/useKeyboard/utils.js.map +1 -1
- package/dist/esm/hooks/useLatest/useLatest.js.map +1 -1
- package/dist/esm/hooks/useListboxNav/useListboxNav.js.map +1 -1
- package/dist/esm/hooks/useMediaQuery/useMediaQuery.js.map +1 -1
- package/dist/esm/hooks/useMergedRef/useMergedRef.js.map +1 -1
- package/dist/esm/hooks/useNavigationHistory/useNavigationHistory.js.map +1 -1
- package/dist/esm/hooks/useResizeObserver/useResizeObserver.js.map +1 -1
- package/dist/esm/hooks/useTheme/useTheme.js +1 -1
- package/dist/esm/hooks/useTheme/useTheme.js.map +1 -1
- package/dist/esm/hooks/useThrottledCallback/useThrottledCallback.js.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node_modules/tslib/tslib.es6.js.map +1 -1
- package/dist/esm/styles.css.js +3 -0
- package/dist/esm/styles.css.js.map +1 -0
- package/dist/esm/theme/ThemeProvider.js +5 -3
- package/dist/esm/theme/ThemeProvider.js.map +1 -1
- package/dist/esm/theme/VanillaThemeProvider.js.map +1 -1
- package/dist/esm/theme/breakpoints.js.map +1 -1
- package/dist/esm/theme/createCustomTheme.js +1 -1
- package/dist/esm/theme/createCustomTheme.js.map +1 -1
- package/dist/esm/theme/createLightTheme.js.map +1 -1
- package/dist/esm/theme/darkThemeValues.js.map +1 -1
- package/dist/esm/theme/lightThemeValues.js.map +1 -1
- package/dist/esm/theme/themeContractData.js.map +1 -1
- package/dist/esm/utils/cx.js.map +1 -1
- package/dist/esm/utils/devWarn.js.map +1 -1
- package/dist/esm/utils/mathExpression.js.map +1 -1
- package/dist/esm/utils/mathUtils.js.map +1 -1
- package/dist/esm/utils/objects.js.map +1 -1
- package/dist/esm/utils/platform.js.map +1 -1
- package/dist/tokens/tokens.dark.css +1 -1
- package/dist/tokens/tokens.json +1 -1
- package/dist/tokens/tokens.light.css +1 -1
- package/dist/types/components/Icons/CameraIcon.d.ts +34 -0
- package/dist/types/components/Icons/CubeIcon.d.ts +34 -0
- package/dist/types/components/Icons/OrbitIcon.d.ts +34 -0
- package/dist/types/components/Icons/RotateIcon.d.ts +35 -0
- package/dist/types/components/Icons/SpinIcon.d.ts +35 -0
- package/dist/types/components/Icons/ZoomFitIcon.d.ts +35 -0
- package/dist/types/components/controls/Select/Select.d.ts +1 -1
- package/dist/types/components/controls/Select/Select.types.d.ts +43 -9
- package/dist/types/components/controls/Slider/Slider.d.ts +7 -0
- package/dist/types/components/editor/PropertyInspector/PropertyInspector.types.d.ts +49 -3
- package/dist/types/components/feedback/Spinner/Spinner.d.ts +6 -1
- package/dist/types/components/feedback/Spinner/Spinner.types.d.ts +8 -0
- package/dist/types/components/primitives/Button/Button.d.ts +1 -1
- package/dist/types/components/primitives/IconButton/IconButton.d.ts +3 -2
- package/dist/types/components/primitives/viewport/Viewport.d.ts +5 -2
- package/dist/types/components/shell/MenuBar/MenuBar.d.ts +862 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/theme/ThemeProvider.d.ts +5 -3
- package/package.json +6 -2
- package/dist/esm/_virtual/_commonjsHelpers.js +0 -6
- package/dist/esm/_virtual/_commonjsHelpers.js.map +0 -1
- package/dist/esm/_virtual/cjs.js +0 -4
- package/dist/esm/_virtual/cjs.js.map +0 -1
- package/dist/esm/_virtual/cssesc.js +0 -8
- package/dist/esm/_virtual/cssesc.js.map +0 -1
- package/dist/esm/_virtual/picocolors.js +0 -8
- package/dist/esm/_virtual/picocolors.js.map +0 -1
- package/dist/esm/_virtual/picocolors2.js +0 -4
- package/dist/esm/_virtual/picocolors2.js.map +0 -1
- package/dist/esm/node_modules/@emotion/hash/dist/emotion-hash.esm.js +0 -56
- package/dist/esm/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/adapter/dist/vanilla-extract-css-adapter.esm.js +0 -46
- package/dist/esm/node_modules/@vanilla-extract/css/adapter/dist/vanilla-extract-css-adapter.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/dist/taggedTemplateLiteral-10998315.esm.js +0 -13
- package/dist/esm/node_modules/@vanilla-extract/css/dist/taggedTemplateLiteral-10998315.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/dist/transformCss-fd0786e1.esm.js +0 -962
- package/dist/esm/node_modules/@vanilla-extract/css/dist/transformCss-fd0786e1.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.esm.js +0 -309
- package/dist/esm/node_modules/@vanilla-extract/css/dist/vanilla-extract-css.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/fileScope/dist/vanilla-extract-css-fileScope.esm.js +0 -18
- package/dist/esm/node_modules/@vanilla-extract/css/fileScope/dist/vanilla-extract-css-fileScope.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/injectStyles/dist/vanilla-extract-css-injectStyles.esm.js +0 -23
- package/dist/esm/node_modules/@vanilla-extract/css/injectStyles/dist/vanilla-extract-css-injectStyles.esm.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/css/node_modules/lru-cache/dist/esm/index.js +0 -1543
- package/dist/esm/node_modules/@vanilla-extract/css/node_modules/lru-cache/dist/esm/index.js.map +0 -1
- package/dist/esm/node_modules/@vanilla-extract/private/dist/vanilla-extract-private.esm.js +0 -38
- package/dist/esm/node_modules/@vanilla-extract/private/dist/vanilla-extract-private.esm.js.map +0 -1
- package/dist/esm/node_modules/css-what/lib/es/parse.js +0 -424
- package/dist/esm/node_modules/css-what/lib/es/parse.js.map +0 -1
- package/dist/esm/node_modules/css-what/lib/es/types.js +0 -29
- package/dist/esm/node_modules/css-what/lib/es/types.js.map +0 -1
- package/dist/esm/node_modules/cssesc/cssesc.js +0 -120
- package/dist/esm/node_modules/cssesc/cssesc.js.map +0 -1
- package/dist/esm/node_modules/dedent/dist/dedent.js +0 -100
- package/dist/esm/node_modules/dedent/dist/dedent.js.map +0 -1
- package/dist/esm/node_modules/deep-object-diff/mjs/diff.js +0 -40
- package/dist/esm/node_modules/deep-object-diff/mjs/diff.js.map +0 -1
- package/dist/esm/node_modules/deep-object-diff/mjs/utils.js +0 -9
- package/dist/esm/node_modules/deep-object-diff/mjs/utils.js.map +0 -1
- package/dist/esm/node_modules/deepmerge/dist/cjs.js +0 -143
- package/dist/esm/node_modules/deepmerge/dist/cjs.js.map +0 -1
- package/dist/esm/node_modules/media-query-parser/dist/media-query-parser.esm.js +0 -1386
- package/dist/esm/node_modules/media-query-parser/dist/media-query-parser.esm.js.map +0 -1
- package/dist/esm/node_modules/modern-ahocorasick/dist/index.js +0 -102
- package/dist/esm/node_modules/modern-ahocorasick/dist/index.js.map +0 -1
- package/dist/esm/node_modules/picocolors/picocolors.js +0 -87
- package/dist/esm/node_modules/picocolors/picocolors.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeGraphDrawing.js","sources":["../../../../../../src/components/editor/NodeGraph/nodeGraphDrawing.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nodeGraphDrawing.js","sources":["src/components/editor/NodeGraph/nodeGraphDrawing.ts"],"sourcesContent":["import {\n applyGroupResize,\n getBezierControlPoints,\n resolveEdgeEndpoints,\n} from './nodeGraphMath';\n\nimport type {\n NodeGraphEdgeStyleFn,\n NodeGraphPortRef,\n NodeGraphPortSide,\n NodeGraphSelection,\n} from './NodeGraph.types';\nimport type {\n BezierControlPoints,\n NodeLookup,\n PortPositionLookup,\n} from './nodeGraphMath';\nimport type {\n NodeGraphDataState,\n NodeGraphInteractionState,\n} from './NodeGraphStore';\nimport type {\n CanvasThemeColors,\n Point2D,\n} from '@/components/primitives/canvas/canvas.types';\nimport type { ViewportLayerDrawInfo } from '@/components/primitives/viewport';\n\nexport interface NodeGraphDrawTheme extends CanvasThemeColors {\n /** Colour of an unselected, non-hovered edge. */\n edgeStroke: string;\n /** Colour of a selected edge. */\n edgeStrokeSelected: string;\n /** Colour of the hovered edge. */\n edgeStrokeHovered: string;\n /** Colour of the in-flight connection preview. */\n previewStroke: string;\n /** Colour of an in-flight connection rejected by `isValidConnection`. */\n previewStrokeInvalid: string;\n /** Group backdrop fill. */\n groupFill: string;\n /** Group backdrop fill when selected. */\n groupFillSelected: string;\n /** Group outline colour. */\n groupStroke: string;\n /** Group label colour. */\n groupLabel: string;\n}\n\n/** Stroke widths in *screen* pixels — independent of zoom. */\nconst EDGE_STROKE_WIDTH = 1.5;\nconst EDGE_STROKE_WIDTH_SELECTED = 2.5;\nconst EDGE_STROKE_WIDTH_HOVERED = 2;\nconst PREVIEW_STROKE_WIDTH = 2;\nconst GROUP_STROKE_WIDTH = 1;\n\n/**\n * Stroke a cubic Bézier to the given context. The control points are in\n * screen coordinates (already transformed by the caller).\n */\nfunction strokeBezier(\n ctx: CanvasRenderingContext2D,\n cp: BezierControlPoints\n): void {\n ctx.beginPath();\n ctx.moveTo(cp.p0.x, cp.p0.y);\n ctx.bezierCurveTo(cp.c1.x, cp.c1.y, cp.c2.x, cp.c2.y, cp.p3.x, cp.p3.y);\n ctx.stroke();\n}\n\nfunction toScreenCp(\n cp: BezierControlPoints,\n worldToScreen: (p: Point2D) => Point2D\n): BezierControlPoints {\n return {\n p0: worldToScreen(cp.p0),\n c1: worldToScreen(cp.c1),\n c2: worldToScreen(cp.c2),\n p3: worldToScreen(cp.p3),\n };\n}\n\n/**\n * Margin (screen px) added around the viewport before culling an edge.\n * Covers the stroke half-width + round line-cap overshoot for the default\n * styles, plus headroom for moderately wider consumer `edgeStyle` widths.\n * A curve whose control-point bbox is more than this far outside the\n * viewport cannot paint a visible pixel inside it.\n */\nconst EDGE_CULL_MARGIN_PX = 32;\n\n/**\n * True when a cubic Bézier (given by its screen-space control points)\n * cannot intersect the viewport. The curve lies within the convex hull of\n * its control points, so an axis-aligned bbox of the four points is a\n * conservative bound — if that bbox is entirely past one viewport edge\n * (plus {@link EDGE_CULL_MARGIN_PX}), the curve is off-screen.\n */\nexport function bezierOutsideViewport(\n cp: BezierControlPoints,\n width: number,\n height: number\n): boolean {\n const minX = Math.min(cp.p0.x, cp.c1.x, cp.c2.x, cp.p3.x);\n if (minX > width + EDGE_CULL_MARGIN_PX) return true;\n const maxX = Math.max(cp.p0.x, cp.c1.x, cp.c2.x, cp.p3.x);\n if (maxX < -EDGE_CULL_MARGIN_PX) return true;\n const minY = Math.min(cp.p0.y, cp.c1.y, cp.c2.y, cp.p3.y);\n if (minY > height + EDGE_CULL_MARGIN_PX) return true;\n const maxY = Math.max(cp.p0.y, cp.c1.y, cp.c2.y, cp.p3.y);\n if (maxY < -EDGE_CULL_MARGIN_PX) return true;\n return false;\n}\n\n/** Draw all edges in the graph. */\nexport function drawEdges(\n ctx: CanvasRenderingContext2D,\n info: ViewportLayerDrawInfo,\n data: NodeGraphDataState,\n selection: NodeGraphSelection,\n hoveredEdgeId: string | null,\n interaction: NodeGraphInteractionState,\n getNodeById: NodeLookup,\n getPortPosition: PortPositionLookup,\n edgeStyle: NodeGraphEdgeStyleFn | undefined,\n theme: NodeGraphDrawTheme\n): void {\n // Either a node-drag (`drag-nodes`) or a group-drag carrying contained\n // nodes (`drag-groups.containedNodeIds`) shifts edge endpoints live —\n // resolve to a single (ids, delta) shape so the loop below stays simple.\n // The interaction state already exposes `nodeIds` / `containedNodeIds` as\n // ReadonlySet, so no per-frame Set construction is needed here.\n let dragSet: { ids: ReadonlySet<string>; delta: Point2D } | null = null;\n if (interaction.kind === 'drag-nodes') {\n dragSet = {\n ids: interaction.nodeIds,\n delta: interaction.delta,\n };\n } else if (interaction.kind === 'drag-groups') {\n dragSet = {\n ids: interaction.containedNodeIds,\n delta: interaction.delta,\n };\n }\n // While an endpoint is being re-dragged, hide the edge from this layer so\n // only the connection preview is shown (the wire \"detaches\" and follows\n // the cursor).\n const reconnectingId =\n interaction.kind === 'connect' ? interaction.reconnectEdgeId : undefined;\n // O(1) membership for the per-edge selected check below — this layer\n // redraws every frame during a drag, so a linear `selection.edges.includes`\n // per edge would be O(edges × selected) each frame.\n const selectedEdgeIds = new Set(selection.edges);\n for (const edge of data.edges) {\n if (edge.id === reconnectingId) continue;\n const endpoints = resolveEdgeEndpoints(edge, getNodeById, getPortPosition);\n if (!endpoints) continue;\n\n // Apply the in-flight drag delta so edges follow nodes 1:1 during a drag,\n // instead of snapping to the new position on pointerup.\n const source = dragSet?.ids.has(edge.source.node)\n ? {\n x: endpoints.source.x + dragSet.delta.x,\n y: endpoints.source.y + dragSet.delta.y,\n }\n : endpoints.source;\n const target = dragSet?.ids.has(edge.target.node)\n ? {\n x: endpoints.target.x + dragSet.delta.x,\n y: endpoints.target.y + dragSet.delta.y,\n }\n : endpoints.target;\n\n const cpWorld = getBezierControlPoints(\n source,\n endpoints.srcSide,\n target,\n endpoints.tgtSide\n );\n const cpScreen = toScreenCp(cpWorld, p => info.worldToScreen(p));\n\n // Frustum cull: a cubic Bézier is fully contained in the convex hull of\n // its four control points, so if the screen-space bbox of those points\n // lies entirely outside the viewport (plus a margin) the curve can't be\n // visible — skip the style callback + stroke entirely. This bounds the\n // per-frame edge cost by what's on screen rather than total edge count,\n // which is the dominant cost when zoomed in on a large graph.\n if (bezierOutsideViewport(cpScreen, info.size.width, info.size.height)) {\n continue;\n }\n\n const isSelected = selectedEdgeIds.has(edge.id);\n const isHovered = hoveredEdgeId === edge.id;\n\n // Resolve consumer override for this edge. Source/target ports\n // come from the store — `dataType` and `side` are already there,\n // no parallel index needed on the consumer side.\n const srcPos = getPortPosition(edge.source.node, edge.source.port);\n const tgtPos = getPortPosition(edge.target.node, edge.target.port);\n const customStyle = edgeStyle?.(edge, {\n selected: isSelected,\n hovered: isHovered,\n sourcePort: srcPos\n ? srcPos.dataType !== undefined\n ? { side: srcPos.side, dataType: srcPos.dataType }\n : { side: srcPos.side }\n : null,\n targetPort: tgtPos\n ? tgtPos.dataType !== undefined\n ? { side: tgtPos.side, dataType: tgtPos.dataType }\n : { side: tgtPos.side }\n : null,\n });\n\n // State-driven defaults; consumer overrides via `customStyle` take\n // precedence when they're not undefined. Selected / hovered still\n // win over a plain `edge.color` so the interaction state stays\n // visible — but consumer can override even that with `edgeStyle`.\n const defaultColor = isSelected\n ? theme.edgeStrokeSelected\n : isHovered\n ? theme.edgeStrokeHovered\n : (edge.color ?? theme.edgeStroke);\n const defaultWidth = isSelected\n ? EDGE_STROKE_WIDTH_SELECTED\n : isHovered\n ? EDGE_STROKE_WIDTH_HOVERED\n : EDGE_STROKE_WIDTH;\n\n ctx.strokeStyle = customStyle?.color ?? defaultColor;\n ctx.lineWidth = customStyle?.width ?? defaultWidth;\n ctx.lineCap = 'round';\n if (customStyle?.dash != null && customStyle.dash.length > 0) {\n ctx.setLineDash(customStyle.dash as number[]);\n } else {\n ctx.setLineDash([]);\n }\n\n strokeBezier(ctx, cpScreen);\n }\n // Reset shared state mutated above so subsequent layers (groups,\n // preview) don't inherit a stale dash pattern.\n ctx.setLineDash([]);\n}\n\n/** Draw group backdrops (under nodes, under edges). */\nexport function drawGroups(\n ctx: CanvasRenderingContext2D,\n info: ViewportLayerDrawInfo,\n data: NodeGraphDataState,\n selection: NodeGraphSelection,\n interaction: NodeGraphInteractionState,\n theme: NodeGraphDrawTheme\n): void {\n // Live drag / resize support — mirror what the HTML overlay shows so the\n // canvas backdrop stays glued to the user's cursor during gestures.\n const dragSet =\n interaction.kind === 'drag-groups'\n ? { ids: interaction.groupIds, delta: interaction.delta }\n : null;\n const resizing = interaction.kind === 'resize-group' ? interaction : null;\n const selectedGroupIds = new Set(selection.groups);\n\n for (const group of data.groups) {\n let bx = group.bounds.x;\n let by = group.bounds.y;\n let bw = group.bounds.width;\n let bh = group.bounds.height;\n if (dragSet?.ids.has(group.id)) {\n bx += dragSet.delta.x;\n by += dragSet.delta.y;\n } else if (resizing?.groupId === group.id) {\n const next = applyGroupResize(\n resizing.startBounds,\n resizing.handle,\n resizing.delta\n );\n bx = next.x;\n by = next.y;\n bw = next.width;\n bh = next.height;\n }\n\n const tl = info.worldToScreen({ x: bx, y: by });\n const br = info.worldToScreen({ x: bx + bw, y: by + bh });\n const width = br.x - tl.x;\n const height = br.y - tl.y;\n if (width <= 0 || height <= 0) continue;\n\n const isSelected = selectedGroupIds.has(group.id);\n\n ctx.fillStyle =\n group.color ?? (isSelected ? theme.groupFillSelected : theme.groupFill);\n ctx.fillRect(tl.x, tl.y, width, height);\n\n ctx.strokeStyle = group.color ?? theme.groupStroke;\n ctx.lineWidth = GROUP_STROKE_WIDTH;\n ctx.strokeRect(tl.x + 0.5, tl.y + 0.5, width - 1, height - 1);\n // The label is rendered by the HTML overlay (`NodeGraphGroupView`) so\n // it stays editable on click and scales with the world transform like\n // the rest of the group body. Canvas no longer paints it — avoids the\n // duplicate-title artefact where a screen-space canvas label and a\n // world-space HTML label drifted apart at non-1 zoom.\n }\n}\n\n/**\n * Draw the in-flight connection preview — a Bézier from the source port to\n * the current pointer position, styled to indicate validity.\n */\nexport function drawConnectionPreview(\n ctx: CanvasRenderingContext2D,\n info: ViewportLayerDrawInfo,\n interaction: NodeGraphInteractionState,\n resolveSourcePort: (\n ref: NodeGraphPortRef\n ) => { position: Point2D; side: NodeGraphPortSide } | null,\n theme: NodeGraphDrawTheme\n): void {\n if (interaction.kind !== 'connect') return;\n const src = resolveSourcePort(interaction.source);\n if (!src) return;\n\n // The \"target\" side for the preview curve mirrors the source so the curve\n // pulls toward the cursor naturally even when the cursor is free-floating.\n const tgtSide = oppositeSide(src.side);\n const cpWorld = getBezierControlPoints(\n src.position,\n src.side,\n interaction.currentWorld,\n tgtSide\n );\n const cpScreen = toScreenCp(cpWorld, p => info.worldToScreen(p));\n\n ctx.strokeStyle = interaction.invalid\n ? theme.previewStrokeInvalid\n : theme.previewStroke;\n ctx.lineWidth = PREVIEW_STROKE_WIDTH;\n ctx.lineCap = 'round';\n ctx.setLineDash(interaction.invalid ? [6, 4] : []);\n\n strokeBezier(ctx, cpScreen);\n\n ctx.setLineDash([]);\n\n // Endpoint marker at the cursor — small circle so the user sees the\n // pointer-snap target.\n const cursorScreen = info.worldToScreen(interaction.currentWorld);\n ctx.beginPath();\n ctx.arc(cursorScreen.x, cursorScreen.y, 4, 0, Math.PI * 2);\n ctx.fillStyle = interaction.invalid\n ? theme.previewStrokeInvalid\n : theme.previewStroke;\n ctx.fill();\n}\n\nfunction oppositeSide(side: NodeGraphPortSide): NodeGraphPortSide {\n switch (side) {\n case 'left':\n return 'right';\n case 'right':\n return 'left';\n case 'top':\n return 'bottom';\n case 'bottom':\n return 'top';\n default: {\n const _unreached: never = side;\n return _unreached;\n }\n }\n}\n\n/** Resolved canvas-drawing theme assembled from the base theme + overrides. */\nexport function buildDrawTheme(base: CanvasThemeColors): NodeGraphDrawTheme {\n return {\n ...base,\n edgeStroke: base.textMuted,\n edgeStrokeSelected: base.accentPrimary,\n edgeStrokeHovered: base.textSecondary,\n previewStroke: base.accentPrimary,\n previewStrokeInvalid: 'rgba(220, 38, 38, 0.9)',\n groupFill: 'rgba(255, 255, 255, 0.03)',\n groupFillSelected: 'rgba(255, 255, 255, 0.05)',\n groupStroke: base.borderDefault,\n groupLabel: base.textSecondary,\n };\n}\n\n// ─── Background pattern (dots / grid) ───\n\nexport interface BackgroundDrawOptions {\n variant: 'dots' | 'grid' | 'none';\n /** Grid spacing in world units. */\n gap: number;\n /** Override pattern colour (defaults to theme.borderDefault). */\n color?: string;\n /** Override background fill (defaults to theme.backgroundSecondary). */\n background?: string;\n}\n\n/**\n * Minimum on-screen distance (in CSS pixels) between adjacent dots / grid\n * lines. When the base `gap × zoom` falls below this, the renderer drops\n * down to a coarser LOD level (effective gap × 2, × 4, …) so the screen\n * never carries more than `viewportArea / (TARGET_SCREEN_GAP²)` elements.\n *\n * Acts like a mip-map level for the background pattern — keeps perf\n * constant under zoom-out instead of scaling quadratically with the world\n * area exposed.\n */\nconst TARGET_SCREEN_GAP = 18;\n\n/**\n * Lower hard cutoff: when even the coarsest pattern would be denser than\n * this on screen, skip the pattern entirely. Without this, an\n * extreme-zoom-out (e.g. fitting a 100k-node graph in 800px) would still\n * fire pattern-fill operations that the GPU can't sample meaningfully.\n */\nconst MIN_VISIBLE_SCREEN_GAP = 3;\n\n/**\n * Draw a uniform background pattern across the entire visible viewport.\n * Used by `NodeGraph.Background`.\n *\n * Performance strategy:\n *\n * 1. **LOD** — when zoomed out the world gap is multiplied by the\n * smallest power-of-two that keeps the on-screen spacing ≥\n * `TARGET_SCREEN_GAP`. The number of dots/lines drawn per frame is\n * therefore bounded by `viewportArea / TARGET_SCREEN_GAP²` regardless\n * of how far the user zooms out.\n * 2. **Pattern fill** — a single off-screen tile is built (one dot or\n * one crosshair of lines) and used as `ctx.createPattern(…, 'repeat')`.\n * A single `fillRect` covers the whole viewport, replacing what was\n * previously O(n) `arc()`/`stroke()` calls. The pattern's origin is\n * translated so the tile aligns with the world grid.\n */\nexport function drawBackground(\n ctx: CanvasRenderingContext2D,\n info: ViewportLayerDrawInfo,\n theme: NodeGraphDrawTheme,\n options: BackgroundDrawOptions\n): void {\n const background = options.background ?? theme.backgroundSecondary;\n ctx.fillStyle = background;\n ctx.fillRect(0, 0, info.size.width, info.size.height);\n\n if (options.variant === 'none' || options.gap <= 0) return;\n\n // Resolve the on-screen spacing the user-supplied world gap would yield\n // at the current zoom, then step up the world gap in powers of two\n // until each cell is at least TARGET_SCREEN_GAP pixels apart on screen.\n const baseScreenGap = options.gap * info.transform.zoom;\n if (baseScreenGap <= 0) return;\n let lodMultiplier = 1;\n while (baseScreenGap * lodMultiplier < TARGET_SCREEN_GAP) {\n lodMultiplier *= 2;\n // Safety: cap LOD at a sensible upper bound so a pathological zoom\n // (e.g. 1e-12) doesn't spin here forever.\n if (lodMultiplier > 1 << 20) break;\n }\n const screenGap = baseScreenGap * lodMultiplier;\n if (screenGap < MIN_VISIBLE_SCREEN_GAP) return;\n\n const color = options.color ?? theme.borderDefault;\n\n // World-space origin in screen pixels — the pattern's tile (0,0) must\n // land here so the dots/lines line up with the world grid. Modulo by\n // the tile size to keep the translation in `[0, tileSize)`.\n const origin = info.worldToScreen({ x: 0, y: 0 });\n const alignedTileSize = screenGap;\n const offsetX =\n ((origin.x % alignedTileSize) + alignedTileSize) % alignedTileSize;\n const offsetY =\n ((origin.y % alignedTileSize) + alignedTileSize) % alignedTileSize;\n\n // Snap the world origin offset to keep dots crisply pixel-aligned at\n // pan time. Sub-pixel pattern positions blur the rendered tile.\n const tx = Math.round(offsetX);\n const ty = Math.round(offsetY);\n\n const tileSize = Math.max(1, Math.round(alignedTileSize));\n if (options.variant === 'dots') {\n const dotRadius = Math.max(0.75, Math.min(1.75, screenGap / 24));\n const tile = getCachedTile(`dots:${tileSize}:${dotRadius}:${color}`, () =>\n buildDotTile(alignedTileSize, dotRadius, color)\n );\n if (!tile) return;\n fillWithPattern(ctx, tile, info.size.width, info.size.height, tx, ty);\n } else {\n const tile = getCachedTile(`grid:${tileSize}:${color}`, () =>\n buildGridTile(alignedTileSize, color)\n );\n if (!tile) return;\n ctx.globalAlpha = 0.6;\n fillWithPattern(ctx, tile, info.size.width, info.size.height, tx, ty);\n ctx.globalAlpha = 1;\n }\n}\n\n// Off-screen pattern tile cache. A pan keeps zoom (hence tile size, dot\n// radius, and colour) constant, so without this every panned frame would\n// allocate a fresh OffscreenCanvas and redraw the dot/grid. Keyed by every\n// input that affects the rendered pixels; bounded with FIFO eviction so a\n// continuous zoom (which varies the tile size per frame) can't grow it\n// without limit. Colour is in the key, so a theme switch produces a new tile\n// rather than a stale one.\nconst TILE_CACHE_LIMIT = 16;\nconst tileCache = new Map<string, HTMLCanvasElement | OffscreenCanvas>();\n\nfunction getCachedTile(\n key: string,\n build: () => HTMLCanvasElement | OffscreenCanvas | null\n): HTMLCanvasElement | OffscreenCanvas | null {\n const cached = tileCache.get(key);\n if (cached) return cached;\n const tile = build();\n if (!tile) return null;\n tileCache.set(key, tile);\n if (tileCache.size > TILE_CACHE_LIMIT) {\n const oldest = tileCache.keys().next().value;\n if (oldest !== undefined) tileCache.delete(oldest);\n }\n return tile;\n}\n\n/**\n * Build a single-cell repeating tile with one dot centred inside it.\n * Returns `null` when the environment has no `OffscreenCanvas`/`<canvas>`\n * (e.g. some SSR test runners) so the caller can bail without throwing.\n */\nfunction buildDotTile(\n tileSize: number,\n dotRadius: number,\n color: string\n): HTMLCanvasElement | OffscreenCanvas | null {\n const c = createTileCanvas(tileSize);\n if (!c) return null;\n const tctx = c.getContext('2d');\n if (!tctx) return null;\n tctx.clearRect(0, 0, tileSize, tileSize);\n tctx.fillStyle = color;\n tctx.beginPath();\n tctx.arc(tileSize / 2, tileSize / 2, dotRadius, 0, Math.PI * 2);\n tctx.fill();\n return c;\n}\n\n/**\n * Build a single-cell repeating tile carrying one vertical + one\n * horizontal line at the right/bottom edge — when tiled this forms a\n * full grid without overlap. Lines are at `tileSize - 0.5` so they fall\n * on whole pixels after the integer-snapped `setTransform` below.\n */\nfunction buildGridTile(\n tileSize: number,\n color: string\n): HTMLCanvasElement | OffscreenCanvas | null {\n const c = createTileCanvas(tileSize);\n if (!c) return null;\n const tctx = c.getContext('2d');\n if (!tctx) return null;\n tctx.clearRect(0, 0, tileSize, tileSize);\n tctx.strokeStyle = color;\n tctx.lineWidth = 1;\n // Right edge → vertical line; bottom edge → horizontal line.\n tctx.beginPath();\n tctx.moveTo(tileSize - 0.5, 0);\n tctx.lineTo(tileSize - 0.5, tileSize);\n tctx.moveTo(0, tileSize - 0.5);\n tctx.lineTo(tileSize, tileSize - 0.5);\n tctx.stroke();\n return c;\n}\n\nfunction createTileCanvas(\n size: number\n): HTMLCanvasElement | OffscreenCanvas | null {\n const rounded = Math.max(1, Math.round(size));\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(rounded, rounded);\n }\n if (typeof document === 'undefined') return null;\n const c = document.createElement('canvas');\n c.width = rounded;\n c.height = rounded;\n return c;\n}\n\n/**\n * Fill the entire viewport with a repeating pattern, translating the\n * pattern origin to `(tx, ty)` so the tile aligns with the world grid.\n * Single canvas call — independent of the number of dots/lines drawn.\n */\nfunction fillWithPattern(\n ctx: CanvasRenderingContext2D,\n tile: HTMLCanvasElement | OffscreenCanvas,\n width: number,\n height: number,\n tx: number,\n ty: number\n): void {\n const pattern = ctx.createPattern(tile, 'repeat');\n if (!pattern) return;\n ctx.save();\n // Move the pattern origin so the first tile starts at (tx, ty) instead\n // of (0, 0). The canvas tracks pattern origin via the current transform.\n ctx.translate(tx, ty);\n ctx.fillStyle = pattern;\n ctx.fillRect(-tx, -ty, width, height);\n ctx.restore();\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeGraphIds.js","sources":["
|
|
1
|
+
{"version":3,"file":"nodeGraphIds.js","sources":["src/components/editor/NodeGraph/nodeGraphIds.ts"],"sourcesContent":["import type { NodeGraphPortRef } from './NodeGraph.types';\n\n// Module-scoped monotonic counter — guarantees uniqueness within a single\n// session even when `Date.now()` collides (tight bursts of connections,\n// fake timers in tests). Combined with a short random tail it gives a\n// near-zero collision risk without pulling in `crypto.randomUUID`, which\n// isn't available in every browser / runtime the library targets.\nlet idCounter = 0;\n\nfunction uniqueSuffix(): string {\n const t = Date.now().toString(36);\n const c = (idCounter++).toString(36);\n const r = Math.random().toString(36).slice(2, 6);\n return `${t}-${c}-${r}`;\n}\n\n/**\n * Generate a unique-enough id for a freshly-spawned node from a template.\n * Format: `${templateId}-${timestamp36}-${counter36}-${random36}`.\n */\nexport function generateNodeId(templateId: string): string {\n return `${templateId}-${uniqueSuffix()}`;\n}\n\n/**\n * Generate a unique edge id from its endpoints. Includes source/target\n * port refs in the id so it's somewhat readable in devtools, plus the\n * standard timestamp + counter + random tail to guarantee uniqueness\n * across rapid back-to-back connections.\n */\nexport function generateEdgeId(\n source: NodeGraphPortRef,\n target: NodeGraphPortRef\n): string {\n return `edge-${source.node}.${source.port}-${target.node}.${target.port}-${uniqueSuffix()}`;\n}\n"],"names":[],"mappings":"AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,GAAG,CAAC;AAEjB,SAAS,YAAY,GAAA;IACnB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;IACjC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;AACpC,IAAA,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AAChD,IAAA,OAAO,GAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,EAAI,CAAC,EAAE;AACzB;AAEA;;;AAGG;AACG,SAAU,cAAc,CAAC,UAAkB,EAAA;AAC/C,IAAA,OAAO,GAAG,UAAU,CAAA,CAAA,EAAI,YAAY,EAAE,EAAE;AAC1C;AAEA;;;;;AAKG;AACG,SAAU,cAAc,CAC5B,MAAwB,EACxB,MAAwB,EAAA;IAExB,OAAO,CAAA,KAAA,EAAQ,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAA,CAAA,EAAI,MAAM,CAAC,IAAI,CAAA,CAAA,EAAI,MAAM,CAAC,IAAI,IAAI,YAAY,EAAE,EAAE;AAC7F;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeGraphMath.js","sources":["../../../../../../src/components/editor/NodeGraph/nodeGraphMath.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nodeGraphMath.js","sources":["src/components/editor/NodeGraph/nodeGraphMath.ts"],"sourcesContent":["import type {\n NodeGraphEdge,\n NodeGraphNode,\n NodeGraphPortRef,\n NodeGraphPortSide,\n} from './NodeGraph.types';\nimport type {\n NodeGraphMeasuredSize,\n NodeGraphPortPosition,\n} from './NodeGraphStore';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type { WorldRect } from '@/components/primitives/viewport';\n\n/**\n * Fallback size used when a node has no measured DOM size yet (first paint\n * before `ResizeObserver` has fired) and no explicit `node.width`/`height`.\n */\nexport const DEFAULT_NODE_WIDTH = 180;\nexport const DEFAULT_NODE_HEIGHT = 80;\n\ninterface NodeBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Read the function used to look up the registered port position. Pure\n * resolver — the math module takes this as an argument so it stays free\n * of a store dependency.\n */\nexport type PortPositionLookup = (\n nodeId: string,\n portId: string\n) => NodeGraphPortPosition | null;\n\n/** Read the measured size of a node wrapper (or null if not measured yet). */\nexport type MeasuredSizeLookup = (\n nodeId: string\n) => NodeGraphMeasuredSize | null;\n\n/**\n * O(1) node-by-id lookup. Hot resolvers ({@link resolvePortRef},\n * {@link resolveEdgeEndpoints}) take this instead of an array to keep edge\n * drawing at `O(edges)` rather than `O(edges × nodes)`.\n */\nexport type NodeLookup = (id: string) => NodeGraphNode | undefined;\n\n/**\n * Resolve a node's effective bounding box.\n *\n * Priority: explicit `node.width`/`node.height` > measured DOM size >\n * `defaults`. This keeps consumer-controlled fixed-size nodes deterministic\n * while letting auto-sized nodes pick up their real dimensions for\n * hit-testing, marquee selection, and `fitToContent`.\n */\nexport function getNodeBox(\n node: NodeGraphNode,\n measuredSize?: NodeGraphMeasuredSize | null,\n defaults: { width: number; height: number } = {\n width: DEFAULT_NODE_WIDTH,\n height: DEFAULT_NODE_HEIGHT,\n }\n): NodeBox {\n return {\n x: node.position.x,\n y: node.position.y,\n width: node.width ?? measuredSize?.width ?? defaults.width,\n height: node.height ?? measuredSize?.height ?? defaults.height,\n };\n}\n\n/**\n * Unit vector pointing away from a port along its side. Used as the\n * tangent direction for the Bézier handle on that endpoint.\n */\nexport function sideVector(side: NodeGraphPortSide): Point2D {\n switch (side) {\n case 'left':\n return { x: -1, y: 0 };\n case 'right':\n return { x: 1, y: 0 };\n case 'top':\n return { x: 0, y: -1 };\n case 'bottom':\n return { x: 0, y: 1 };\n default: {\n const _unreached: never = side;\n return _unreached;\n }\n }\n}\n\nexport interface BezierControlPoints {\n /** Source endpoint. */\n p0: Point2D;\n /** Source-side control point. */\n c1: Point2D;\n /** Target-side control point. */\n c2: Point2D;\n /** Target endpoint. */\n p3: Point2D;\n}\n\n/**\n * Compute control points for a Cubic Bézier connecting `source` (on side\n * `srcSide`) to `target` (on side `tgtSide`). The handle length scales\n * with the distance between the endpoints, with a floor so short edges\n * still curve visibly.\n */\nexport function getBezierControlPoints(\n source: Point2D,\n srcSide: NodeGraphPortSide,\n target: Point2D,\n tgtSide: NodeGraphPortSide\n): BezierControlPoints {\n const dx = target.x - source.x;\n const dy = target.y - source.y;\n const dist = Math.hypot(dx, dy);\n\n const srcHorizontal = srcSide === 'left' || srcSide === 'right';\n const tgtHorizontal = tgtSide === 'left' || tgtSide === 'right';\n const srcAxis = srcHorizontal ? Math.abs(dx) : Math.abs(dy);\n const tgtAxis = tgtHorizontal ? Math.abs(dx) : Math.abs(dy);\n const minHandle = 32;\n const srcLen = Math.max(minHandle, srcAxis * 0.5, dist * 0.25);\n const tgtLen = Math.max(minHandle, tgtAxis * 0.5, dist * 0.25);\n\n const srcVec = sideVector(srcSide);\n const tgtVec = sideVector(tgtSide);\n\n return {\n p0: source,\n c1: { x: source.x + srcVec.x * srcLen, y: source.y + srcVec.y * srcLen },\n c2: { x: target.x + tgtVec.x * tgtLen, y: target.y + tgtVec.y * tgtLen },\n p3: target,\n };\n}\n\n/**\n * Evaluate a Cubic Bézier at parameter `t` in `[0, 1]`.\n */\nexport function evaluateBezier(cp: BezierControlPoints, t: number): Point2D {\n const it = 1 - t;\n const it2 = it * it;\n const t2 = t * t;\n const w0 = it2 * it;\n const w1 = 3 * it2 * t;\n const w2 = 3 * it * t2;\n const w3 = t2 * t;\n return {\n x: cp.p0.x * w0 + cp.c1.x * w1 + cp.c2.x * w2 + cp.p3.x * w3,\n y: cp.p0.y * w0 + cp.c1.y * w1 + cp.c2.y * w2 + cp.p3.y * w3,\n };\n}\n\n/**\n * Test whether a world point is within `threshold` world units of the\n * Bézier curve. Samples the curve at fixed intervals and measures\n * point-to-segment distance.\n */\nexport function isPointNearBezier(\n point: Point2D,\n cp: BezierControlPoints,\n threshold: number,\n samples = 24\n): boolean {\n let prev = cp.p0;\n for (let i = 1; i <= samples; i++) {\n const t = i / samples;\n const curr = evaluateBezier(cp, t);\n if (pointToSegmentDistance(point, prev, curr) <= threshold) return true;\n prev = curr;\n }\n return false;\n}\n\n/**\n * Test whether a world point is inside (or on the edge of) a node box.\n */\nexport function isPointInNode(\n point: Point2D,\n node: NodeGraphNode,\n measuredSize?: NodeGraphMeasuredSize | null,\n defaults?: { width: number; height: number }\n): boolean {\n const box = getNodeBox(node, measuredSize, defaults);\n return (\n point.x >= box.x &&\n point.x <= box.x + box.width &&\n point.y >= box.y &&\n point.y <= box.y + box.height\n );\n}\n\n/** True when a rectangle contains a point. */\nexport function isPointInRect(point: Point2D, rect: WorldRect): boolean {\n return (\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height\n );\n}\n\n/** True when two axis-aligned rectangles overlap (non-strict). */\nexport function rectsIntersect(a: WorldRect, b: WorldRect): boolean {\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\n/**\n * True when `inner` is fully contained inside `outer` (closed comparison —\n * a rectangle that touches the outer's edge counts as contained). Used by\n * the group-drag controller to decide which nodes ride along with their\n * enclosing group.\n */\nexport function rectContains(outer: WorldRect, inner: WorldRect): boolean {\n return (\n inner.x >= outer.x &&\n inner.y >= outer.y &&\n inner.x + inner.width <= outer.x + outer.width &&\n inner.y + inner.height <= outer.y + outer.height\n );\n}\n\n/**\n * Compute the tight bounding box of a node list, factoring in measured /\n * default sizes. Returns a zero-width rect at the origin when the list\n * is empty.\n */\nexport function computeNodesBounds(\n nodes: ReadonlyArray<NodeGraphNode>,\n measuredSizes?: MeasuredSizeLookup,\n defaults?: { width: number; height: number }\n): WorldRect {\n if (nodes.length === 0) return { x: 0, y: 0, width: 0, height: 0 };\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const node of nodes) {\n const box = getNodeBox(node, measuredSizes?.(node.id), defaults);\n if (box.x < minX) minX = box.x;\n if (box.y < minY) minY = box.y;\n if (box.x + box.width > maxX) maxX = box.x + box.width;\n if (box.y + box.height > maxY) maxY = box.y + box.height;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Snap a world-space delta to the nearest grid increment. Pass `false`\n * for `grid` to return the delta unchanged.\n */\nexport function snapDelta(delta: Point2D, grid: number | false): Point2D {\n if (grid === false || grid <= 0) return delta;\n return {\n x: Math.round(delta.x / grid) * grid,\n y: Math.round(delta.y / grid) * grid,\n };\n}\n\n/**\n * Resolve the next selection for a click on `id`, honouring the additive\n * modifier (shift / cmd / ctrl). Non-additive replaces the selection with\n * just `id`; additive toggles `id` in/out of the current set. Shared by the\n * node-drag, group-drag, and edge-click paths so the toggle semantics stay\n * identical everywhere.\n */\nexport function toggleSelected(\n ids: ReadonlyArray<string>,\n id: string,\n additive: boolean\n): string[] {\n if (!additive) return [id];\n return ids.includes(id)\n ? ids.filter(existing => existing !== id)\n : [...ids, id];\n}\n\n/** Minimum size (in world units) a group can be resized down to. */\nexport const MIN_GROUP_SIZE = 32;\n\n/**\n * Compute the new group bounds during a resize gesture, given the\n * original bounds, the cumulative drag delta, and which handle is being\n * dragged. Enforces a minimum size on each axis so the group doesn't\n * collapse to zero.\n */\nexport function applyGroupResize(\n start: WorldRect,\n handle: 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w',\n delta: Point2D,\n minSize = MIN_GROUP_SIZE\n): WorldRect {\n let { x, y, width, height } = start;\n\n const movesLeft = handle === 'nw' || handle === 'w' || handle === 'sw';\n const movesRight = handle === 'ne' || handle === 'e' || handle === 'se';\n const movesTop = handle === 'nw' || handle === 'n' || handle === 'ne';\n const movesBottom = handle === 'sw' || handle === 's' || handle === 'se';\n\n if (movesLeft) {\n const dx = Math.min(delta.x, start.width - minSize);\n x = start.x + dx;\n width = start.width - dx;\n } else if (movesRight) {\n width = Math.max(minSize, start.width + delta.x);\n }\n if (movesTop) {\n const dy = Math.min(delta.y, start.height - minSize);\n y = start.y + dy;\n height = start.height - dy;\n } else if (movesBottom) {\n height = Math.max(minSize, start.height + delta.y);\n }\n return { x, y, width, height };\n}\n\n/**\n * Resolve a port reference to its **world-space** position + side using\n * the slot-registered port position lookup. Returns `null` when the node\n * is missing or the port hasn't been measured yet (the slot's\n * `useLayoutEffect` hasn't run).\n */\nexport function resolvePortRef(\n ref: NodeGraphPortRef,\n getNodeById: NodeLookup,\n getPortPosition: PortPositionLookup\n): {\n node: NodeGraphNode;\n position: Point2D;\n side: NodeGraphPortSide;\n dataType?: string;\n} | null {\n const node = getNodeById(ref.node);\n if (!node) return null;\n const portPos = getPortPosition(ref.node, ref.port);\n if (!portPos) return null;\n return {\n node,\n position: {\n x: node.position.x + portPos.x,\n y: node.position.y + portPos.y,\n },\n side: portPos.side,\n ...(portPos.dataType !== undefined ? { dataType: portPos.dataType } : {}),\n };\n}\n\n/**\n * Resolve both endpoints of an edge to world-space positions + sides.\n * Returns `null` when either endpoint can't be resolved (missing node or\n * not-yet-measured port).\n */\nexport function resolveEdgeEndpoints(\n edge: NodeGraphEdge,\n getNodeById: NodeLookup,\n getPortPosition: PortPositionLookup\n): {\n source: Point2D;\n srcSide: NodeGraphPortSide;\n target: Point2D;\n tgtSide: NodeGraphPortSide;\n} | null {\n const src = resolvePortRef(edge.source, getNodeById, getPortPosition);\n if (!src) return null;\n const tgt = resolvePortRef(edge.target, getNodeById, getPortPosition);\n if (!tgt) return null;\n return {\n source: src.position,\n srcSide: src.side,\n target: tgt.position,\n tgtSide: tgt.side,\n };\n}\n\n/**\n * Apply a selection-driven cascade delete to a graph snapshot. Removes\n * the selected nodes / edges / groups and additionally drops any edge\n * whose source or target node was removed — eliminates the classic\n * \"orphan edge dangling off a deleted node\" bug. Pure function; returns\n * the same array references when nothing was removed.\n *\n * Used internally by `<NodeGraph>` when no `onDelete` is supplied, and\n * exported so consumers who DO supply `onDelete` (e.g. to snapshot for\n * undo, log telemetry, show confirmations) can reuse the same logic\n * without rewriting the filter.\n */\nexport function applyCascadeDelete<TNode extends { id: string }>(\n input: {\n nodes: ReadonlyArray<TNode>;\n edges: ReadonlyArray<NodeGraphEdge>;\n groups: ReadonlyArray<{ id: string }>;\n },\n selection: {\n nodes: ReadonlyArray<string>;\n edges: ReadonlyArray<string>;\n groups: ReadonlyArray<string>;\n }\n): {\n nodes: TNode[] | ReadonlyArray<TNode>;\n edges: NodeGraphEdge[] | ReadonlyArray<NodeGraphEdge>;\n groups: typeof input.groups;\n} {\n const removedNodeIds = new Set(selection.nodes);\n const removedEdgeIds = new Set(selection.edges);\n const removedGroupIds = new Set(selection.groups);\n\n const nodes =\n removedNodeIds.size > 0\n ? input.nodes.filter(n => !removedNodeIds.has(n.id))\n : input.nodes;\n const edges = input.edges.filter(\n e =>\n !removedEdgeIds.has(e.id) &&\n !removedNodeIds.has(e.source.node) &&\n !removedNodeIds.has(e.target.node)\n );\n const groups =\n removedGroupIds.size > 0\n ? input.groups.filter(g => !removedGroupIds.has(g.id))\n : input.groups;\n\n return {\n nodes,\n // Keep the input array reference when nothing changed — lets the\n // consumer skip an unnecessary `setEdges` if they want to.\n edges: edges.length === input.edges.length ? input.edges : edges,\n groups,\n };\n}\n\n/**\n * Find the topmost edge whose Bézier passes within `threshold` world units\n * of `point`. Iterates in reverse so the last-drawn edge wins, matching what\n * the user sees on top. Returns the edge id, or `null` when none is hit.\n *\n * Used for pointer hover + click selection + right-click targeting of edges,\n * which are drawn on a canvas (no DOM to hit-test against).\n */\nexport function findEdgeAtPoint(\n point: Point2D,\n edges: ReadonlyArray<NodeGraphEdge>,\n getNodeById: NodeLookup,\n getPortPosition: PortPositionLookup,\n threshold: number\n): string | null {\n for (let i = edges.length - 1; i >= 0; i--) {\n const edge = edges[i];\n if (!edge) continue;\n const ends = resolveEdgeEndpoints(edge, getNodeById, getPortPosition);\n if (!ends) continue;\n const cp = getBezierControlPoints(\n ends.source,\n ends.srcSide,\n ends.target,\n ends.tgtSide\n );\n // Broad-phase rejection: a cubic Bézier is contained within the convex\n // hull of its control points, so a point outside their bounding box\n // (expanded by `threshold`) can never be within `threshold` of the curve.\n // Skips the 24-sample distance test for the vast majority of edges on\n // large graphs — turns hover/click hit-testing from O(edges × 24) into a\n // couple of comparisons per non-candidate edge.\n if (point.x < Math.min(cp.p0.x, cp.c1.x, cp.c2.x, cp.p3.x) - threshold)\n continue;\n if (point.x > Math.max(cp.p0.x, cp.c1.x, cp.c2.x, cp.p3.x) + threshold)\n continue;\n if (point.y < Math.min(cp.p0.y, cp.c1.y, cp.c2.y, cp.p3.y) - threshold)\n continue;\n if (point.y > Math.max(cp.p0.y, cp.c1.y, cp.c2.y, cp.p3.y) + threshold)\n continue;\n if (isPointNearBezier(point, cp, threshold)) return edge.id;\n }\n return null;\n}\n\n// ─── Internals ───\n\nfunction pointToSegmentDistance(p: Point2D, a: Point2D, b: Point2D): number {\n const abx = b.x - a.x;\n const aby = b.y - a.y;\n const lenSq = abx * abx + aby * aby;\n if (lenSq === 0) return Math.hypot(p.x - a.x, p.y - a.y);\n let t = ((p.x - a.x) * abx + (p.y - a.y) * aby) / lenSq;\n if (t < 0) t = 0;\n else if (t > 1) t = 1;\n return Math.hypot(p.x - (a.x + t * abx), p.y - (a.y + t * aby));\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortSlots.js","sources":["
|
|
1
|
+
{"version":3,"file":"sortSlots.js","sources":["src/components/editor/NodeGraph/sortSlots.ts"],"sourcesContent":["import React from 'react';\n\nimport { devWarn } from '@/utils/devWarn';\n\nimport { NODE_GRAPH_SLOT } from './NodeGraph.types';\nimport {\n NodeGraphBackground,\n NodeGraphMinimap,\n NodeGraphSpawnPalette,\n NodeGraphToolbar,\n} from './NodeGraphSlots';\n\nimport type { NodeGraphSlotKind, NodeGraphSlotMarker } from './NodeGraph.types';\n\ntype NodeGraphBackgroundProps = React.ComponentProps<\n typeof NodeGraphBackground\n>;\ntype NodeGraphMinimapProps = React.ComponentProps<typeof NodeGraphMinimap>;\ntype NodeGraphToolbarProps = React.ComponentProps<typeof NodeGraphToolbar>;\ntype NodeGraphSpawnPaletteProps = React.ComponentProps<\n typeof NodeGraphSpawnPalette\n>;\n\nexport interface SortedSlots {\n hasBackground: boolean;\n backgroundProps: NodeGraphBackgroundProps | null;\n hasMinimap: boolean;\n minimapProps: NodeGraphMinimapProps | null;\n /** Multiple toolbars can co-exist (e.g. top-left + top-right). */\n toolbars: ReadonlyArray<NodeGraphToolbarProps>;\n spawnPaletteProps: NodeGraphSpawnPaletteProps | null;\n}\n\nfunction getSlotKind(el: React.ReactElement): NodeGraphSlotKind | null {\n if (typeof el.type !== 'function' && typeof el.type !== 'object') {\n return null;\n }\n const marker = (el.type as Partial<NodeGraphSlotMarker>)[NODE_GRAPH_SLOT];\n return marker ?? null;\n}\n\n/**\n * Walk `<NodeGraph>` children, recognise the compound slot subcomponents\n * (`<NodeGraph.Background>`, `<NodeGraph.Minimap>`, `<NodeGraph.Toolbar>`,\n * `<NodeGraph.SpawnPalette>`), and collect their props. Anything else\n * triggers a dev-time warning — the main component never renders raw\n * children, only the recognised slots in the right places of its tree.\n */\nexport function sortSlots(children: React.ReactNode): SortedSlots {\n // `null as T | null` (rather than `: T | null = null`) keeps the flow type a\n // nullable union: these are only ever assigned inside the `forEach` callback\n // below, and TypeScript can't see closure mutations, so a plain `= null`\n // would narrow them to `null` and make the `!== null` checks below look dead.\n let backgroundProps = null as NodeGraphBackgroundProps | null;\n let minimapProps = null as NodeGraphMinimapProps | null;\n let spawnPaletteProps = null as NodeGraphSpawnPaletteProps | null;\n const toolbars: NodeGraphToolbarProps[] = [];\n React.Children.forEach(children, child => {\n if (!React.isValidElement(child)) {\n if (child != null && child !== false) {\n devWarn(\n '[NodeGraph] children must be slot subcomponents (<NodeGraph.Background />, <NodeGraph.Minimap />, <NodeGraph.Toolbar />, <NodeGraph.SpawnPalette />).'\n );\n }\n return;\n }\n const kind = getSlotKind(child);\n if (kind === 'background') {\n backgroundProps = child.props as NodeGraphBackgroundProps;\n } else if (kind === 'minimap') {\n minimapProps = child.props as NodeGraphMinimapProps;\n } else if (kind === 'toolbar') {\n toolbars.push(child.props as NodeGraphToolbarProps);\n } else if (kind === 'spawn-palette') {\n spawnPaletteProps = child.props as NodeGraphSpawnPaletteProps;\n } else {\n const dn = (child.type as { displayName?: string } | undefined)\n ?.displayName;\n if (dn?.startsWith('NodeGraph.')) {\n devWarn(\n `[NodeGraph] child \"${dn}\" looks like a slot subcomponent but lacks the ` +\n 'NODE_GRAPH_SLOT marker. If you wrapped it in React.memo or HOCs, copy the ' +\n 'marker symbol over to the wrapper.'\n );\n }\n }\n });\n return {\n hasBackground: backgroundProps !== null,\n backgroundProps,\n hasMinimap: minimapProps !== null,\n minimapProps,\n toolbars,\n spawnPaletteProps,\n };\n}\n"],"names":[],"mappings":";;;;AAiCA,SAAS,WAAW,CAAC,EAAsB,EAAA;AACzC,IAAA,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,EAAE;AAChE,QAAA,OAAO,IAAI;IACb;IACA,MAAM,MAAM,GAAI,EAAE,CAAC,IAAqC,CAAC,eAAe,CAAC;IACzE,OAAO,MAAM,IAAI,IAAI;AACvB;AAEA;;;;;;AAMG;AACG,SAAU,SAAS,CAAC,QAAyB,EAAA;;;;;IAKjD,IAAI,eAAe,GAAG,IAAuC;IAC7D,IAAI,YAAY,GAAG,IAAoC;IACvD,IAAI,iBAAiB,GAAG,IAAyC;IACjE,MAAM,QAAQ,GAA4B,EAAE;IAC5C,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAG;QACvC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;YAChC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK,EAAE;gBACpC,OAAO,CACL,uJAAuJ,CACxJ;YACH;YACA;QACF;AACA,QAAA,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC;AAC/B,QAAA,IAAI,IAAI,KAAK,YAAY,EAAE;AACzB,YAAA,eAAe,GAAG,KAAK,CAAC,KAAiC;QAC3D;AAAO,aAAA,IAAI,IAAI,KAAK,SAAS,EAAE;AAC7B,YAAA,YAAY,GAAG,KAAK,CAAC,KAA8B;QACrD;AAAO,aAAA,IAAI,IAAI,KAAK,SAAS,EAAE;AAC7B,YAAA,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAA8B,CAAC;QACrD;AAAO,aAAA,IAAI,IAAI,KAAK,eAAe,EAAE;AACnC,YAAA,iBAAiB,GAAG,KAAK,CAAC,KAAmC;QAC/D;aAAO;AACL,YAAA,MAAM,EAAE,GAAI,KAAK,CAAC;AAChB,kBAAE,WAAW;AACf,YAAA,IAAI,EAAE,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE;gBAChC,OAAO,CACL,CAAA,mBAAA,EAAsB,EAAE,CAAA,+CAAA,CAAiD;oBACvE,4EAA4E;AAC5E,oBAAA,oCAAoC,CACvC;YACH;QACF;AACF,IAAA,CAAC,CAAC;IACF,OAAO;QACL,aAAa,EAAE,eAAe,KAAK,IAAI;QACvC,eAAe;QACf,UAAU,EAAE,YAAY,KAAK,IAAI;QACjC,YAAY;QACZ,QAAQ;QACR,iBAAiB;KAClB;AACH;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDragGesture.js","sources":["
|
|
1
|
+
{"version":3,"file":"useDragGesture.js","sources":["src/components/editor/NodeGraph/useDragGesture.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useLayoutEffect, useRef } from 'react';\n\nimport type React from 'react';\n\ninterface ActiveGesture {\n pointerId: number;\n teardown: () => void;\n}\n\nexport interface DragGestureHandlers {\n /** Fired on each document `pointermove` for the captured pointer. */\n onMove: (event: PointerEvent) => void;\n /**\n * Fired on `pointercancel` for the captured pointer. Document listeners are\n * already detached by the time this runs — just reset business state.\n */\n onCancel: () => void;\n}\n\nexport interface DragGestureControls {\n /**\n * Begin a pointer-drag on `event.currentTarget`: capture the pointer, attach\n * document `pointermove` / `pointercancel` listeners, and remember the\n * gesture so `finish` (or unmount) can release it. Any gesture still in\n * flight is torn down first — defensive against a lost `pointercancel`\n * (e.g. pointer capture dropped on alt-tab between moves).\n */\n begin: (\n event: React.PointerEvent<HTMLElement>,\n handlers: DragGestureHandlers\n ) => void;\n /**\n * Finish from a `pointerup` handler: release pointer capture and detach the\n * document listeners. Returns `false` when the up doesn't belong to the\n * active gesture (stale or secondary pointer) so the caller can bail.\n */\n finish: (event: React.PointerEvent<HTMLElement>) => boolean;\n}\n\n/**\n * Mechanical lifecycle for a pointer-capture drag gesture, shared by the node\n * and group drag controllers. Owns pointer capture, document listener\n * attach/detach, the per-pointer id guard, and cleanup on unmount — leaving\n * each hook to supply only its own move / cancel / up business logic. Document\n * listeners exist only while a gesture is in flight, so there's zero\n * pointermove cost between drags.\n */\nexport function useDragGesture(): DragGestureControls {\n const activeRef = useRef<ActiveGesture | null>(null);\n\n // Release in-flight document listeners if the component unmounts mid-drag.\n useLayoutEffect(() => {\n return () => {\n activeRef.current?.teardown();\n activeRef.current = null;\n };\n }, []);\n\n const begin = useCallback(\n (\n event: React.PointerEvent<HTMLElement>,\n handlers: DragGestureHandlers\n ): void => {\n activeRef.current?.teardown();\n\n const pointerId = event.pointerId;\n event.currentTarget.setPointerCapture(pointerId);\n\n const handleMove = (e: PointerEvent): void => {\n if (e.pointerId !== pointerId) return;\n handlers.onMove(e);\n };\n const handleCancel = (e: PointerEvent): void => {\n if (e.pointerId !== pointerId) return;\n teardown();\n handlers.onCancel();\n };\n // Function declaration (hoisted) so the handlers above can close over it.\n function teardown(): void {\n document.removeEventListener('pointermove', handleMove);\n document.removeEventListener('pointercancel', handleCancel);\n if (activeRef.current?.pointerId === pointerId) {\n activeRef.current = null;\n }\n }\n\n document.addEventListener('pointermove', handleMove);\n document.addEventListener('pointercancel', handleCancel);\n activeRef.current = { pointerId, teardown };\n },\n []\n );\n\n const finish = useCallback(\n (event: React.PointerEvent<HTMLElement>): boolean => {\n const active = activeRef.current;\n if (active?.pointerId !== event.pointerId) return false;\n const target = event.currentTarget;\n if (target.hasPointerCapture(event.pointerId)) {\n target.releasePointerCapture(event.pointerId);\n }\n active.teardown();\n return true;\n },\n []\n );\n\n return { begin, finish };\n}\n"],"names":[],"mappings":";;;AAyCA;;;;;;;AAOG;;AAED;;;AAIE;AACE;AACA;AACF;;;AAQE;AAEA;AACA;AAEA;AACE;;AACA;AACF;AACA;AACE;;AACA;;AAEF;;AAEA;AACE;AACA;;AAEE;;;AAIJ;AACA;;;AAMJ;AAEI;AACA;AAA2C;AAC3C;;AAEE;;;AAGF;;AAKJ;AACF;;"}
|
|
@@ -4,7 +4,7 @@ import '../../../utils/devWarn.js';
|
|
|
4
4
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
5
5
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
6
6
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
7
|
-
import '
|
|
7
|
+
import '@vanilla-extract/css';
|
|
8
8
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
9
9
|
import 'react/jsx-runtime';
|
|
10
10
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeGraph.js","sources":["../../../../../../src/components/editor/NodeGraph/useNodeGraph.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;AAwBA;AACE;AACA;AACA;;AA2FF;;;;;;;;;;;;;;;;;;AAkBG;AACG;AAGJ;AAGA;AAGA;AAGA;;;AAMA;AACA;AACA;AACA;AAEA;;;AAGE;AACA;;AAGF;AAEI;;AACA;;;;;AAMG;AAGH;AACA;AACA;;AAIA;;AAEA;AACE;AACE;AACA;;AAED;;;AAMP;AAEI;;AACA;;AAEA;AACA;AACE;;AAEE;;AAED;;AAEL;;AAME;AACF;AAIF;AACE;AACA;AAEE;AACA;;;;;;;;AAYF;AACA;AACA;;;;;AAUE;AAKA;AAAyB;AACzB;AACA;AACA;AACA;AACF;;;AAaM;AACA;;AAGJ;;;AAEA;;;;AAIE;;AAEF;AACA;AACF;;;AAOE;;;AAGE;AACE;;AAEF;AACE;;;AAGJ;AACA;;AAKJ;AAEI;;AACA;;AAEA;AACA;AACE;;;AAGE;AACD;;AAEL;AAIF;;;AAIA;;;;;AAMI;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;AA0BN;;"}
|
|
1
|
+
{"version":3,"file":"useNodeGraph.js","sources":["src/components/editor/NodeGraph/useNodeGraph.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useState } from 'react';\n\nimport { useLatest } from '@/hooks';\n\nimport {\n duplicateNodes as duplicateNodesImpl,\n edgesConnectedToPort,\n} from './nodeGraphActions';\nimport { generateEdgeId, generateNodeId } from './nodeGraphIds';\nimport { applyCascadeDelete } from './nodeGraphMath';\n\nimport type {\n NodeGraphEdge,\n NodeGraphGroup,\n NodeGraphNode,\n NodeGraphPortRef,\n NodeGraphSelection,\n} from './NodeGraph.types';\nimport type { DuplicateNodesOptions } from './nodeGraphActions';\nimport type { WorldRect } from '@/components/primitives/viewport';\nimport type { Dispatch, SetStateAction } from 'react';\n\nconst EMPTY_SELECTION: NodeGraphSelection = {\n nodes: [],\n edges: [],\n groups: [],\n};\n\n/** A node accepted by `addNode` — the `id` is generated when omitted. */\nexport type NodeGraphNodeInput = Omit<NodeGraphNode, 'id'> & { id?: string };\n\nexport interface UseNodeGraphOptions {\n /** Initial nodes. @default [] */\n nodes?: NodeGraphNode[];\n /** Initial edges. @default [] */\n edges?: NodeGraphEdge[];\n /** Initial groups. @default [] */\n groups?: NodeGraphGroup[];\n /** Initial selection. @default { nodes: [], edges: [], groups: [] } */\n selection?: NodeGraphSelection;\n}\n\nexport interface AddGroupOptions {\n /** Group id. Generated when omitted. */\n id?: string;\n label?: string;\n color?: string;\n}\n\n/** The four controlled props + change handlers, ready to spread. */\nexport interface NodeGraphBind {\n nodes: NodeGraphNode[];\n edges: NodeGraphEdge[];\n groups: NodeGraphGroup[];\n selection: NodeGraphSelection;\n onNodesChange: (nodes: NodeGraphNode[]) => void;\n onEdgesChange: (edges: NodeGraphEdge[]) => void;\n onGroupsChange: (groups: NodeGraphGroup[]) => void;\n onSelectionChange: (selection: NodeGraphSelection) => void;\n}\n\nexport interface UseNodeGraphReturn {\n nodes: NodeGraphNode[];\n edges: NodeGraphEdge[];\n groups: NodeGraphGroup[];\n selection: NodeGraphSelection;\n\n setNodes: Dispatch<SetStateAction<NodeGraphNode[]>>;\n setEdges: Dispatch<SetStateAction<NodeGraphEdge[]>>;\n setGroups: Dispatch<SetStateAction<NodeGraphGroup[]>>;\n setSelection: Dispatch<SetStateAction<NodeGraphSelection>>;\n\n /** Append a node (generating an id when omitted). Returns the node id. */\n addNode: (node: NodeGraphNodeInput) => string;\n /**\n * Cascade-delete the given nodes — removes them, drops any edge touching\n * them, and prunes them from the selection.\n */\n removeNodes: (ids: ReadonlyArray<string>) => void;\n /** Remove the given edges and prune them from the selection. */\n removeEdges: (ids: ReadonlyArray<string>) => void;\n /** Remove every edge connected to a port — \"detach all\" for one socket. */\n disconnectPort: (node: string, port: string) => void;\n /**\n * Cascade-delete the current selection (nodes + edges + groups) and clear\n * it — the programmatic equivalent of pressing Delete.\n */\n removeSelection: () => void;\n /**\n * Clone nodes (defaults to the current selection), append the copies, and\n * select them. Returns the new node ids.\n */\n duplicateNodes: (\n ids?: ReadonlyArray<string>,\n options?: DuplicateNodesOptions\n ) => string[];\n /**\n * Add an edge between two ports, de-duplicating identical endpoints.\n * Returns the new (or existing) edge id.\n */\n connect: (\n source: NodeGraphPortRef,\n target: NodeGraphPortRef,\n data?: unknown\n ) => string;\n /** Append a group. Returns the group id. */\n addGroup: (bounds: WorldRect, options?: AddGroupOptions) => string;\n /** Remove the given groups and prune them from the selection. */\n removeGroups: (ids: ReadonlyArray<string>) => void;\n /** Clear the selection. */\n clearSelection: () => void;\n\n /** Spread onto `<NodeGraph {...bind} />` to wire all four controlled props. */\n bind: NodeGraphBind;\n}\n\n/**\n * Own a node graph's state (nodes / edges / groups / selection) plus the\n * mutations every editor re-implements — add / remove (with edge cascade) /\n * duplicate / connect / group. Spread `bind` onto `<NodeGraph>` and call the\n * actions from your toolbar / context menu:\n *\n * ```tsx\n * const graph = useNodeGraph({ nodes: initialNodes, edges: initialEdges });\n * return (\n * <NodeGraph {...graph.bind} renderNode={renderNode}>\n * <NodeGraph.Background />\n * </NodeGraph>\n * );\n * // graph.addNode(...), graph.removeSelection(), graph.duplicateNodes(), ...\n * ```\n *\n * Uncontrolled by design — the hook owns the state. For controlled state\n * (Redux / Zustand / external store) wire the four `onChange` props yourself.\n */\nexport function useNodeGraph(\n options?: UseNodeGraphOptions\n): UseNodeGraphReturn {\n const [nodes, setNodes] = useState<NodeGraphNode[]>(\n () => options?.nodes ?? []\n );\n const [edges, setEdges] = useState<NodeGraphEdge[]>(\n () => options?.edges ?? []\n );\n const [groups, setGroups] = useState<NodeGraphGroup[]>(\n () => options?.groups ?? []\n );\n const [selection, setSelection] = useState<NodeGraphSelection>(\n () => options?.selection ?? EMPTY_SELECTION\n );\n\n // Snapshot refs so multi-slice actions read a consistent view without\n // re-creating the callbacks on every state change.\n const nodesRef = useLatest(nodes);\n const edgesRef = useLatest(edges);\n const groupsRef = useLatest(groups);\n const selectionRef = useLatest(selection);\n\n const addNode = useCallback((node: NodeGraphNodeInput): string => {\n const id = node.id ?? generateNodeId('node');\n const next: NodeGraphNode = { ...node, id };\n setNodes(prev => [...prev, next]);\n return id;\n }, []);\n\n const removeNodes = useCallback(\n (ids: ReadonlyArray<string>): void => {\n if (ids.length === 0) return;\n const removed = new Set(ids);\n const result = applyCascadeDelete(\n {\n nodes: nodesRef.current,\n edges: edgesRef.current,\n groups: groupsRef.current,\n },\n { nodes: ids, edges: [], groups: [] }\n );\n setNodes(result.nodes as NodeGraphNode[]);\n setEdges(result.edges as NodeGraphEdge[]);\n const sel = selectionRef.current;\n const keptEdgeIds = new Set(\n (result.edges as NodeGraphEdge[]).map(e => e.id)\n );\n const dropsNode = sel.nodes.some(nodeId => removed.has(nodeId));\n const dropsEdge = sel.edges.some(edgeId => !keptEdgeIds.has(edgeId));\n if (dropsNode || dropsEdge) {\n setSelection({\n nodes: sel.nodes.filter(nodeId => !removed.has(nodeId)),\n edges: sel.edges.filter(edgeId => keptEdgeIds.has(edgeId)),\n groups: sel.groups,\n });\n }\n },\n [nodesRef, edgesRef, groupsRef, selectionRef]\n );\n\n const removeEdges = useCallback(\n (ids: ReadonlyArray<string>): void => {\n if (ids.length === 0) return;\n const removed = new Set(ids);\n setEdges(prev => prev.filter(e => !removed.has(e.id)));\n const sel = selectionRef.current;\n if (sel.edges.some(edgeId => removed.has(edgeId))) {\n setSelection({\n nodes: sel.nodes,\n edges: sel.edges.filter(edgeId => !removed.has(edgeId)),\n groups: sel.groups,\n });\n }\n },\n [selectionRef]\n );\n\n const disconnectPort = useCallback(\n (node: string, port: string): void => {\n removeEdges(edgesConnectedToPort(edgesRef.current, { node, port }));\n },\n [edgesRef, removeEdges]\n );\n\n const removeSelection = useCallback((): void => {\n const sel = selectionRef.current;\n if (\n sel.nodes.length === 0 &&\n sel.edges.length === 0 &&\n sel.groups.length === 0\n ) {\n return;\n }\n const result = applyCascadeDelete(\n {\n nodes: nodesRef.current,\n edges: edgesRef.current,\n groups: groupsRef.current,\n },\n sel\n );\n setNodes(result.nodes as NodeGraphNode[]);\n setEdges(result.edges as NodeGraphEdge[]);\n setGroups(result.groups as NodeGraphGroup[]);\n setSelection(EMPTY_SELECTION);\n }, [nodesRef, edgesRef, groupsRef, selectionRef]);\n\n const duplicateNodes = useCallback(\n (\n ids?: ReadonlyArray<string>,\n duplicateOptions?: DuplicateNodesOptions\n ): string[] => {\n const targetIds = ids ?? selectionRef.current.nodes;\n const copies = duplicateNodesImpl(\n nodesRef.current,\n targetIds,\n duplicateOptions\n );\n if (copies.length === 0) return [];\n setNodes(prev => [...prev, ...copies]);\n const newIds = copies.map(n => n.id);\n setSelection({ nodes: newIds, edges: [], groups: [] });\n return newIds;\n },\n [nodesRef, selectionRef]\n );\n\n const connect = useCallback(\n (\n source: NodeGraphPortRef,\n target: NodeGraphPortRef,\n data?: unknown\n ): string => {\n const existing = edgesRef.current.find(\n e =>\n e.source.node === source.node &&\n e.source.port === source.port &&\n e.target.node === target.node &&\n e.target.port === target.port\n );\n if (existing) return existing.id;\n const id = generateEdgeId(source, target);\n const edge: NodeGraphEdge = {\n id,\n source,\n target,\n ...(data !== undefined ? { data } : {}),\n };\n setEdges(prev => [...prev, edge]);\n return id;\n },\n [edgesRef]\n );\n\n const addGroup = useCallback(\n (bounds: WorldRect, groupOptions?: AddGroupOptions): string => {\n const id = groupOptions?.id ?? generateNodeId('group');\n const group: NodeGraphGroup = {\n id,\n bounds,\n ...(groupOptions?.label !== undefined\n ? { label: groupOptions.label }\n : {}),\n ...(groupOptions?.color !== undefined\n ? { color: groupOptions.color }\n : {}),\n };\n setGroups(prev => [...prev, group]);\n return id;\n },\n []\n );\n\n const removeGroups = useCallback(\n (ids: ReadonlyArray<string>): void => {\n if (ids.length === 0) return;\n const removed = new Set(ids);\n setGroups(prev => prev.filter(g => !removed.has(g.id)));\n const sel = selectionRef.current;\n if (sel.groups.some(groupId => removed.has(groupId))) {\n setSelection({\n nodes: sel.nodes,\n edges: sel.edges,\n groups: sel.groups.filter(groupId => !removed.has(groupId)),\n });\n }\n },\n [selectionRef]\n );\n\n const clearSelection = useCallback((): void => {\n setSelection(EMPTY_SELECTION);\n }, []);\n\n const bind = useMemo<NodeGraphBind>(\n () => ({\n nodes,\n edges,\n groups,\n selection,\n onNodesChange: setNodes,\n onEdgesChange: setEdges,\n onGroupsChange: setGroups,\n onSelectionChange: setSelection,\n }),\n [nodes, edges, groups, selection]\n );\n\n return {\n nodes,\n edges,\n groups,\n selection,\n setNodes,\n setEdges,\n setGroups,\n setSelection,\n addNode,\n removeNodes,\n removeEdges,\n disconnectPort,\n removeSelection,\n duplicateNodes,\n connect,\n addGroup,\n removeGroups,\n clearSelection,\n bind,\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAwBA;AACE;AACA;AACA;;AA2FF;;;;;;;;;;;;;;;;;;AAkBG;AACG;AAGJ;AAGA;AAGA;AAGA;;;AAMA;AACA;AACA;AACA;AAEA;;;AAGE;AACA;;AAGF;AAEI;;AACA;;;;;AAMG;AAGH;AACA;AACA;;AAIA;;AAEA;AACE;AACE;AACA;;AAED;;;AAMP;AAEI;;AACA;;AAEA;AACA;AACE;;AAEE;;AAED;;AAEL;;AAME;AACF;AAIF;AACE;AACA;AAEE;AACA;;;;;;;;AAYF;AACA;AACA;;;;;AAUE;AAKA;AAAyB;AACzB;AACA;AACA;AACA;AACF;;;AAaM;AACA;;AAGJ;;;AAEA;;;;AAIE;;AAEF;AACA;AACF;;;AAOE;;;AAGE;AACE;;AAEF;AACE;;;AAGJ;AACA;;AAKJ;AAEI;;AACA;;AAEA;AACA;AACE;;;AAGE;AACD;;AAEL;AAIF;;;AAIA;;;;;AAMI;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;AA0BN;;"}
|
|
@@ -9,7 +9,7 @@ import '../../../utils/devWarn.js';
|
|
|
9
9
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
10
10
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
11
11
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
12
|
-
import '
|
|
12
|
+
import '@vanilla-extract/css';
|
|
13
13
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
14
14
|
import 'react/jsx-runtime';
|
|
15
15
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeGraphConnection.js","sources":["../../../../../../src/components/editor/NodeGraph/useNodeGraphConnection.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBA;AACA;AAkDA;;;AAGG;AACH;;;;;;AAKsB;AAClB;;AAEF;AACF;AAEA;;;;AAIG;AACH;AAKE;AACA;;;AAGE;;;;;AAKJ;AAEA;;;;;;;;;AASG;AACG;AAGJ;AAWA;AACA;AACA;AACA;AACA;AAEA;;;;AAKE;AACE;AACA;AACF;;;AAKE;AACA;;AACA;;AAKF;;;;;;;;AAYE;AACA;AACF;;;;AAOF;;;AAUI;;;AAIE;;AAEA;AACA;AACA;AACA;AACE;;AAEH;AACD;AACE;;;;;;;;;AAWA;;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;AAkBE;;;AAGA;;AAEA;AACE;;AAEH;AACH;AAEA;;AAEI;AACA;;;;AAGF;AACA;AACE;;AAEJ;;AAGE;;;;AAIA;AACA;AACA;AACA;AACF;AAEA;;AAKE;AACA;AACE;AAEE;AAEF;;AAEJ;AAEA;AAIE;AACA;;AAEE;;;AAGA;;;AAGJ;;AAGE;AACA;;AAEA;;AACA;AACA;AAEA;;;;AAIM;AACA;AACA;AACD;;;AAGC;AACA;AACA;AACD;;;AAGH;AACA;;AAEK;AACA;AAEG;;;;AAKN;;;AAGE;AACA;AACA;AACD;;;;;;;AAQC;AACA;AACA;AACD;;;;;AAML;;;;;;;AAMI;AACE;;AAEA;;AAEF;;;;;AAKF;;AAEA;AACD;;;AAID;AACA;;AAEA;;;;AAGE;AACA;;AAED;;AAGH;AACA;AACA;AACA;AACF;;;;;;;;;AAUC;;AASC;;;;;;;;AAMA;;;;AAIE;AACD;AACH;AAIF;;AAQI;;;;AAGA;AACA;AACE;AACA;AACA;;AAED;AACH;AAIF;AACF;;"}
|
|
1
|
+
{"version":3,"file":"useNodeGraphConnection.js","sources":["src/components/editor/NodeGraph/useNodeGraphConnection.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { screenToWorld } from '@/components/primitives/viewport';\nimport { useLatest } from '@/hooks';\n\nimport { generateEdgeId } from './nodeGraphIds';\n\nimport type {\n NodeGraphEdge,\n NodeGraphPortRef,\n NodeGraphSelection,\n NodeGraphConnectStartInfo,\n NodeGraphConnectEndInfo,\n NodeGraphConnectionValidationInfo,\n} from './NodeGraph.types';\nimport type { NodeGraphStore } from './NodeGraphStore';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type { ViewportTransform } from '@/components/primitives/viewport';\nimport type React from 'react';\n\n/** Pointer travel (screen px) before a reconnect grab counts as a drag. */\nconst RECONNECT_DRAG_THRESHOLD_PX = 4;\n\n/**\n * What a connection drag is doing: creating a brand-new edge from a port, or\n * re-dragging one endpoint of an existing edge (which on drop moves the\n * endpoint, deletes the edge, or — with no drag — selects it).\n */\ntype ConnectMode =\n | { kind: 'create' }\n | { kind: 'reconnect'; edgeId: string; end: 'source' | 'target' };\n\ninterface UseNodeGraphConnectionOptions {\n viewportRef: React.RefObject<HTMLDivElement | null>;\n store: NodeGraphStore;\n getTransform: () => ViewportTransform;\n isValidConnection?: (\n source: NodeGraphPortRef,\n target: NodeGraphPortRef,\n info: NodeGraphConnectionValidationInfo\n ) => boolean;\n onConnectStart?: (info: NodeGraphConnectStartInfo) => void;\n onConnectEnd?: (info: NodeGraphConnectEndInfo) => void;\n emitEdgesChange: (next: NodeGraphEdge[]) => void;\n /** Used to select an edge when a reconnect grab ends as a plain click. */\n emitSelectionChange?: (next: NodeGraphSelection) => void;\n}\n\ninterface UseNodeGraphConnectionReturn {\n /**\n * Handler attached to each `<NodeGraph.Port>` slot. Starts a connection\n * drag (create mode) and wires up document-level pointer listeners until\n * the drag terminates.\n */\n onPortPointerDown: (\n event: React.PointerEvent<HTMLElement>,\n nodeId: string,\n portId: string\n ) => void;\n /**\n * Start re-dragging one endpoint of an existing edge. Invoked by the\n * parent when the pointer grabs near an edge endpoint on the background.\n */\n onEdgeReconnectStart: (\n edgeId: string,\n end: 'source' | 'target',\n clientX: number,\n clientY: number\n ) => void;\n}\n\n/**\n * Read the port id/node id encoded in `data-*` attributes of an element\n * (or its ancestors). Returns null when the element isn't a port handle.\n */\nfunction readPortRefFromElement(el: Element | null): NodeGraphPortRef | null {\n let cursor: Element | null = el;\n while (cursor) {\n const node = cursor.getAttribute('data-node-id');\n const port = cursor.getAttribute('data-port-id');\n if (node && port) return { node, port };\n cursor = cursor.parentElement;\n }\n return null;\n}\n\n/**\n * Build the validation info object passed to `isValidConnection`. Looks up\n * the per-port side + dataType in the store so the consumer doesn't have\n * to maintain a parallel port index.\n */\nfunction buildValidationInfo(\n store: NodeGraphStore,\n source: NodeGraphPortRef,\n target: NodeGraphPortRef\n): NodeGraphConnectionValidationInfo {\n const src = store.getPortPosition(source.node, source.port);\n const tgt = store.getPortPosition(target.node, target.port);\n const sideCombo = src && tgt ? `${src.side}->${tgt.side}` : 'unknown';\n return {\n sameNode: source.node === target.node,\n sideCombo,\n ...(src?.dataType !== undefined ? { sourceDataType: src.dataType } : {}),\n ...(tgt?.dataType !== undefined ? { targetDataType: tgt.dataType } : {}),\n };\n}\n\n/**\n * Connection-drag controller. Owns the lifecycle from `pointerdown` (on a\n * port for a new edge, or near an edge endpoint for a reconnect) through\n * document-level `pointermove` / `pointerup` to the eventual edge emission.\n *\n * Document listeners are attached only while a drag is in flight — outside\n * of a gesture there is zero pointermove cost. Move events are coalesced\n * to one hit-test per animation frame so `document.elementFromPoint`\n * doesn't force a layout flush on every pointer poll.\n */\nexport function useNodeGraphConnection(\n options: UseNodeGraphConnectionOptions\n): UseNodeGraphConnectionReturn {\n const {\n viewportRef,\n store,\n getTransform,\n isValidConnection,\n onConnectStart,\n onConnectEnd,\n emitEdgesChange,\n emitSelectionChange,\n } = options;\n\n const isValidRef = useLatest(isValidConnection);\n const onConnectStartRef = useLatest(onConnectStart);\n const onConnectEndRef = useLatest(onConnectEnd);\n const emitEdgesChangeRef = useLatest(emitEdgesChange);\n const emitSelectionChangeRef = useLatest(emitSelectionChange);\n\n const teardownRef = useRef<(() => void) | null>(null);\n\n // If the component unmounts mid-drag, release the document listeners so\n // we don't leak handlers attached to the page.\n useEffect(() => {\n return () => {\n teardownRef.current?.();\n teardownRef.current = null;\n };\n }, []);\n\n const screenPointToWorld = useCallback(\n (clientX: number, clientY: number): Point2D => {\n const viewport = viewportRef.current;\n if (!viewport) return { x: 0, y: 0 };\n const rect = viewport.getBoundingClientRect();\n return screenToWorld(\n { x: clientX - rect.left, y: clientY - rect.top },\n getTransform()\n );\n },\n [viewportRef, getTransform]\n );\n\n // Whether a connection from `source` to `candidate` is allowed: defers to\n // the consumer's `isValidConnection` when provided, otherwise the built-in\n // rule of \"any port but one on the same node\". Shared by the live-hover\n // preview and both drop paths (create + reconnect) so the accept/reject\n // verdict can never drift between them.\n const isAcceptable = useCallback(\n (source: NodeGraphPortRef, candidate: NodeGraphPortRef): boolean => {\n const info = buildValidationInfo(store, source, candidate);\n const validator = isValidRef.current;\n return validator ? validator(source, candidate, info) : !info.sameNode;\n },\n [store, isValidRef]\n );\n\n // Shared drag lifecycle for both modes. `source` is the fixed endpoint the\n // preview draws from and the one passed to `isValidConnection` as the\n // source argument.\n const beginDrag = useCallback(\n (params: {\n source: NodeGraphPortRef;\n startClientX: number;\n startClientY: number;\n mode: ConnectMode;\n }): void => {\n const { source, startClientX, startClientY, mode } = params;\n\n // If a previous gesture didn't tear down for some reason, clean it now.\n teardownRef.current?.();\n\n const startWorld = screenPointToWorld(startClientX, startClientY);\n store.setInteraction({\n kind: 'connect',\n source,\n currentWorld: startWorld,\n candidate: null,\n invalid: false,\n ...(mode.kind === 'reconnect'\n ? { reconnectEdgeId: mode.edgeId, reconnectEnd: mode.end }\n : {}),\n });\n if (mode.kind === 'create') {\n onConnectStartRef.current?.({ source, worldPoint: startWorld });\n }\n\n let pendingPoint: { x: number; y: number } | null = null;\n let rafId = 0;\n let didMove = false;\n\n const runMove = (): void => {\n rafId = 0;\n const point = pendingPoint;\n pendingPoint = null;\n if (!point) return;\n const state = store.getInteraction();\n if (state.kind !== 'connect') return;\n\n const currentWorld = screenPointToWorld(point.x, point.y);\n const candidate = document.elementFromPoint(point.x, point.y);\n const candidateRef = readPortRefFromElement(candidate);\n\n let nextCandidate: NodeGraphPortRef | null = null;\n let invalid = false;\n if (candidateRef) {\n if (\n candidateRef.node === state.source.node &&\n candidateRef.port === state.source.port\n ) {\n // Hovering back over the fixed endpoint — treat as no candidate.\n nextCandidate = null;\n } else {\n nextCandidate = candidateRef;\n invalid = !isAcceptable(state.source, candidateRef);\n }\n }\n\n store.setInteraction({\n kind: 'connect',\n source: state.source,\n currentWorld,\n candidate: nextCandidate,\n invalid,\n ...(mode.kind === 'reconnect'\n ? { reconnectEdgeId: mode.edgeId, reconnectEnd: mode.end }\n : {}),\n });\n };\n\n const handleMove = (e: PointerEvent): void => {\n if (!didMove) {\n const dx = e.clientX - startClientX;\n const dy = e.clientY - startClientY;\n if (Math.hypot(dx, dy) >= RECONNECT_DRAG_THRESHOLD_PX) didMove = true;\n }\n pendingPoint = { x: e.clientX, y: e.clientY };\n if (rafId === 0) {\n rafId = requestAnimationFrame(runMove);\n }\n };\n\n const teardown = (): void => {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n document.removeEventListener('pointermove', handleMove);\n document.removeEventListener('pointerup', handleUp);\n document.removeEventListener('pointercancel', handleCancel);\n teardownRef.current = null;\n };\n\n const resolveCandidate = (\n clientX: number,\n clientY: number\n ): NodeGraphPortRef | null => {\n const dropEl = document.elementFromPoint(clientX, clientY);\n const finalCandidate = readPortRefFromElement(dropEl);\n return finalCandidate &&\n !(\n finalCandidate.node === source.node &&\n finalCandidate.port === source.port\n )\n ? finalCandidate\n : null;\n };\n\n const dropPoint = (\n clientX: number,\n clientY: number\n ): { worldPoint: Point2D; screenPoint: Point2D } => {\n const viewport = viewportRef.current;\n const rect = viewport?.getBoundingClientRect();\n const screenPoint = rect\n ? { x: clientX - rect.left, y: clientY - rect.top }\n : { x: clientX, y: clientY };\n return {\n worldPoint: screenPointToWorld(clientX, clientY),\n screenPoint,\n };\n };\n\n function handleUp(e: PointerEvent): void {\n teardown();\n const state = store.getInteraction();\n store.setInteraction({ kind: 'idle' });\n if (state.kind !== 'connect') return;\n const candidate = resolveCandidate(e.clientX, e.clientY);\n const drop = dropPoint(e.clientX, e.clientY);\n\n if (mode.kind === 'reconnect') {\n // A grab that never moved is a click — select the edge, keep it.\n if (!didMove) {\n emitSelectionChangeRef.current?.({\n nodes: [],\n edges: [mode.edgeId],\n groups: [],\n });\n onConnectEndRef.current?.({\n source,\n target: null,\n cancelled: true,\n ...drop,\n });\n return;\n }\n const accepted = candidate ? isAcceptable(source, candidate) : false;\n if (candidate && accepted) {\n const next = store\n .getData()\n .edges.map(edge =>\n edge.id === mode.edgeId\n ? mode.end === 'source'\n ? { ...edge, source: candidate }\n : { ...edge, target: candidate }\n : edge\n );\n emitEdgesChangeRef.current(next);\n onConnectEndRef.current?.({\n source,\n target: candidate,\n cancelled: false,\n ...drop,\n });\n } else {\n // Dropped on empty space or an invalid port → detach (delete).\n emitEdgesChangeRef.current(\n store.getData().edges.filter(edge => edge.id !== mode.edgeId)\n );\n onConnectEndRef.current?.({\n source,\n target: null,\n cancelled: true,\n ...drop,\n });\n }\n return;\n }\n\n // Create mode.\n let cancelled = !candidate;\n if (candidate) {\n const accepted = isAcceptable(source, candidate);\n if (!accepted) {\n cancelled = true;\n } else {\n const newEdge: NodeGraphEdge = {\n id: generateEdgeId(source, candidate),\n source,\n target: candidate,\n };\n emitEdgesChangeRef.current([...store.getData().edges, newEdge]);\n }\n }\n onConnectEndRef.current?.({\n source,\n target: cancelled ? null : (candidate ?? null),\n cancelled,\n ...drop,\n });\n }\n\n function handleCancel(e: PointerEvent): void {\n teardown();\n const state = store.getInteraction();\n store.setInteraction({ kind: 'idle' });\n if (state.kind !== 'connect') return;\n onConnectEndRef.current?.({\n source,\n target: null,\n cancelled: true,\n ...dropPoint(e.clientX, e.clientY),\n });\n }\n\n teardownRef.current = teardown;\n document.addEventListener('pointermove', handleMove);\n document.addEventListener('pointerup', handleUp);\n document.addEventListener('pointercancel', handleCancel);\n },\n [\n store,\n viewportRef,\n screenPointToWorld,\n onConnectStartRef,\n onConnectEndRef,\n emitEdgesChangeRef,\n emitSelectionChangeRef,\n isAcceptable,\n ]\n );\n\n const onPortPointerDown = useCallback(\n (\n event: React.PointerEvent<HTMLElement>,\n nodeId: string,\n portId: string\n ): void => {\n if (event.button !== 0) return;\n event.stopPropagation();\n event.preventDefault();\n // Bail when the port hasn't measured yet — without a registered\n // position the preview curve has no anchor.\n if (!store.getPortPosition(nodeId, portId)) return;\n beginDrag({\n source: { node: nodeId, port: portId },\n startClientX: event.clientX,\n startClientY: event.clientY,\n mode: { kind: 'create' },\n });\n },\n [store, beginDrag]\n );\n\n const onEdgeReconnectStart = useCallback(\n (\n edgeId: string,\n end: 'source' | 'target',\n clientX: number,\n clientY: number\n ): void => {\n const edge = store.getData().edges.find(e => e.id === edgeId);\n if (!edge) return;\n // The fixed endpoint is the *other* end — that's what the preview\n // anchors to and what the dragged end validates against.\n const fixed = end === 'source' ? edge.target : edge.source;\n beginDrag({\n source: fixed,\n startClientX: clientX,\n startClientY: clientY,\n mode: { kind: 'reconnect', edgeId, end },\n });\n },\n [store, beginDrag]\n );\n\n return { onPortPointerDown, onEdgeReconnectStart };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBA;AACA;AAkDA;;;AAGG;AACH;;;;;;AAKsB;AAClB;;AAEF;AACF;AAEA;;;;AAIG;AACH;AAKE;AACA;;;AAGE;;;;;AAKJ;AAEA;;;;;;;;;AASG;AACG;AAGJ;AAWA;AACA;AACA;AACA;AACA;AAEA;;;;AAKE;AACE;AACA;AACF;;;AAKE;AACA;;AACA;;AAKF;;;;;;;;AAYE;AACA;AACF;;;;AAOF;;;AAUI;;;AAIE;;AAEA;AACA;AACA;AACA;AACE;;AAEH;AACD;AACE;;;;;;;;;AAWA;;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;AAkBE;;;AAGA;;AAEA;AACE;;AAEH;AACH;AAEA;;AAEI;AACA;;;;AAGF;AACA;AACE;;AAEJ;;AAGE;;;;AAIA;AACA;AACA;AACA;AACF;AAEA;;AAKE;AACA;AACE;AAEE;AAEF;;AAEJ;AAEA;AAIE;AACA;;AAEE;;;AAGA;;;AAGJ;;AAGE;AACA;;AAEA;;AACA;AACA;AAEA;;;;AAIM;AACA;AACA;AACD;;;AAGC;AACA;AACA;AACD;;;AAGH;AACA;;AAEK;AACA;AAEG;;;;AAKN;;;AAGE;AACA;AACA;AACD;;;;;;;AAQC;AACA;AACA;AACD;;;;;AAML;;;;;;;AAMI;AACE;;AAEA;;AAEF;;;;;AAKF;;AAEA;AACD;;;AAID;AACA;;AAEA;;;;AAGE;AACA;;AAED;;AAGH;AACA;AACA;AACA;AACF;;;;;;;;;AAUC;;AASC;;;;;;;;AAMA;;;;AAIE;AACD;AACH;AAIF;;AAQI;;;;AAGA;AACA;AACE;AACA;AACA;;AAED;AACH;AAIF;AACF;;"}
|
|
@@ -9,7 +9,7 @@ import '../../../utils/devWarn.js';
|
|
|
9
9
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
10
10
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
11
11
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
12
|
-
import '
|
|
12
|
+
import '@vanilla-extract/css';
|
|
13
13
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
14
14
|
import 'react/jsx-runtime';
|
|
15
15
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeGraphEdgeInteraction.js","sources":["
|
|
1
|
+
{"version":3,"file":"useNodeGraphEdgeInteraction.js","sources":["src/components/editor/NodeGraph/useNodeGraphEdgeInteraction.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { worldToScreen as screenFromWorld } from '@/components/primitives/viewport';\nimport { useLatest } from '@/hooks';\n\nimport { findEdgeAtPoint, resolveEdgeEndpoints } from './nodeGraphMath';\n\nimport type { NodeGraphStore } from './NodeGraphStore';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type { ViewportTransform } from '@/components/primitives/viewport';\nimport type React from 'react';\n\n/**\n * Pointer proximity (screen px) for hovering / clicking / right-clicking an\n * edge. Divided by the current zoom to get the world-space threshold. Also\n * consumed by the parent for marquee-click edge selection and hit-testing.\n */\nexport const EDGE_HIT_PX = 6;\n\n/**\n * Pointer proximity (screen px) to an edge endpoint that starts a\n * reconnect / detach grab instead of selecting the edge.\n */\nconst EDGE_ENDPOINT_GRAB_PX = 16;\n\ninterface UseNodeGraphEdgeInteractionOptions {\n store: NodeGraphStore;\n getTransform: () => ViewportTransform;\n screenToWorldLocal: (clientX: number, clientY: number) => Point2D;\n localScreenPoint: (clientX: number, clientY: number) => Point2D;\n onEdgeReconnectStart: (\n edgeId: string,\n end: 'source' | 'target',\n clientX: number,\n clientY: number\n ) => void;\n disabled?: boolean;\n}\n\ninterface UseNodeGraphEdgeInteractionReturn {\n /** Attach to the root surface's `onPointerMove` — RAF-coalesced edge hover. */\n onRootPointerMove: (event: React.PointerEvent<HTMLDivElement>) => void;\n /** Attach to `onPointerLeave` — clears hover + cancels any pending hit-test. */\n onRootPointerLeave: () => void;\n /**\n * Attach to `onPointerDownCapture` — pre-empts the Viewport's marquee / pan\n * when the pointer lands near an edge endpoint, handing off to the\n * connection controller in reconnect mode.\n */\n onRootPointerDownCapture: (event: React.PointerEvent<HTMLDivElement>) => void;\n}\n\n/**\n * Edge hover + endpoint-grab interactions for the `<NodeGraph>` root surface.\n * Edges live on a canvas layer (no DOM to receive pointer events), so both\n * hovering an edge and grabbing its endpoint to reconnect are resolved by a\n * Bézier hit-test against the pointer position. Hover is RAF-coalesced to one\n * hit-test per frame; the endpoint grab runs in the capture phase so it wins\n * over the Viewport's own marquee / pan before they begin.\n */\nexport function useNodeGraphEdgeInteraction(\n options: UseNodeGraphEdgeInteractionOptions\n): UseNodeGraphEdgeInteractionReturn {\n const {\n store,\n getTransform,\n screenToWorldLocal,\n localScreenPoint,\n onEdgeReconnectStart,\n disabled,\n } = options;\n\n const disabledRef = useLatest(disabled);\n const edgeHoverRaf = useRef(0);\n const edgeHoverPoint = useRef<Point2D | null>(null);\n\n const clearEdgeHover = useCallback((): void => {\n const hover = store.getHover();\n if (hover.hoveredEdgeId !== null) {\n store.setHover({ ...hover, hoveredEdgeId: null });\n }\n }, [store]);\n\n const onRootPointerMove = useCallback(\n (event: React.PointerEvent<HTMLDivElement>): void => {\n if (disabledRef.current) return;\n if (store.getInteraction().kind !== 'idle') return;\n const el = event.target as Element | null;\n if (el?.closest('[data-node-id]')) {\n clearEdgeHover();\n return;\n }\n edgeHoverPoint.current = { x: event.clientX, y: event.clientY };\n if (edgeHoverRaf.current !== 0) return;\n edgeHoverRaf.current = requestAnimationFrame(() => {\n edgeHoverRaf.current = 0;\n const point = edgeHoverPoint.current;\n edgeHoverPoint.current = null;\n if (!point || store.getInteraction().kind !== 'idle') return;\n const zoom = getTransform().zoom || 1;\n const world = screenToWorldLocal(point.x, point.y);\n const edgeId = findEdgeAtPoint(\n world,\n store.getData().edges,\n store.getNodeById,\n store.getPortPosition,\n EDGE_HIT_PX / zoom\n );\n const hover = store.getHover();\n if (hover.hoveredEdgeId !== edgeId) {\n store.setHover({ ...hover, hoveredEdgeId: edgeId });\n }\n });\n },\n [store, disabledRef, getTransform, screenToWorldLocal, clearEdgeHover]\n );\n\n const onRootPointerLeave = useCallback((): void => {\n if (edgeHoverRaf.current !== 0) {\n cancelAnimationFrame(edgeHoverRaf.current);\n edgeHoverRaf.current = 0;\n }\n edgeHoverPoint.current = null;\n clearEdgeHover();\n }, [clearEdgeHover]);\n\n const onRootPointerDownCapture = useCallback(\n (event: React.PointerEvent<HTMLDivElement>): void => {\n if (disabledRef.current) return;\n if (event.button !== 0) return;\n const el = event.target as Element | null;\n if (el?.closest('[data-node-id]')) return;\n const transform = getTransform();\n const zoom = transform.zoom || 1;\n const world = screenToWorldLocal(event.clientX, event.clientY);\n const edges = store.getData().edges;\n const edgeId = findEdgeAtPoint(\n world,\n edges,\n store.getNodeById,\n store.getPortPosition,\n EDGE_HIT_PX / zoom\n );\n if (!edgeId) return;\n const edge = edges.find(e => e.id === edgeId);\n if (!edge) return;\n const ends = resolveEdgeEndpoints(\n edge,\n store.getNodeById,\n store.getPortPosition\n );\n if (!ends) return;\n const srcScreen = screenFromWorld(ends.source, transform);\n const tgtScreen = screenFromWorld(ends.target, transform);\n const local = localScreenPoint(event.clientX, event.clientY);\n const dSrc = Math.hypot(local.x - srcScreen.x, local.y - srcScreen.y);\n const dTgt = Math.hypot(local.x - tgtScreen.x, local.y - tgtScreen.y);\n if (Math.min(dSrc, dTgt) > EDGE_ENDPOINT_GRAB_PX) return;\n event.stopPropagation();\n event.preventDefault();\n const end = dSrc <= dTgt ? 'source' : 'target';\n onEdgeReconnectStart(edgeId, end, event.clientX, event.clientY);\n },\n [\n disabledRef,\n getTransform,\n screenToWorldLocal,\n localScreenPoint,\n store,\n onEdgeReconnectStart,\n ]\n );\n\n // Cancel a pending hover hit-test if the component unmounts mid-frame.\n useEffect(() => {\n return () => {\n if (edgeHoverRaf.current !== 0) {\n cancelAnimationFrame(edgeHoverRaf.current);\n }\n };\n }, []);\n\n return { onRootPointerMove, onRootPointerLeave, onRootPointerDownCapture };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAcA;;;;AAIG;AACI;AAEP;;;AAGG;AACH;AA6BA;;;;;;;AAOG;AACG;AAGJ;AASA;AACA;AACA;AAEA;AACE;AACA;AACE;;AAEJ;AAEA;;;AAGI;;AACA;AACA;AACE;;;AAGF;AACA;;AACA;AACE;AACA;AACA;;;;AAGA;;AAQA;AACA;AACE;;AAEJ;AACF;AAIF;AACE;AACE;AACA;;AAEF;AACA;AACF;AAEA;;;AAGI;;AACA;AACA;;AACA;AACA;AACA;;;AASA;;AACA;AACA;;AACA;AAKA;;;;AAGA;;;;;;;AAMA;AACA;AACF;;;;;;;AAQC;;;AAKD;AACE;AACE;;AAEJ;;AAGF;AACF;;"}
|
|
@@ -9,7 +9,7 @@ import '../../../utils/devWarn.js';
|
|
|
9
9
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
10
10
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
11
11
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
12
|
-
import '
|
|
12
|
+
import '@vanilla-extract/css';
|
|
13
13
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
14
14
|
import 'react/jsx-runtime';
|
|
15
15
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeGraphGroupDrag.js","sources":["../../../../../../src/components/editor/NodeGraph/useNodeGraphGroupDrag.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAkCA;AAiEA;;;;;;;;;;;;AAYG;AACG;;AAeJ;AACA;AACA;AACA;AACA;AAEA;AAEA;;;;;AAKG;;;;AAKG;AACE;AACA;;;;AAIF;AACE;;;AAEA;;AACA;AAAwC;;;AAG5C;AACF;;;;AAQE;AACE;;AACA;AAA8C;;AAEhD;AACF;AAIF;;;;;;AAOA;AACA;AAEA;AACE;AACA;;AACA;AACA;AACF;AAEA;AACE;AACE;AACA;;;;AAKJ;AACE;AACA;AACF;;AAGE;AACE;AACA;AACF;AACF;AAEA;AAEI;AACA;;AACA;AACE;AACA;AACF;AACF;;;;AAOF;AAEI;AACA;;AACA;;;AAGA;AACA;AACE;AACA;;;AAIF;AACE;;;AAEE;;AAEF;;AAOA;AACE;AACA;;;AAGA;;AAED;;;;;;AAKD;;AASA;AACE;;;;AAIA;;AAED;;AAEL;;;;;;;AAQC;AAGH;AACE;AACA;AACA;;AAEF;;AAOI;;;;;AAIA;AACA;AACA;AAEA;;AAEE;;;AAEA;;;;;AAKF;;;AAGI;;;;;;AAOJ;AACA;AACA;;AAEE;;AAEE;AACE;AACA;;;;;;AAON;;AAEA;AACA;AACE;AACA;AACD;;AAGC;;;AAGA;;;AAGA;AACA;;;AAGA;;AAEA;;AAEJ;;;;;;;;;AAUC;;AASC;;;;;;AAKA;;AAEA;AACA;AACE;AACA;AACD;;AAGC;;;;;;AAMA;;;;AAIA;AACA;AACA;;;;;AAKA;;;AAGA;;AAEA;AACD;AACH;;;;;;;;AASC;;AAQC;AACA;;;AAEA;;;AAIA;AAEA;;;AAII;;;;AAIA;AACE;AACA;AAAY;;AAEV;AACA;AACE;AACA;AACA;AACD;;AAEL;AACA;;AAEE;AACE;AACA;AAAY;;AAEV;;;AAGJ;AACA;;;;;;;;AAOC;AACL;;AAGE;;AAGA;;AAMG;AACA;AAGH;;;;;;AAKF;;AAEE;AACA;AACA;AACD;;AAGH;AACF;;;;;;;AAQC;;;;;;AAQL;;"}
|
|
1
|
+
{"version":3,"file":"useNodeGraphGroupDrag.js","sources":["src/components/editor/NodeGraph/useNodeGraphGroupDrag.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { screenToWorld as worldFromScreen } from '@/components/primitives/viewport';\nimport { useLatest } from '@/hooks';\n\nimport {\n applyGroupResize,\n getNodeBox,\n rectContains,\n rectsIntersect,\n snapDelta,\n toggleSelected,\n} from './nodeGraphMath';\nimport { useDragGesture } from './useDragGesture';\n\nimport type {\n NodeGraphGroup,\n NodeGraphNode,\n NodeGraphSelection,\n} from './NodeGraph.types';\nimport type {\n NodeGraphGroupResizeHandle,\n NodeGraphInteractionState,\n NodeGraphStore,\n} from './NodeGraphStore';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type {\n ViewportTransform,\n WorldRect,\n} from '@/components/primitives/viewport';\nimport type React from 'react';\n\nconst DRAG_START_THRESHOLD_PX = 3;\n\n/**\n * Pending interaction state buffered between pointermove and the next rAF\n * flush. Carries either a `drag-groups` or `resize-group` payload — they\n * share the same lifecycle, so the buffer keeps the latest of either.\n */\ntype PendingGroupInteraction = Extract<\n NodeGraphInteractionState,\n { kind: 'drag-groups' } | { kind: 'resize-group' }\n>;\n\ninterface UseNodeGraphGroupDragOptions {\n store: NodeGraphStore;\n getTransform: () => ViewportTransform;\n localScreenPoint: (clientX: number, clientY: number) => Point2D;\n snapToGrid: number | false;\n disabled?: boolean;\n defaultNodeSize: { width: number; height: number };\n emitGroupsChange: (next: NodeGraphGroup[]) => void;\n emitNodesChange: (next: NodeGraphNode[]) => void;\n emitSelectionChange: (next: NodeGraphSelection) => void;\n}\n\ninterface UseNodeGraphGroupDragReturn {\n onGroupBodyPointerDown: (\n event: React.PointerEvent<HTMLDivElement>,\n group: NodeGraphGroup\n ) => void;\n onGroupHandlePointerDown: (\n event: React.PointerEvent<HTMLDivElement>,\n group: NodeGraphGroup,\n handle: NodeGraphGroupResizeHandle\n ) => void;\n onGroupBodyPointerUp: (\n event: React.PointerEvent<HTMLDivElement>,\n group: NodeGraphGroup\n ) => void;\n}\n\ninterface GroupDragSession {\n kind: 'drag' | 'resize';\n pointerId: number;\n clickedGroupId: string;\n /** Handle being dragged (only for kind === 'resize'). */\n handle: NodeGraphGroupResizeHandle | null;\n startScreen: Point2D;\n startWorld: Point2D;\n selectionAtStart: NodeGraphSelection;\n /** Snapshot of bounds keyed by group id (for drag). */\n groupStartBounds: Map<string, WorldRect>;\n /**\n * Nodes fully contained inside one of the dragged groups at gesture\n * start — they ride along with the group(s). Set so the per-node\n * subscriber selector can do O(1) membership checks during the drag.\n */\n containedNodeIds: ReadonlySet<string>;\n /** Start positions of the contained nodes, keyed by node id. */\n nodeStartPositions: Map<string, Point2D>;\n /** Bounds of the resized group at start (for resize). */\n resizeStartBounds: WorldRect | null;\n additive: boolean;\n didDrag: boolean;\n}\n\n/**\n * Pointer-driven controller for group bodies and resize handles. Three\n * gestures share the same session state machine:\n *\n * - **drag**: pointerdown on a group body → snap-aware translation that\n * carries fully-contained nodes along, refused on overlap with other\n * groups, click-selection fallback when below the drag threshold.\n * - **resize**: pointerdown on a handle → eight-direction resize via\n * {@link applyGroupResize}, refused on overlap.\n * - **click**: pointerup before the drag threshold → selection toggle.\n *\n * Document listeners are attached only while a gesture is in flight.\n */\nexport function useNodeGraphGroupDrag(\n options: UseNodeGraphGroupDragOptions\n): UseNodeGraphGroupDragReturn {\n const {\n store,\n getTransform,\n localScreenPoint,\n snapToGrid,\n disabled,\n defaultNodeSize,\n emitGroupsChange,\n emitNodesChange,\n emitSelectionChange,\n } = options;\n\n const snapToGridRef = useLatest(snapToGrid);\n const disabledRef = useLatest(disabled);\n const emitGroupsChangeRef = useLatest(emitGroupsChange);\n const emitNodesChangeRef = useLatest(emitNodesChange);\n const emitSelectionChangeRef = useLatest(emitSelectionChange);\n\n const groupSessionRef = useRef<GroupDragSession | null>(null);\n\n /**\n * True when applying `delta` to the dragged groups (`session.groupStartBounds`)\n * would put any of them on top of a non-dragged group. Used by the\n * pointermove handler for live visual feedback and by pointerup to\n * refuse the commit.\n */\n const groupDragWouldOverlap = useCallback(\n (groupStartBounds: Map<string, WorldRect>, delta: Point2D): boolean => {\n const currentGroups = store.getData().groups;\n for (const [draggedId, start] of groupStartBounds) {\n const next: WorldRect = {\n x: start.x + delta.x,\n y: start.y + delta.y,\n width: start.width,\n height: start.height,\n };\n for (const other of currentGroups) {\n if (groupStartBounds.has(other.id)) continue;\n // Skip self defensively — already covered by the line above.\n if (other.id === draggedId) continue;\n if (rectsIntersect(next, other.bounds)) return true;\n }\n }\n return false;\n },\n [store]\n );\n\n /** True when the resized bounds would intersect any non-resized group. */\n const groupResizeWouldOverlap = useCallback(\n (groupId: string, nextBounds: WorldRect): boolean => {\n const currentGroups = store.getData().groups;\n for (const other of currentGroups) {\n if (other.id === groupId) continue;\n if (rectsIntersect(nextBounds, other.bounds)) return true;\n }\n return false;\n },\n [store]\n );\n\n const gesture = useDragGesture();\n\n // ── rAF-throttled interaction commits ──\n //\n // See `useNodeGraphNodeDrag` for the rationale — same coalescing pattern\n // applied to the group drag + resize move stream. Buffer the latest\n // interaction payload in a ref; an rAF callback drains it once per frame.\n const pendingInteractionRef = useRef<PendingGroupInteraction | null>(null);\n const rafRef = useRef<number>(0);\n\n const commitPending = useCallback((): void => {\n const pending = pendingInteractionRef.current;\n if (!pending) return;\n pendingInteractionRef.current = null;\n store.setInteraction(pending);\n }, [store]);\n\n const cancelRaf = useCallback((): void => {\n if (rafRef.current !== 0) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = 0;\n }\n }, []);\n\n /** Synchronous flush — cancels any pending rAF and commits immediately. */\n const flushPending = useCallback((): void => {\n cancelRaf();\n commitPending();\n }, [cancelRaf, commitPending]);\n\n useEffect(() => {\n return () => {\n cancelRaf();\n pendingInteractionRef.current = null;\n };\n }, [cancelRaf]);\n\n const scheduleCommit = useCallback(\n (next: PendingGroupInteraction): void => {\n pendingInteractionRef.current = next;\n if (rafRef.current !== 0) return;\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = 0;\n commitPending();\n });\n },\n [commitPending]\n );\n\n // Shared move handler for both the drag-groups and resize-group gestures.\n // Reads the active session from the ref and pushes the live interaction\n // delta into the store; the threshold-to-start gate lives here for drags.\n const handleGroupMove = useCallback(\n (e: PointerEvent): void => {\n const session = groupSessionRef.current;\n if (session?.pointerId !== e.pointerId) return;\n const current = localScreenPoint(e.clientX, e.clientY);\n const dx = current.x - session.startScreen.x;\n const dy = current.y - session.startScreen.y;\n const transform = getTransform();\n const worldDelta = {\n x: dx / transform.zoom,\n y: dy / transform.zoom,\n };\n const snapped = snapDelta(worldDelta, snapToGridRef.current);\n\n if (session.kind === 'drag') {\n if (!session.didDrag) {\n if (Math.hypot(dx, dy) < DRAG_START_THRESHOLD_PX) return;\n session.didDrag = true;\n }\n const ids: ReadonlySet<string> = new Set(\n session.groupStartBounds.keys()\n );\n const blocked = groupDragWouldOverlap(\n session.groupStartBounds,\n snapped\n );\n scheduleCommit({\n kind: 'drag-groups',\n groupIds: ids,\n containedNodeIds: session.containedNodeIds,\n startWorld: session.startWorld,\n delta: snapped,\n blocked,\n });\n } else if (session.resizeStartBounds && session.handle) {\n // `session.kind` is narrowed to 'resize' here (the `'drag'` branch\n // above is the only other kind); we still guard the optional\n // resize fields before using them.\n const nextBounds = applyGroupResize(\n session.resizeStartBounds,\n session.handle,\n snapped\n );\n const blocked = groupResizeWouldOverlap(\n session.clickedGroupId,\n nextBounds\n );\n scheduleCommit({\n kind: 'resize-group',\n groupId: session.clickedGroupId,\n handle: session.handle,\n startBounds: session.resizeStartBounds,\n delta: snapped,\n blocked,\n });\n }\n },\n [\n localScreenPoint,\n getTransform,\n snapToGridRef,\n groupDragWouldOverlap,\n groupResizeWouldOverlap,\n scheduleCommit,\n ]\n );\n\n const handleGroupCancel = useCallback((): void => {\n cancelRaf();\n pendingInteractionRef.current = null;\n groupSessionRef.current = null;\n store.setInteraction({ kind: 'idle' });\n }, [store, cancelRaf]);\n\n const onGroupBodyPointerDown = useCallback(\n (\n event: React.PointerEvent<HTMLDivElement>,\n group: NodeGraphGroup\n ): void => {\n if (event.button !== 0) return;\n event.stopPropagation();\n if (disabledRef.current) return;\n\n const additive = event.shiftKey || event.metaKey || event.ctrlKey;\n const currentSelection = store.getSelection();\n const alreadySelected = currentSelection.groups.includes(group.id);\n\n let dragIds: string[];\n if (alreadySelected) {\n dragIds = currentSelection.groups;\n } else if (!additive) {\n dragIds = [group.id];\n } else {\n dragIds = [...currentSelection.groups, group.id];\n }\n\n const startBounds = new Map<string, WorldRect>();\n for (const g of store.getData().groups) {\n if (dragIds.includes(g.id)) {\n startBounds.set(g.id, { ...g.bounds });\n }\n }\n\n // Snapshot nodes that are fully inside any of the dragged groups —\n // they ride along with the gesture so the visual grouping stays\n // consistent.\n const containedSet = new Set<string>();\n const nodeStartPositions = new Map<string, Point2D>();\n const measuredFor = store.getMeasuredSize;\n for (const n of store.getData().nodes) {\n const nb = getNodeBox(n, measuredFor(n.id), defaultNodeSize);\n for (const startRect of startBounds.values()) {\n if (rectContains(startRect, nb)) {\n containedSet.add(n.id);\n nodeStartPositions.set(n.id, { ...n.position });\n break;\n }\n }\n }\n const containedNodeIds: ReadonlySet<string> = containedSet;\n\n const startScreen = localScreenPoint(event.clientX, event.clientY);\n const startWorld = worldFromScreen(startScreen, getTransform());\n const pointerId = event.pointerId;\n gesture.begin(event, {\n onMove: handleGroupMove,\n onCancel: handleGroupCancel,\n });\n\n groupSessionRef.current = {\n kind: 'drag',\n pointerId,\n clickedGroupId: group.id,\n handle: null,\n startScreen,\n startWorld,\n selectionAtStart: currentSelection,\n groupStartBounds: startBounds,\n containedNodeIds,\n nodeStartPositions,\n resizeStartBounds: null,\n additive,\n didDrag: false,\n };\n },\n [\n disabledRef,\n defaultNodeSize,\n store,\n localScreenPoint,\n getTransform,\n gesture,\n handleGroupMove,\n handleGroupCancel,\n ]\n );\n\n const onGroupHandlePointerDown = useCallback(\n (\n event: React.PointerEvent<HTMLDivElement>,\n group: NodeGraphGroup,\n handle: NodeGraphGroupResizeHandle\n ): void => {\n if (event.button !== 0) return;\n event.stopPropagation();\n event.preventDefault();\n if (disabledRef.current) return;\n\n const startScreen = localScreenPoint(event.clientX, event.clientY);\n const startWorld = worldFromScreen(startScreen, getTransform());\n const pointerId = event.pointerId;\n gesture.begin(event, {\n onMove: handleGroupMove,\n onCancel: handleGroupCancel,\n });\n\n groupSessionRef.current = {\n kind: 'resize',\n pointerId,\n clickedGroupId: group.id,\n handle,\n startScreen,\n startWorld,\n selectionAtStart: store.getSelection(),\n groupStartBounds: new Map(),\n containedNodeIds: new Set<string>(),\n nodeStartPositions: new Map(),\n resizeStartBounds: { ...group.bounds },\n additive: false,\n didDrag: true,\n };\n // Immediately register the resize interaction so the canvas + overlay\n // start tracking from delta=0 at the click point.\n store.setInteraction({\n kind: 'resize-group',\n groupId: group.id,\n handle,\n startBounds: { ...group.bounds },\n delta: { x: 0, y: 0 },\n blocked: false,\n });\n },\n [\n disabledRef,\n localScreenPoint,\n getTransform,\n store,\n gesture,\n handleGroupMove,\n handleGroupCancel,\n ]\n );\n\n const onGroupBodyPointerUp = useCallback(\n (\n event: React.PointerEvent<HTMLDivElement>,\n group: NodeGraphGroup\n ): void => {\n const session = groupSessionRef.current;\n if (session?.pointerId !== event.pointerId) return;\n event.stopPropagation();\n gesture.finish(event);\n\n // Drain the rAF buffer so `store.getInteraction()` below reflects the\n // last pointermove rather than the previous frame's commit.\n flushPending();\n\n const interaction = store.getInteraction();\n\n if (session.kind === 'drag' && session.didDrag) {\n if (interaction.kind === 'drag-groups' && !interaction.blocked) {\n const delta = interaction.delta;\n // Apply the delta to both groups and any nodes that were\n // contained at gesture start, in a single set of state writes\n // so consumers get one atomic onGroupsChange + onNodesChange.\n const nextGroups = store.getData().groups.map(g => {\n const start = session.groupStartBounds.get(g.id);\n if (!start) return g;\n return {\n ...g,\n bounds: {\n ...start,\n x: start.x + delta.x,\n y: start.y + delta.y,\n },\n };\n });\n emitGroupsChangeRef.current(nextGroups);\n if (session.nodeStartPositions.size > 0) {\n const nextNodes = store.getData().nodes.map(n => {\n const start = session.nodeStartPositions.get(n.id);\n if (!start) return n;\n return {\n ...n,\n position: { x: start.x + delta.x, y: start.y + delta.y },\n };\n });\n emitNodesChangeRef.current(nextNodes);\n }\n }\n // If `blocked`, drop the gesture without committing — the overlay\n // already snaps back to the start position when we clear the\n // interaction state below.\n store.setInteraction({ kind: 'idle' });\n } else if (session.kind === 'resize') {\n if (\n interaction.kind === 'resize-group' &&\n !interaction.blocked &&\n session.resizeStartBounds &&\n session.handle\n ) {\n const next = applyGroupResize(\n session.resizeStartBounds,\n session.handle,\n interaction.delta\n );\n const nextGroups = store\n .getData()\n .groups.map(g =>\n g.id === session.clickedGroupId ? { ...g, bounds: next } : g\n );\n emitGroupsChangeRef.current(nextGroups);\n }\n store.setInteraction({ kind: 'idle' });\n } else {\n // Plain click on group body → selection\n const current = session.selectionAtStart;\n emitSelectionChangeRef.current({\n nodes: session.additive ? current.nodes : [],\n edges: session.additive ? current.edges : [],\n groups: toggleSelected(current.groups, group.id, session.additive),\n });\n }\n\n groupSessionRef.current = null;\n },\n [\n store,\n emitGroupsChangeRef,\n emitNodesChangeRef,\n emitSelectionChangeRef,\n gesture,\n flushPending,\n ]\n );\n\n return {\n onGroupBodyPointerDown,\n onGroupHandlePointerDown,\n onGroupBodyPointerUp,\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAkCA;AAiEA;;;;;;;;;;;;AAYG;AACG;;AAeJ;AACA;AACA;AACA;AACA;AAEA;AAEA;;;;;AAKG;;;;AAKG;AACE;AACA;;;;AAIF;AACE;;;AAEA;;AACA;AAAwC;;;AAG5C;AACF;;;;AAQE;AACE;;AACA;AAA8C;;AAEhD;AACF;AAIF;;;;;;AAOA;AACA;AAEA;AACE;AACA;;AACA;AACA;AACF;AAEA;AACE;AACE;AACA;;;;AAKJ;AACE;AACA;AACF;;AAGE;AACE;AACA;AACF;AACF;AAEA;AAEI;AACA;;AACA;AACE;AACA;AACF;AACF;;;;AAOF;AAEI;AACA;;AACA;;;AAGA;AACA;AACE;AACA;;;AAIF;AACE;;;AAEE;;AAEF;;AAOA;AACE;AACA;;;AAGA;;AAED;;;;;;AAKD;;AASA;AACE;;;;AAIA;;AAED;;AAEL;;;;;;;AAQC;AAGH;AACE;AACA;AACA;;AAEF;;AAOI;;;;;AAIA;AACA;AACA;AAEA;;AAEE;;;AAEA;;;;;AAKF;;;AAGI;;;;;;AAOJ;AACA;AACA;;AAEE;;AAEE;AACE;AACA;;;;;;AAON;;AAEA;AACA;AACE;AACA;AACD;;AAGC;;;AAGA;;;AAGA;AACA;;;AAGA;;AAEA;;AAEJ;;;;;;;;;AAUC;;AASC;;;;;;AAKA;;AAEA;AACA;AACE;AACA;AACD;;AAGC;;;;;;AAMA;;;;AAIA;AACA;AACA;;;;;AAKA;;;AAGA;;AAEA;AACD;AACH;;;;;;;;AASC;;AAQC;AACA;;;AAEA;;;AAIA;AAEA;;;AAII;;;;AAIA;AACE;AACA;AAAY;;AAEV;AACA;AACE;AACA;AACA;AACD;;AAEL;AACA;;AAEE;AACE;AACA;AAAY;;AAEV;;;AAGJ;AACA;;;;;;;;AAOC;AACL;;AAGE;;AAGA;;AAMG;AACA;AAGH;;;;;;AAKF;;AAEE;AACA;AACA;AACD;;AAGH;AACF;;;;;;;AAQC;;;;;;AAQL;;"}
|
|
@@ -4,7 +4,7 @@ import '../../../utils/devWarn.js';
|
|
|
4
4
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
5
5
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
6
6
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
7
|
-
import '
|
|
7
|
+
import '@vanilla-extract/css';
|
|
8
8
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
9
9
|
import 'react/jsx-runtime';
|
|
10
10
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeGraphKeyboard.js","sources":["
|
|
1
|
+
{"version":3,"file":"useNodeGraphKeyboard.js","sources":["src/components/editor/NodeGraph/useNodeGraphKeyboard.ts"],"sourcesContent":["'use client';\n\nimport { useCallback } from 'react';\n\nimport { useLatest } from '@/hooks';\n\nimport type { NodeGraphNode, NodeGraphSelection } from './NodeGraph.types';\nimport type { NodeGraphStore } from './NodeGraphStore';\nimport type React from 'react';\n\ninterface UseNodeGraphKeyboardOptions {\n store: NodeGraphStore;\n emitNodesChange: (next: NodeGraphNode[]) => void;\n emitSelectionChange: (next: NodeGraphSelection) => void;\n onDelete?: (selection: NodeGraphSelection) => void;\n onActivate?: (node: NodeGraphNode) => void;\n snapToGrid: number | false;\n /** When true, all keyboard handling is skipped. */\n disabled?: boolean;\n}\n\ninterface UseNodeGraphKeyboardReturn {\n onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => void;\n}\n\nconst NUDGE_STEP_DEFAULT = 1;\nconst NUDGE_STEP_SHIFT = 10;\n\n/**\n * Keyboard interaction model for `<NodeGraph>`:\n *\n * | Keys | Action |\n * | ------------------- | -------------------------------------------- |\n * | Arrow keys | Nudge selected nodes by 1 grid step (or 1 unit) |\n * | Shift + Arrow keys | Nudge by 10× the base step |\n * | Delete / Backspace | Emit `onDelete(selection)` (non-empty) |\n * | Enter | Emit `onActivate(node)` when exactly one node selected |\n * | Cmd/Ctrl + A | Select all nodes |\n * | Escape | Clear selection (or cancel active gesture) |\n */\nexport function useNodeGraphKeyboard(\n options: UseNodeGraphKeyboardOptions\n): UseNodeGraphKeyboardReturn {\n const {\n store,\n emitNodesChange,\n emitSelectionChange,\n onDelete,\n onActivate,\n snapToGrid,\n disabled,\n } = options;\n\n const emitNodesChangeRef = useLatest(emitNodesChange);\n const emitSelectionChangeRef = useLatest(emitSelectionChange);\n const onDeleteRef = useLatest(onDelete);\n const onActivateRef = useLatest(onActivate);\n const snapToGridRef = useLatest(snapToGrid);\n const disabledRef = useLatest(disabled);\n\n const nudgeSelected = useCallback(\n (dx: number, dy: number): boolean => {\n const data = store.getData();\n const selection = store.getSelection();\n if (selection.nodes.length === 0) return false;\n const selectedIds = new Set(selection.nodes);\n const next = data.nodes.map(node => {\n if (!selectedIds.has(node.id)) return node;\n return {\n ...node,\n position: { x: node.position.x + dx, y: node.position.y + dy },\n };\n });\n emitNodesChangeRef.current(next);\n return true;\n },\n [store, emitNodesChangeRef]\n );\n\n const onKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (disabledRef.current) return;\n // Don't steal input focus — if the event originated in an editable\n // element inside a node body, leave it alone.\n const target = event.target as HTMLElement | null;\n if (\n target &&\n (target.isContentEditable ||\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'SELECT')\n ) {\n return;\n }\n\n const grid = snapToGridRef.current;\n const baseStep = grid === false || grid <= 0 ? NUDGE_STEP_DEFAULT : grid;\n const step = event.shiftKey ? baseStep * NUDGE_STEP_SHIFT : baseStep;\n\n // Dispatch on `event.code` so character keys are matched by physical\n // location (e.g. `KeyA` for Ctrl+A), not by the printed character\n // — which would otherwise differ on non-QWERTY / non-Latin layouts.\n // For special keys (`ArrowUp`, `Delete`, `Backspace`, `Enter`,\n // `Escape`) `event.code` equals `event.key`, so existing cases keep\n // working unchanged.\n switch (event.code) {\n case 'ArrowUp':\n if (nudgeSelected(0, -step)) event.preventDefault();\n return;\n case 'ArrowDown':\n if (nudgeSelected(0, step)) event.preventDefault();\n return;\n case 'ArrowLeft':\n if (nudgeSelected(-step, 0)) event.preventDefault();\n return;\n case 'ArrowRight':\n if (nudgeSelected(step, 0)) event.preventDefault();\n return;\n case 'Delete':\n case 'Backspace': {\n const selection = store.getSelection();\n if (\n selection.nodes.length === 0 &&\n selection.edges.length === 0 &&\n selection.groups.length === 0\n ) {\n return;\n }\n onDeleteRef.current?.(selection);\n event.preventDefault();\n return;\n }\n case 'Enter': {\n const selection = store.getSelection();\n if (selection.nodes.length !== 1) return;\n const id = selection.nodes[0];\n const node = id != null ? store.getNodeById(id) : undefined;\n if (node) {\n onActivateRef.current?.(node);\n event.preventDefault();\n }\n return;\n }\n // `event.code` is layout-independent — matches the physical \"A\"\n // key regardless of the user's keyboard layout (Polish, Cyrillic,\n // Dvorak, etc., would otherwise fire a different `event.key`).\n case 'KeyA': {\n if (!(event.metaKey || event.ctrlKey)) return;\n const data = store.getData();\n emitSelectionChangeRef.current({\n nodes: data.nodes.map(n => n.id),\n edges: [],\n groups: [],\n });\n event.preventDefault();\n return;\n }\n case 'Escape': {\n // Cancel an in-flight connection first; otherwise clear selection.\n const interaction = store.getInteraction();\n if (interaction.kind !== 'idle') {\n store.setInteraction({ kind: 'idle' });\n event.preventDefault();\n return;\n }\n const selection = store.getSelection();\n if (\n selection.nodes.length === 0 &&\n selection.edges.length === 0 &&\n selection.groups.length === 0\n ) {\n return;\n }\n emitSelectionChangeRef.current({ nodes: [], edges: [], groups: [] });\n event.preventDefault();\n return;\n }\n default:\n return;\n }\n },\n [\n store,\n nudgeSelected,\n onDeleteRef,\n onActivateRef,\n emitSelectionChangeRef,\n snapToGridRef,\n disabledRef,\n ]\n );\n\n return { onKeyDown };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAyBA;AACA;AAEA;;;;;;;;;;;AAWG;AACG;AAGJ;AAUA;AACA;AACA;AACA;AACA;AACA;;AAII;AACA;AACA;AAAkC;;;;AAGD;;AAE7B;;;AAGJ;AACA;AACA;AACF;AAIF;;;;;AAKI;AACA;;;;AAKI;;;AAKJ;AACA;AACA;;;;;;;AAQA;AACE;AACE;;;AAEF;AACE;;;AAEF;AACE;;;AAEF;AACE;;;AAEF;;AAEE;AACA;AAEE;AACA;;;AAIF;;;;;AAKA;AACA;;;AAEA;;AAEE;;;;;;;;;;;AAUF;;AAEE;AACA;AACA;AACD;;;;;;AAMD;AACA;;;;;AAKA;AACA;AAEE;AACA;;;AAIF;;;;AAIF;;;AAGJ;;;;;;;;AASC;;AAIL;;"}
|
|
@@ -9,7 +9,7 @@ import '../../../utils/devWarn.js';
|
|
|
9
9
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
10
10
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
11
11
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
12
|
-
import '
|
|
12
|
+
import '@vanilla-extract/css';
|
|
13
13
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
14
14
|
import 'react/jsx-runtime';
|
|
15
15
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeGraphNodeDrag.js","sources":["../../../../../../src/components/editor/NodeGraph/useNodeGraphNodeDrag.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAgBA;AA2CA;;;;;;;;;AASG;AACG;AAGJ;AAUA;AACA;AACA;AACA;AAEA;AACA;;;;;;;;;;AAWA;AACA;AAEA;AACE;AACA;;AACA;;AAEE;;;;AAID;AACH;AAEA;AACE;AACE;AACA;;;;AAKJ;AACE;AACA;AACF;;;;AAKE;AACE;AACA;AACF;AACF;;AAII;AAAwB;;;;;;;;;AAQxB;AACA;AACA;;;AAIA;;AAEE;;;;;;AAKA;;;;;AAKF;;;AAGI;;;AAIJ;;AAEA;AAEA;AACE;AACA;;AACA;;;AAGA;;;;AAGE;;;AAGE;;;AAGF;;AAEF;AACA;AACE;AACA;;;AAGF;;;;;;;AASE;;AAEF;;AACA;AACE;AACA;AACF;AACF;AAEA;AACE;;AAEE;AACA;AACA;;;AAGH;;;;;;AAOC;AACA;;AAEA;;AAEJ;;;;;;;;;AAUC;;AAKC;AACA;;;AAEA;;;;AAKA;AAEA;;AAEE;AACA;AACE;AACA;AACE;AACA;AAAY;;AAEV;;;AAGJ;AACA;;;;;;AAKF;AACE;;AAEE;AACA;AACA;AACD;;;AAIL;AACF;AAIF;AACF;;"}
|
|
1
|
+
{"version":3,"file":"useNodeGraphNodeDrag.js","sources":["src/components/editor/NodeGraph/useNodeGraphNodeDrag.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { screenToWorld as worldFromScreen } from '@/components/primitives/viewport';\nimport { useLatest } from '@/hooks';\n\nimport { snapDelta, toggleSelected } from './nodeGraphMath';\nimport { useDragGesture } from './useDragGesture';\n\nimport type { NodeGraphNode, NodeGraphSelection } from './NodeGraph.types';\nimport type { NodeGraphStore } from './NodeGraphStore';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type { ViewportTransform } from '@/components/primitives/viewport';\nimport type React from 'react';\n\nconst DRAG_START_THRESHOLD_PX = 3;\n\n/** Pending drag state buffered between pointermove and the next rAF flush. */\ninterface PendingDragMove {\n ids: ReadonlySet<string>;\n startWorld: Point2D;\n delta: Point2D;\n}\n\ninterface UseNodeGraphNodeDragOptions {\n store: NodeGraphStore;\n getTransform: () => ViewportTransform;\n localScreenPoint: (clientX: number, clientY: number) => Point2D;\n snapToGrid: number | false;\n disabled?: boolean;\n emitNodesChange: (next: NodeGraphNode[]) => void;\n emitSelectionChange: (next: NodeGraphSelection) => void;\n}\n\ninterface UseNodeGraphNodeDragReturn {\n onNodeBodyPointerDown: (\n event: React.PointerEvent<HTMLDivElement>,\n node: NodeGraphNode\n ) => void;\n onNodeBodyPointerUp: (\n event: React.PointerEvent<HTMLDivElement>,\n node: NodeGraphNode\n ) => void;\n}\n\ninterface DragSession {\n pointerId: number;\n clickedNodeId: string;\n startScreen: Point2D;\n startWorld: Point2D;\n /** Snapshot of selection at gesture start (for shift-toggle reset). */\n selectionAtStart: NodeGraphSelection;\n /** Snapshot of node positions at gesture start. */\n nodeStartPositions: Map<string, Point2D>;\n additive: boolean;\n didDrag: boolean;\n}\n\n/**\n * Pointer-driven drag + click-select controller for node bodies. Owns the\n * gesture lifecycle (`pointerdown` → document `pointermove` → `pointerup`\n * or `pointercancel`), commits position updates through the\n * controlled-state emitter on success, and falls back to plain click\n * selection when the pointer moves less than the drag threshold.\n *\n * Document listeners are attached only while a gesture is in flight, so\n * pointermove cost is zero between drags.\n */\nexport function useNodeGraphNodeDrag(\n options: UseNodeGraphNodeDragOptions\n): UseNodeGraphNodeDragReturn {\n const {\n store,\n getTransform,\n localScreenPoint,\n snapToGrid,\n disabled,\n emitNodesChange,\n emitSelectionChange,\n } = options;\n\n const snapToGridRef = useLatest(snapToGrid);\n const disabledRef = useLatest(disabled);\n const emitNodesChangeRef = useLatest(emitNodesChange);\n const emitSelectionChangeRef = useLatest(emitSelectionChange);\n\n const dragRef = useRef<DragSession | null>(null);\n const gesture = useDragGesture();\n\n // ── rAF-throttled interaction commits ──\n //\n // Native pointermove fires at the display's refresh rate (up to several\n // hundred Hz on high-refresh monitors) — without throttling, every event\n // triggers a full notification cycle through every NodeGraphStore\n // subscriber (one per node + one per edge label). Buffering the latest\n // delta in a ref and flushing once per frame caps the commit rate at\n // requestAnimationFrame, which already matches the refresh rate the\n // canvas layers are drawing at.\n const pendingMoveRef = useRef<PendingDragMove | null>(null);\n const rafRef = useRef<number>(0);\n\n const commitPending = useCallback((): void => {\n const pending = pendingMoveRef.current;\n if (!pending) return;\n pendingMoveRef.current = null;\n store.setInteraction({\n kind: 'drag-nodes',\n nodeIds: pending.ids,\n startWorld: pending.startWorld,\n delta: pending.delta,\n });\n }, [store]);\n\n const cancelRaf = useCallback((): void => {\n if (rafRef.current !== 0) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = 0;\n }\n }, []);\n\n /** Synchronous flush — cancels any pending rAF and commits immediately. */\n const flushPending = useCallback((): void => {\n cancelRaf();\n commitPending();\n }, [cancelRaf, commitPending]);\n\n // Cancel any in-flight rAF on unmount so a teardown mid-drag doesn't fire\n // a commit into a torn-down store.\n useEffect(() => {\n return () => {\n cancelRaf();\n pendingMoveRef.current = null;\n };\n }, [cancelRaf]);\n\n const onNodeBodyPointerDown = useCallback(\n (event: React.PointerEvent<HTMLDivElement>, node: NodeGraphNode): void => {\n if (event.button !== 0) return; // only primary button\n // Always stop propagation for clicks on a node body so the Viewport\n // beneath us doesn't fire a marquee. This applies even when disabled\n // or non-interactive — the click is consumed by the node hit target.\n event.stopPropagation();\n if (disabledRef.current) return;\n if (node.selectable === false && node.draggable === false) return;\n\n const additive = event.shiftKey || event.metaKey || event.ctrlKey;\n const currentSelection = store.getSelection();\n const alreadySelected = currentSelection.nodes.includes(node.id);\n\n // Decide which node ids should drag together. If clicked node is in\n // the selection, drag all selected nodes; otherwise just this one.\n let dragIds: string[];\n if (alreadySelected) {\n dragIds = currentSelection.nodes;\n } else if (!additive) {\n // Pre-emptively select just this node so the drag matches what the\n // user sees as \"selected\" mid-gesture. The actual selection emit\n // happens in pointerup if no drag occurred.\n dragIds = [node.id];\n } else {\n dragIds = [...currentSelection.nodes, node.id];\n }\n\n const positions = new Map<string, Point2D>();\n for (const n of store.getData().nodes) {\n if (dragIds.includes(n.id)) {\n positions.set(n.id, { ...n.position });\n }\n }\n\n const startScreen = localScreenPoint(event.clientX, event.clientY);\n const startWorld = worldFromScreen(startScreen, getTransform());\n const pointerId = event.pointerId;\n\n const handleMove = (e: PointerEvent): void => {\n const session = dragRef.current;\n if (session?.pointerId !== pointerId) return;\n const current = localScreenPoint(e.clientX, e.clientY);\n const dx = current.x - session.startScreen.x;\n const dy = current.y - session.startScreen.y;\n if (!session.didDrag) {\n if (Math.hypot(dx, dy) < DRAG_START_THRESHOLD_PX) return;\n const clicked = store.getNodeById(session.clickedNodeId);\n if (clicked?.draggable === false) {\n // Not draggable — promote to a no-op drag flag so pointerup falls\n // through to click selection logic.\n session.didDrag = false;\n return;\n }\n session.didDrag = true;\n }\n const transform = getTransform();\n const worldDelta = {\n x: dx / transform.zoom,\n y: dy / transform.zoom,\n };\n const snapped = snapDelta(worldDelta, snapToGridRef.current);\n const ids: ReadonlySet<string> = new Set(\n session.nodeStartPositions.keys()\n );\n // Buffer the latest delta; the rAF callback below picks the most\n // recent value when the frame fires, so any intermediate moves\n // between frames are coalesced into one commit.\n pendingMoveRef.current = {\n ids,\n startWorld: session.startWorld,\n delta: snapped,\n };\n if (rafRef.current !== 0) return;\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = 0;\n commitPending();\n });\n };\n\n gesture.begin(event, {\n onMove: handleMove,\n onCancel: () => {\n cancelRaf();\n pendingMoveRef.current = null;\n dragRef.current = null;\n store.setInteraction({ kind: 'idle' });\n },\n });\n\n dragRef.current = {\n pointerId,\n clickedNodeId: node.id,\n startScreen,\n startWorld,\n selectionAtStart: currentSelection,\n nodeStartPositions: positions,\n additive,\n didDrag: false,\n };\n },\n [\n store,\n getTransform,\n localScreenPoint,\n snapToGridRef,\n disabledRef,\n gesture,\n cancelRaf,\n commitPending,\n ]\n );\n\n const onNodeBodyPointerUp = useCallback(\n (event: React.PointerEvent<HTMLDivElement>, node: NodeGraphNode): void => {\n const session = dragRef.current;\n if (session?.pointerId !== event.pointerId) return;\n event.stopPropagation();\n gesture.finish(event);\n\n // Drain any deferred pointermove update before reading from the store —\n // otherwise the commit would use the previous frame's delta and drop\n // the final sub-frame movement before pointerup.\n flushPending();\n\n if (session.didDrag) {\n // Commit positions from store's interaction delta.\n const interaction = store.getInteraction();\n if (interaction.kind === 'drag-nodes') {\n const delta = interaction.delta;\n const nextNodes = store.getData().nodes.map(n => {\n const start = session.nodeStartPositions.get(n.id);\n if (!start) return n;\n return {\n ...n,\n position: { x: start.x + delta.x, y: start.y + delta.y },\n };\n });\n emitNodesChangeRef.current(nextNodes);\n }\n store.setInteraction({ kind: 'idle' });\n } else {\n // Plain click — handle selection semantics.\n if (node.selectable !== false) {\n const current = session.selectionAtStart;\n emitSelectionChangeRef.current({\n nodes: toggleSelected(current.nodes, node.id, session.additive),\n edges: session.additive ? current.edges : [],\n groups: session.additive ? current.groups : [],\n });\n }\n }\n\n dragRef.current = null;\n },\n [store, emitNodesChangeRef, emitSelectionChangeRef, gesture, flushPending]\n );\n\n return { onNodeBodyPointerDown, onNodeBodyPointerUp };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAgBA;AA2CA;;;;;;;;;AASG;AACG;AAGJ;AAUA;AACA;AACA;AACA;AAEA;AACA;;;;;;;;;;AAWA;AACA;AAEA;AACE;AACA;;AACA;;AAEE;;;;AAID;AACH;AAEA;AACE;AACE;AACA;;;;AAKJ;AACE;AACA;AACF;;;;AAKE;AACE;AACA;AACF;AACF;;AAII;AAAwB;;;;;;;;;AAQxB;AACA;AACA;;;AAIA;;AAEE;;;;;;AAKA;;;;;AAKF;;;AAGI;;;AAIJ;;AAEA;AAEA;AACE;AACA;;AACA;;;AAGA;;;;AAGE;;;AAGE;;;AAGF;;AAEF;AACA;AACE;AACA;;;AAGF;;;;;;;AASE;;AAEF;;AACA;AACE;AACA;AACF;AACF;AAEA;AACE;;AAEE;AACA;AACA;;;AAGH;;;;;;AAOC;AACA;;AAEA;;AAEJ;;;;;;;;;AAUC;;AAKC;AACA;;;AAEA;;;;AAKA;AAEA;;AAEE;AACA;AACE;AACA;AACE;AACA;AAAY;;AAEV;;;AAGJ;AACA;;;;;;AAKF;AACE;;AAEE;AACA;AACA;AACD;;;AAIL;AACF;AAIF;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStoreSlice.js","sources":["
|
|
1
|
+
{"version":3,"file":"useStoreSlice.js","sources":["src/components/editor/NodeGraph/useStoreSlice.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\n\ninterface SliceCache<TSource, TSelected> {\n source: TSource;\n selected: TSelected;\n}\n\n/**\n * Subscribe to a slice of an external store, returning a memoized selection.\n *\n * Avoids the re-render storm caused by calling `useSyncExternalStore` with a\n * raw slice getter when the slice mutates at high frequency (e.g. drag\n * deltas at 60–120 Hz) but each subscriber only cares about a per-id payload.\n *\n * The selector is invoked only when the underlying source reference changes;\n * if the freshly computed selection compares equal to the previous one via\n * `isEqual`, the previous selection reference is preserved so downstream\n * `Object.is` checks (including React's reconciler) treat it as unchanged.\n *\n * Inspired by `use-sync-external-store/with-selector`, kept local to avoid\n * pulling in an extra peer dependency for a single call site.\n */\nexport function useStoreSlice<TSource, TSelected>(\n subscribe: (cb: () => void) => () => void,\n getSnapshot: () => TSource,\n selector: (snapshot: TSource) => TSelected,\n isEqual: (a: TSelected, b: TSelected) => boolean = Object.is\n): TSelected {\n const cacheRef = useRef<SliceCache<TSource, TSelected> | null>(null);\n const selectorRef = useRef(selector);\n const isEqualRef = useRef(isEqual);\n // Keep these refs pointed at the latest selector + equality fn so the\n // snapshot getter below always uses current values without forcing a\n // re-subscribe. This mirrors `use-sync-external-store/with-selector`, which\n // deliberately writes these refs during render rather than in an effect.\n // eslint-disable-next-line react-hooks/refs -- intentional with-selector latest refs\n selectorRef.current = selector;\n // eslint-disable-next-line react-hooks/refs -- intentional with-selector latest refs\n isEqualRef.current = isEqual;\n\n const getSelectedSnapshot = useCallback((): TSelected => {\n const next = getSnapshot();\n const cache = cacheRef.current;\n if (cache && Object.is(cache.source, next)) {\n return cache.selected;\n }\n const selected = selectorRef.current(next);\n if (cache && isEqualRef.current(cache.selected, selected)) {\n cacheRef.current = { source: next, selected: cache.selected };\n return cache.selected;\n }\n cacheRef.current = { source: next, selected };\n return selected;\n }, [getSnapshot]);\n\n return useSyncExternalStore(subscribe, getSelectedSnapshot);\n}\n"],"names":[],"mappings":";;;AASA;;;;;;;;;;;;;;AAcG;AACG;AAMJ;AACA;AACA;;;;;;AAMA;;AAEA;AAEA;AACE;AACA;AACA;;;;AAIA;AACE;;;;AAIF;AACF;AAEA;AACF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyGroup.js","sources":["
|
|
1
|
+
{"version":3,"file":"PropertyGroup.js","sources":["src/components/editor/PropertyInspector/PropertyGroup.tsx"],"sourcesContent":["'use client';\n\nimport { assignInlineVars } from '@vanilla-extract/dynamic';\nimport React from 'react';\n\nimport { vars } from '@/theme/contract.css';\nimport { cx } from '@/utils/cx';\n\nimport {\n groupRoot,\n groupDivider,\n groupTitle,\n groupLine,\n indentVar,\n} from './PropertyGroup.css';\n\nimport type { PropertyGroupProps } from './PropertyInspector.types';\n\n// --- Component ---\n\nexport const PropertyGroup: React.FC<PropertyGroupProps> = ({\n title,\n children,\n indent = 0,\n disabled = false,\n\n className,\n style,\n testId,\n ref,\n ...rest\n}) => {\n return (\n <div\n ref={ref}\n className={cx(groupRoot, className)}\n style={{\n ...style,\n ...assignInlineVars({\n [indentVar]: `calc(${indent} * ${vars.spacing.xl})`,\n }),\n opacity: disabled ? 0.5 : 1,\n pointerEvents: disabled ? 'none' : 'auto',\n }}\n data-testid={testId}\n {...rest}\n >\n {title != null && (\n <div className={groupDivider}>\n <span className={groupLine} />\n <span className={groupTitle}>{title}</span>\n <span className={groupLine} />\n </div>\n )}\n {children}\n </div>\n );\n};\n\nPropertyGroup.displayName = 'PropertyGroup';\n"],"names":[],"mappings":";;;;;;;AAkBA;AAEO;AAYL;AAKM;AACA;;;;;AAKD;AAcP;AAEA;;"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import './../../../assets/src/components/editor/PropertyInspector/PropertyPanel.css.ts.vanilla-
|
|
1
|
+
import './../../../assets/src/components/editor/PropertyInspector/PropertyPanel.css.ts.vanilla-Dpr_k5I3.css';
|
|
2
2
|
|
|
3
3
|
var contentBottomSpacingVar = 'var(--contentBottomSpacingVar__151bru71)';
|
|
4
4
|
var contentTopSpacingVar = 'var(--contentTopSpacingVar__151bru70)';
|
|
5
5
|
var panelContent = 'PropertyPanel_panelContent__151bru76';
|
|
6
|
-
var
|
|
6
|
+
var panelContentScroll = 'PropertyPanel_panelContentScroll__151bru77';
|
|
7
|
+
var panelFooter = 'PropertyPanel_panelFooter__151bru78';
|
|
7
8
|
var panelHeader = 'PropertyPanel_panelHeader__151bru73';
|
|
8
9
|
var panelRoot = 'PropertyPanel_panelRoot__151bru72';
|
|
9
10
|
var searchInputBase = 'PropertyPanel_searchInputBase__151bru75';
|
|
10
11
|
var searchWrapper = 'PropertyPanel_searchWrapper__151bru74';
|
|
11
12
|
|
|
12
|
-
export { contentBottomSpacingVar, contentTopSpacingVar, panelContent, panelFooter, panelHeader, panelRoot, searchInputBase, searchWrapper };
|
|
13
|
+
export { contentBottomSpacingVar, contentTopSpacingVar, panelContent, panelContentScroll, panelFooter, panelHeader, panelRoot, searchInputBase, searchWrapper };
|
|
13
14
|
//# sourceMappingURL=PropertyPanel.css.js.map
|