entangle-ui 0.10.0 → 0.11.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 +72 -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/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/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.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.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.map +1 -1
- 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.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.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 +1 -1
- 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.js.map +1 -1
- package/dist/esm/components/shell/FloatingPanel/FloatingPanel.js.map +1 -1
- 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.js +3 -0
- package/dist/esm/styles.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/editor/PropertyInspector/PropertyInspector.types.d.ts +49 -3
- package/dist/types/components/primitives/Button/Button.d.ts +1 -1
- package/dist/types/components/primitives/IconButton/IconButton.d.ts +1 -1
- 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":"ChatMarkdownRenderer.js","sources":["../../../../../../src/components/editor/ChatPanel/ChatMarkdownRenderer.tsx"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;AAwCA;AACE;AACF;AAEA;;;;;;AAWE;AAIE;AACE;AACA;AACD;AACD;AACE;AACA;AAQD;AACD;AACE;;AAcD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;;AAGH;;;;AAMI;;AACA;AACE;;AAEE;;;;;;;;;AAWN;AACE;;AAEF;AACA;;AAGF;AACF;AAoBA;AACE;;;AAIA;;;AAIE;AACE;;;;;;AAOA;;AAEA;AACA;;AAEE;;;;AAIA;AACA;;AAED;;;;AAKH;;AAEE;;;;;;;;;AAUE;;AAEA;AACD;AACD;;;;AAKF;;AAEE;AACE;AACA;;AAEF;;;;AAKF;;AAEE;AACE;AACA;;;;;;AAOJ;;AAEE;AACE;AACA;;;;;;AAOJ;AAEE;AACA;AACA;AAEA;AAEK;AACA;;;AAIL;AACA;;;;;AAIqB;AACnB;AAAW;AACX;AAAU;AACV;AACF;AAEA;;AAEA;AACE;AACA;;AAEF;;;;;AAMF;;AAEE;AAEE;AACA;AACA;AACA;AACA;AACA;;;AAIF;AACA;;AAEF;;AAGF;AACF;AAEA;;;;;;;;;;;;;;;;;AAiBG;;AAED;;AAcI;;AAMA;AASM;AACA;AACE;;;;AAcE;;;AAOF;;AAUA;;AAUA;;AAMA;;AAQA;AACE;;AAEA;AACA;AACA;;AAWgB;;;;AAsClB;AACE;;;AAKZ;AAGJ;;"}
|
|
1
|
+
{"version":3,"file":"ChatMarkdownRenderer.js","sources":["src/components/editor/ChatPanel/ChatMarkdownRenderer.tsx"],"sourcesContent":["'use client';\n\nimport React, { useMemo } from 'react';\n\nimport { Code } from '@/components/primitives/Code';\nimport { cx } from '@/utils/cx';\n\nimport { ChatCodeBlock } from './ChatCodeBlock';\nimport {\n markdownBlockquoteStyle,\n markdownHeadingStyle,\n markdownHrStyle,\n markdownLinkStyle,\n markdownListItemStyle,\n markdownListStyle,\n markdownParagraphStyle,\n markdownRootStyle,\n markdownTableStyle,\n markdownTdStyle,\n markdownThStyle,\n} from './ChatPanel.css';\n\nimport type { ChatMarkdownRendererProps } from './ChatMarkdownRenderer.types';\n\n// ─────────────────────────────────────────────────────────────────\n// Minimal markdown → React renderer.\n//\n// Covers what chat LLMs typically produce: paragraphs, headings,\n// lists, blockquotes, horizontal rules, inline emphasis / code, links,\n// fenced code blocks, and (with `gfm`) pipe tables.\n//\n// Intentionally lightweight — for advanced CommonMark edge cases or\n// full AST control, consumers can supply their own `renderContent`\n// function on `ChatMessage`.\n// ─────────────────────────────────────────────────────────────────\n\ninterface InlineRenderOptions {\n linkTarget: '_self' | '_blank';\n}\n\nfunction escapeHtmlInText(text: string): string {\n return text;\n}\n\nfunction renderInline(\n text: string,\n options: InlineRenderOptions,\n keyPrefix: string\n): React.ReactNode[] {\n const parts: React.ReactNode[] = [];\n let rest = text;\n let index = 0;\n\n // Ordered by precedence. Each pattern captures the full match so we\n // can slice around it, and the content(s) we want to render.\n const patterns: Array<{\n regex: RegExp;\n render: (match: RegExpExecArray, key: string) => React.ReactNode;\n }> = [\n {\n regex: /`([^`]+)`/,\n render: (m, key) => <Code key={key}>{m[1]}</Code>,\n },\n {\n regex: /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/,\n render: (m, key) => (\n <img\n key={key}\n src={m[2]}\n alt={m[1] ?? ''}\n style={{ maxWidth: '100%' }}\n />\n ),\n },\n {\n regex: /\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/,\n render: (m, key) => (\n <a\n key={key}\n href={m[2]}\n target={options.linkTarget}\n rel={\n options.linkTarget === '_blank' ? 'noopener noreferrer' : undefined\n }\n className={markdownLinkStyle}\n >\n {m[1]}\n </a>\n ),\n },\n {\n regex: /\\*\\*([^*]+)\\*\\*/,\n render: (m, key) => <strong key={key}>{m[1]}</strong>,\n },\n {\n regex: /__([^_]+)__/,\n render: (m, key) => <strong key={key}>{m[1]}</strong>,\n },\n {\n regex: /(?<![*\\w])\\*([^*\\n]+)\\*(?![*\\w])/,\n render: (m, key) => <em key={key}>{m[1]}</em>,\n },\n {\n regex: /(?<![_\\w])_([^_\\n]+)_(?![_\\w])/,\n render: (m, key) => <em key={key}>{m[1]}</em>,\n },\n {\n regex: /~~([^~]+)~~/,\n render: (m, key) => <del key={key}>{m[1]}</del>,\n },\n ];\n\n while (rest.length > 0) {\n let best: { start: number; length: number; node: React.ReactNode } | null =\n null;\n\n for (const { regex, render } of patterns) {\n const match = regex.exec(rest);\n if (!match) continue;\n if (best === null || match.index < best.start) {\n best = {\n start: match.index,\n length: match[0].length,\n node: render(match, `${keyPrefix}-i-${index++}`),\n };\n }\n }\n\n if (!best) {\n parts.push(escapeHtmlInText(rest));\n break;\n }\n\n if (best.start > 0) {\n parts.push(escapeHtmlInText(rest.slice(0, best.start)));\n }\n parts.push(best.node);\n rest = rest.slice(best.start + best.length);\n }\n\n return parts;\n}\n\ninterface Block {\n type:\n | 'paragraph'\n | 'heading'\n | 'list'\n | 'orderedList'\n | 'blockquote'\n | 'codeBlock'\n | 'hr'\n | 'table';\n content?: string;\n level?: number;\n items?: string[];\n language?: string;\n rows?: string[][];\n align?: Array<'left' | 'right' | 'center' | null>;\n}\n\nfunction parseBlocks(source: string, gfm: boolean): Block[] {\n const lines = source.replace(/\\r\\n/g, '\\n').split('\\n');\n const blocks: Block[] = [];\n\n let i = 0;\n while (i < lines.length) {\n const line = lines[i] ?? '';\n\n // Skip blank lines between blocks.\n if (/^\\s*$/.test(line)) {\n i++;\n continue;\n }\n\n // Fenced code block\n const fenceMatch = /^```(\\w+)?\\s*$/.exec(line);\n if (fenceMatch) {\n const language = fenceMatch[1];\n const codeLines: string[] = [];\n i++;\n while (i < lines.length && !/^```\\s*$/.test(lines[i] ?? '')) {\n codeLines.push(lines[i] ?? '');\n i++;\n }\n i++; // skip closing fence\n blocks.push({\n type: 'codeBlock',\n content: codeLines.join('\\n'),\n language,\n });\n continue;\n }\n\n // Horizontal rule\n if (/^\\s*(---|\\*\\*\\*|___)\\s*$/.test(line)) {\n blocks.push({ type: 'hr' });\n i++;\n continue;\n }\n\n // Heading (# through ######)\n const headingMatch = /^(#{1,6})\\s+(.*)$/.exec(line);\n if (headingMatch) {\n const hashes = headingMatch[1] ?? '';\n const headingContent = headingMatch[2] ?? '';\n blocks.push({\n type: 'heading',\n level: hashes.length,\n content: headingContent.trim(),\n });\n i++;\n continue;\n }\n\n // Blockquote — consecutive `> ` lines\n if (/^\\s*>/.test(line)) {\n const quoteLines: string[] = [];\n while (i < lines.length && /^\\s*>/.test(lines[i] ?? '')) {\n quoteLines.push((lines[i] ?? '').replace(/^\\s*>\\s?/, ''));\n i++;\n }\n blocks.push({ type: 'blockquote', content: quoteLines.join('\\n') });\n continue;\n }\n\n // Unordered list — lines beginning with `- `, `* `, or `+ `\n if (/^\\s*[-*+]\\s+/.test(line)) {\n const items: string[] = [];\n while (i < lines.length && /^\\s*[-*+]\\s+/.test(lines[i] ?? '')) {\n items.push((lines[i] ?? '').replace(/^\\s*[-*+]\\s+/, ''));\n i++;\n }\n blocks.push({ type: 'list', items });\n continue;\n }\n\n // Ordered list — `1. ...`\n if (/^\\s*\\d+\\.\\s+/.test(line)) {\n const items: string[] = [];\n while (i < lines.length && /^\\s*\\d+\\.\\s+/.test(lines[i] ?? '')) {\n items.push((lines[i] ?? '').replace(/^\\s*\\d+\\.\\s+/, ''));\n i++;\n }\n blocks.push({ type: 'orderedList', items });\n continue;\n }\n\n // GFM pipe table — a header row, a separator `---|---`, then rows.\n if (\n gfm &&\n /\\|/.test(line) &&\n i + 1 < lines.length &&\n /^\\s*\\|?\\s*:?-+:?\\s*(\\|\\s*:?-+:?\\s*)+\\|?\\s*$/.test(lines[i + 1] ?? '')\n ) {\n const split = (row: string) =>\n row\n .replace(/^\\s*\\|/, '')\n .replace(/\\|\\s*$/, '')\n .split('|')\n .map(cell => cell.trim());\n\n const header = split(line);\n const rawAlign = split(lines[i + 1] ?? '');\n const align = rawAlign.map(cell => {\n const left = cell.startsWith(':');\n const right = cell.endsWith(':');\n if (left && right) return 'center' as const;\n if (right) return 'right' as const;\n if (left) return 'left' as const;\n return null;\n });\n\n const rows: string[][] = [header];\n i += 2;\n while (i < lines.length && /\\|/.test(lines[i] ?? '')) {\n rows.push(split(lines[i] ?? ''));\n i++;\n }\n blocks.push({ type: 'table', rows, align });\n continue;\n }\n\n // Paragraph — consecutive non-blank non-block-starting lines.\n const paraLines: string[] = [];\n while (i < lines.length) {\n const ln = lines[i] ?? '';\n if (\n /^\\s*$/.test(ln) ||\n /^```/.test(ln) ||\n /^(#{1,6})\\s+/.test(ln) ||\n /^\\s*>/.test(ln) ||\n /^\\s*[-*+]\\s+/.test(ln) ||\n /^\\s*\\d+\\.\\s+/.test(ln) ||\n /^\\s*(---|\\*\\*\\*|___)\\s*$/.test(ln)\n ) {\n break;\n }\n paraLines.push(ln);\n i++;\n }\n blocks.push({ type: 'paragraph', content: paraLines.join('\\n') });\n }\n\n return blocks;\n}\n\n/**\n * Lightweight markdown renderer for chat messages.\n *\n * Pass it to `ChatMessage.renderContent` to render assistant responses\n * with bold / italic / inline code, links, fenced code blocks, lists,\n * blockquotes, horizontal rules, and GFM pipe tables.\n *\n * For advanced markdown features, supply a custom `renderContent`\n * function that uses your markdown library of choice.\n *\n * @example\n * ```tsx\n * <ChatMessage\n * message={msg}\n * renderContent={content => <ChatMarkdownRenderer content={content} />}\n * />\n * ```\n */\nexport const ChatMarkdownRenderer =\n /*#__PURE__*/ React.memo<ChatMarkdownRendererProps>(\n ({\n content,\n gfm = true,\n linkTarget = '_blank',\n components,\n className,\n style,\n testId,\n ref,\n ...rest\n }) => {\n const blocks = useMemo(() => parseBlocks(content, gfm), [content, gfm]);\n\n const CodeBlock =\n components?.codeBlock ??\n (({ code, language }: { code: string; language?: string }) => (\n <ChatCodeBlock code={code} language={language} />\n ));\n\n return (\n <div\n ref={ref}\n className={cx(markdownRootStyle, className)}\n style={style}\n data-testid={testId}\n {...rest}\n >\n {blocks.map((block, idx) => {\n const key = `b-${idx}`;\n switch (block.type) {\n case 'paragraph':\n return (\n <p key={key} className={markdownParagraphStyle}>\n {renderInline(block.content ?? '', { linkTarget }, key)}\n </p>\n );\n case 'heading': {\n const level = Math.min(Math.max(block.level ?? 1, 1), 6) as\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6;\n const Tag = `h${level}` as keyof React.JSX.IntrinsicElements;\n return (\n <Tag key={key} className={markdownHeadingStyle}>\n {renderInline(block.content ?? '', { linkTarget }, key)}\n </Tag>\n );\n }\n case 'list':\n return (\n <ul key={key} className={markdownListStyle}>\n {(block.items ?? []).map((item, j) => (\n <li key={`${key}-${j}`} className={markdownListItemStyle}>\n {renderInline(item, { linkTarget }, `${key}-${j}`)}\n </li>\n ))}\n </ul>\n );\n case 'orderedList':\n return (\n <ol key={key} className={markdownListStyle}>\n {(block.items ?? []).map((item, j) => (\n <li key={`${key}-${j}`} className={markdownListItemStyle}>\n {renderInline(item, { linkTarget }, `${key}-${j}`)}\n </li>\n ))}\n </ol>\n );\n case 'blockquote':\n return (\n <blockquote key={key} className={markdownBlockquoteStyle}>\n {renderInline(block.content ?? '', { linkTarget }, key)}\n </blockquote>\n );\n case 'codeBlock':\n return (\n <CodeBlock\n key={key}\n code={block.content ?? ''}\n language={block.language}\n />\n );\n case 'hr':\n return <hr key={key} className={markdownHrStyle} />;\n case 'table': {\n const [header, ...rows] = block.rows ?? [];\n const align = block.align ?? [];\n return (\n <table key={key} className={markdownTableStyle}>\n <thead>\n <tr>\n {(header ?? []).map((cell, j) => (\n <th\n key={`${key}-h-${j}`}\n className={markdownThStyle}\n style={\n align[j]\n ? { textAlign: align[j] ?? undefined }\n : undefined\n }\n >\n {renderInline(\n cell,\n { linkTarget },\n `${key}-h-${j}`\n )}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rIdx) => (\n <tr key={`${key}-r-${rIdx}`}>\n {row.map((cell, j) => (\n <td\n key={`${key}-r-${rIdx}-${j}`}\n className={markdownTdStyle}\n style={\n align[j]\n ? { textAlign: align[j] ?? undefined }\n : undefined\n }\n >\n {renderInline(\n cell,\n { linkTarget },\n `${key}-r-${rIdx}-${j}`\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n }\n default:\n return null;\n }\n })}\n </div>\n );\n }\n );\n\nChatMarkdownRenderer.displayName = 'ChatMarkdownRenderer';\n"],"names":[],"mappings":";;;;;;;;AAwCA;AACE;AACF;AAEA;;;;;;AAWE;AAIE;AACE;AACA;AACD;AACD;AACE;AACA;AAQD;AACD;AACE;;AAcD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;AACD;AACE;AACA;AACD;;AAGH;;;;AAMI;;AACA;AACE;;AAEE;;;;;;;;;AAWN;AACE;;AAEF;AACA;;AAGF;AACF;AAoBA;AACE;;;AAIA;;;AAIE;AACE;;;;;;AAOA;;AAEA;AACA;;AAEE;;;;AAIA;AACA;;AAED;;;;AAKH;;AAEE;;;;;;;;;AAUE;;AAEA;AACD;AACD;;;;AAKF;;AAEE;AACE;AACA;;AAEF;;;;AAKF;;AAEE;AACE;AACA;;;;;;AAOJ;;AAEE;AACE;AACA;;;;;;AAOJ;AAEE;AACA;AACA;AAEA;AAEK;AACA;;;AAIL;AACA;;;;;AAIqB;AACnB;AAAW;AACX;AAAU;AACV;AACF;AAEA;;AAEA;AACE;AACA;;AAEF;;;;;AAMF;;AAEE;AAEE;AACA;AACA;AACA;AACA;AACA;;;AAIF;AACA;;AAEF;;AAGF;AACF;AAEA;;;;;;;;;;;;;;;;;AAiBG;;AAED;;AAcI;;AAMA;AASM;AACA;AACE;;;;AAcE;;;AAOF;;AAUA;;AAUA;;AAMA;;AAQA;AACE;;AAEA;AACA;AACA;;AAWgB;;;;AAsClB;AACE;;;AAKZ;AAGJ;;"}
|
|
@@ -88,6 +88,12 @@ import '../../Icons/GitBranchIcon.js';
|
|
|
88
88
|
import '../../Icons/BugIcon.js';
|
|
89
89
|
import '../../Icons/MinusIcon.js';
|
|
90
90
|
import '../../Icons/PinIcon.js';
|
|
91
|
+
import '../../Icons/OrbitIcon.js';
|
|
92
|
+
import '../../Icons/RotateIcon.js';
|
|
93
|
+
import '../../Icons/SpinIcon.js';
|
|
94
|
+
import '../../Icons/CameraIcon.js';
|
|
95
|
+
import '../../Icons/CubeIcon.js';
|
|
96
|
+
import '../../Icons/ZoomFitIcon.js';
|
|
91
97
|
import { Avatar } from '../../primitives/Avatar/Avatar.js';
|
|
92
98
|
import '../../primitives/Avatar/AvatarGroup.js';
|
|
93
99
|
import { cx } from '../../../utils/cx.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessage.js","sources":["
|
|
1
|
+
{"version":3,"file":"ChatMessage.js","sources":["src/components/editor/ChatPanel/ChatMessage.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nimport { ErrorIcon } from '@/components/Icons';\nimport { Avatar } from '@/components/primitives/Avatar';\nimport { cx } from '@/utils/cx';\n\nimport { ChatBubble } from './ChatBubble';\nimport {\n bubbleErrorStyle,\n messageContentStyle,\n messageErrorCaptionStyle,\n messageErrorIconStyle,\n messageMaxWidthVarName,\n messageRecipe,\n messageTextStyle,\n messageTimestampStyle,\n} from './ChatPanel.css';\n\nimport type { ChatMessageProps } from './ChatPanel.types';\n\nfunction resolveMaxWidth(\n value: number | string | undefined\n): string | undefined {\n if (value === undefined) return undefined;\n return typeof value === 'number' ? `${value}px` : value;\n}\n\nfunction formatTimestamp(iso: string): string {\n try {\n const date = new Date(iso);\n return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n } catch {\n return '';\n }\n}\n\nexport const ChatMessage = /*#__PURE__*/ React.memo<ChatMessageProps>(\n ({\n message,\n showTimestamp = false,\n showAvatar = false,\n actions,\n renderContent,\n maxWidth,\n className,\n style,\n testId,\n ref,\n ...rest\n }) => {\n const { role, content, status, timestamp, avatar, displayName } = message;\n const isError = status === 'error';\n\n const renderedContent = renderContent ? (\n renderContent(content)\n ) : (\n <span className={messageTextStyle}>{content}</span>\n );\n\n const resolvedMaxWidth = resolveMaxWidth(maxWidth);\n const rootStyle: React.CSSProperties = resolvedMaxWidth\n ? ({\n [messageMaxWidthVarName]: resolvedMaxWidth,\n ...style,\n } as React.CSSProperties)\n : (style ?? {});\n\n return (\n <div\n ref={ref}\n className={cx(messageRecipe({ role }), className)}\n style={rootStyle}\n data-testid={testId}\n {...rest}\n >\n {showAvatar && role !== 'system' && (\n <Avatar\n size=\"md\"\n src={avatar}\n name={displayName ?? role}\n alt={displayName ?? role}\n />\n )}\n\n <div className={messageContentStyle}>\n <ChatBubble\n role={role}\n className={isError ? bubbleErrorStyle : undefined}\n >\n {renderedContent}\n </ChatBubble>\n\n {isError && (\n <span className={messageErrorCaptionStyle}>\n <span className={messageErrorIconStyle}>\n <ErrorIcon size={12} decorative />\n </span>\n Error generating response\n </span>\n )}\n\n {actions && <div>{actions}</div>}\n\n {showTimestamp && timestamp && (\n <span className={messageTimestampStyle}>\n {formatTimestamp(timestamp)}\n </span>\n )}\n </div>\n </div>\n );\n }\n);\n\nChatMessage.displayName = 'ChatMessage';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA;;AAG2B;AACzB;AACF;AAEA;AACE;AACE;AACA;;AACA;AACA;;AAEJ;AAEO;AAcH;AACA;;AAQA;;AAEE;;AAEI;AACuB;AAC3B;AAEF;AA4CF;AAGF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessageList.js","sources":["
|
|
1
|
+
{"version":3,"file":"ChatMessageList.js","sources":["src/components/editor/ChatPanel/ChatMessageList.tsx"],"sourcesContent":["'use client';\n\nimport React, { useImperativeHandle, useMemo } from 'react';\n\nimport { ScrollArea } from '@/components/layout/ScrollArea';\nimport { useMergedRef } from '@/hooks/useMergedRef';\n\nimport { ChatMessage } from './ChatMessage';\nimport {\n messageListContentStyle,\n newMessagesBannerStyle,\n} from './ChatPanel.css';\nimport { useChatScroll } from './useChatScroll';\n\nimport type {\n ChatMessageListProps,\n ChatMessageListScrollApi,\n} from './ChatPanel.types';\n\nexport const ChatMessageList = /*#__PURE__*/ React.memo<ChatMessageListProps>(\n ({\n messages,\n renderMessage,\n emptyState,\n autoScroll = true,\n scrollApiRef,\n className,\n style,\n testId,\n ref,\n ...rest\n }) => {\n const {\n scrollContainerRef,\n scrollContentRef,\n hasNewMessages,\n scrollToBottom,\n scrollTo,\n scrollToElement,\n } = useChatScroll({\n messages,\n enabled: autoScroll,\n });\n\n // ScrollArea forwards ref to its viewport div — merge with our internal\n // scroll container ref and the consumer's ref.\n const mergedRef = useMergedRef<HTMLDivElement>(scrollContainerRef, ref);\n\n const isAtBottomGetter = React.useCallback(() => {\n const container = scrollContainerRef.current;\n if (!container) return true;\n const { scrollTop, scrollHeight, clientHeight } = container;\n return scrollHeight - scrollTop - clientHeight <= 100;\n }, [scrollContainerRef]);\n\n const scrollApi = useMemo<ChatMessageListScrollApi>(\n () => ({\n scrollToBottom,\n scrollTo,\n scrollToElement,\n isAtBottom: isAtBottomGetter,\n }),\n [scrollToBottom, scrollTo, scrollToElement, isAtBottomGetter]\n );\n\n useImperativeHandle(scrollApiRef, () => scrollApi, [scrollApi]);\n\n if (messages.length === 0 && emptyState) {\n return (\n <ScrollArea\n ref={mergedRef}\n autoFill\n className={className}\n style={style}\n testId={testId}\n {...rest}\n >\n <div\n ref={scrollContentRef}\n className={messageListContentStyle}\n role=\"log\"\n aria-live=\"polite\"\n >\n {emptyState}\n </div>\n </ScrollArea>\n );\n }\n\n return (\n <ScrollArea\n ref={mergedRef}\n autoFill\n className={className}\n style={style}\n testId={testId}\n {...rest}\n >\n <div\n ref={scrollContentRef}\n className={messageListContentStyle}\n role=\"log\"\n aria-live=\"polite\"\n >\n {messages.map((message, index) =>\n renderMessage ? (\n <React.Fragment key={message.id}>\n {renderMessage(message, index)}\n </React.Fragment>\n ) : (\n <ChatMessage key={message.id} message={message} />\n )\n )}\n\n {hasNewMessages && (\n <button\n className={newMessagesBannerStyle}\n onClick={() => {\n scrollToBottom('smooth');\n }}\n type=\"button\"\n >\n New messages\n </button>\n )}\n </div>\n </ScrollArea>\n );\n }\n);\n\nChatMessageList.displayName = 'ChatMessageList';\n"],"names":[],"mappings":";;;;;;;;;AAmBO;AAaH;;AASE;AACD;;;;AAMD;AACE;AACA;AAAgB;;AAEhB;AACF;AAEA;;;;AAKI;;AAKJ;;AAGE;;;;;AA4DJ;AAGF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatPanel.js","sources":["
|
|
1
|
+
{"version":3,"file":"ChatPanel.js","sources":["src/components/editor/ChatPanel/ChatPanel.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nimport { cx } from '@/utils/cx';\n\nimport { chatPanelRecipe, messageMaxWidthVarName } from './ChatPanel.css';\n\nimport type { ChatPanelProps } from './ChatPanel.types';\n\nfunction resolveMaxWidth(\n value: number | string | undefined\n): string | undefined {\n if (value === undefined) return undefined;\n return typeof value === 'number' ? `${value}px` : value;\n}\n\nexport const ChatPanel = /*#__PURE__*/ React.memo<ChatPanelProps>(\n ({\n density = 'comfortable',\n messageMaxWidth,\n children,\n className,\n style,\n testId,\n ref,\n ...rest\n }) => {\n const resolvedMaxWidth = resolveMaxWidth(messageMaxWidth);\n const rootStyle: React.CSSProperties = resolvedMaxWidth\n ? ({\n [messageMaxWidthVarName]: resolvedMaxWidth,\n ...style,\n } as React.CSSProperties)\n : (style ?? {});\n\n return (\n <div\n ref={ref}\n className={cx(chatPanelRecipe({ density }), className)}\n style={rootStyle}\n data-testid={testId}\n {...rest}\n >\n {children}\n </div>\n );\n }\n);\n\nChatPanel.displayName = 'ChatPanel';\n"],"names":[],"mappings":";;;;;;AAUA;;AAG2B;AACzB;AACF;AAEO;AAWH;;AAEE;;AAEI;AACuB;AAC3B;AAEF;AAWF;AAGF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatToolCall.js","sources":["
|
|
1
|
+
{"version":3,"file":"ChatToolCall.js","sources":["src/components/editor/ChatPanel/ChatToolCall.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback } from 'react';\n\nimport { cx } from '@/utils/cx';\n\nimport { MiniWrenchIcon, MiniChevronIcon } from './ChatIcons';\nimport {\n toolCallContainerStyle,\n toolCallHeaderStyle,\n toolCallIconStyle,\n toolCallNameStyle,\n toolCallStatusRecipe,\n toolCallChevronRecipe,\n toolCallDetailsStyle,\n toolCallSectionLabelStyle,\n toolCallPreStyle,\n toolCallErrorStyle,\n toolCallDurationStyle,\n} from './ChatPanel.css';\n\nimport type { ChatToolCallProps } from './ChatPanel.types';\n\n// ─── Status label map ────────────────────────────────────────────\n\nconst STATUS_LABELS = {\n pending: 'Pending',\n running: 'Running',\n completed: 'Completed',\n error: 'Error',\n} as const;\n\n// ─── Component ───────────────────────────────────────────────────\n\nexport const ChatToolCall = /*#__PURE__*/ React.memo<ChatToolCallProps>(\n ({\n toolCall,\n collapsible = true,\n defaultExpanded = false,\n icon,\n renderOutput,\n className,\n style,\n testId,\n ref,\n ...rest\n }) => {\n const [expanded, setExpanded] = useState(defaultExpanded);\n\n const handleToggle = useCallback(() => {\n if (collapsible) {\n setExpanded(prev => !prev);\n }\n }, [collapsible]);\n\n const statusLabel = STATUS_LABELS[toolCall.status];\n const ariaLabel = `Tool ${toolCall.name}: ${statusLabel}`;\n\n return (\n <div\n ref={ref}\n className={cx(toolCallContainerStyle, className)}\n style={style}\n data-testid={testId}\n aria-label={ariaLabel}\n {...rest}\n >\n <button\n type=\"button\"\n className={toolCallHeaderStyle}\n onClick={handleToggle}\n aria-expanded={collapsible ? expanded : undefined}\n >\n <span className={toolCallIconStyle}>\n {icon ?? <MiniWrenchIcon />}\n </span>\n\n <span className={toolCallNameStyle}>{toolCall.name}</span>\n\n <span className={toolCallStatusRecipe({ status: toolCall.status })}>\n {statusLabel}\n </span>\n\n {toolCall.durationMs !== undefined &&\n toolCall.status === 'completed' && (\n <span className={toolCallDurationStyle}>\n {toolCall.durationMs}ms\n </span>\n )}\n\n {collapsible && (\n <span\n className={toolCallChevronRecipe({\n open: expanded || undefined,\n })}\n >\n <MiniChevronIcon />\n </span>\n )}\n </button>\n\n {expanded && (\n <div className={toolCallDetailsStyle}>\n {toolCall.input && (\n <>\n <span className={toolCallSectionLabelStyle}>Input</span>\n <pre className={toolCallPreStyle}>\n {JSON.stringify(toolCall.input, null, 2)}\n </pre>\n </>\n )}\n\n {toolCall.output && (\n <>\n <span className={toolCallSectionLabelStyle}>Output</span>\n {renderOutput ? (\n renderOutput(toolCall.output)\n ) : (\n <pre className={toolCallPreStyle}>\n {JSON.stringify(toolCall.output, null, 2)}\n </pre>\n )}\n </>\n )}\n\n {toolCall.error && (\n <>\n <span className={toolCallSectionLabelStyle}>Error</span>\n <span className={toolCallErrorStyle}>{toolCall.error}</span>\n </>\n )}\n </div>\n )}\n </div>\n );\n }\n);\n\nChatToolCall.displayName = 'ChatToolCall';\n"],"names":[],"mappings":";;;;;;;AAuBA;AAEA;AACE;AACA;AACA;AACA;;AAGF;AAEO;;AAeH;;;;AAIA;;;AAKA;;;AAoCW;AAyCb;AAGF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatTypingIndicator.js","sources":["
|
|
1
|
+
{"version":3,"file":"ChatTypingIndicator.js","sources":["src/components/editor/ChatPanel/ChatTypingIndicator.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nimport { cx } from '@/utils/cx';\n\nimport {\n typingIndicatorStyle,\n typingDotsContainerStyle,\n typingDotStyle,\n typingPulseStyle,\n typingLabelStyle,\n} from './ChatPanel.css';\n\nimport type { ChatTypingIndicatorProps } from './ChatPanel.types';\n\nexport const ChatTypingIndicator =\n /*#__PURE__*/ React.memo<ChatTypingIndicatorProps>(\n ({\n label = 'Thinking...',\n variant = 'dots',\n visible = true,\n className,\n style,\n testId,\n ref,\n ...rest\n }) => {\n if (!visible) return null;\n\n return (\n <div\n ref={ref}\n className={cx(typingIndicatorStyle, className)}\n style={style}\n data-testid={testId}\n role=\"status\"\n aria-label={label}\n {...rest}\n >\n {variant === 'dots' ? (\n <div className={typingDotsContainerStyle} aria-hidden=\"true\">\n <span className={typingDotStyle} />\n <span className={typingDotStyle} />\n <span className={typingDotStyle} />\n </div>\n ) : (\n <div className={typingPulseStyle} aria-hidden=\"true\" />\n )}\n <span className={typingLabelStyle}>{label}</span>\n </div>\n );\n }\n );\n\nChatTypingIndicator.displayName = 'ChatTypingIndicator';\n"],"names":[],"mappings":";;;;;;;AAiBE;AAWI;AAAc;AAEd;AAsBF;AAGJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatInput.js","sources":["
|
|
1
|
+
{"version":3,"file":"useChatInput.js","sources":["src/components/editor/ChatPanel/useChatInput.ts"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\n\nimport type {\n UseChatInputOptions,\n UseChatInputReturn,\n} from './ChatPanel.types';\n\nexport function useChatInput(\n options: UseChatInputOptions = {}\n): UseChatInputReturn {\n const {\n submitKey = 'enter',\n onSubmit,\n maxLines = 6,\n attachmentsCount = 0,\n } = options;\n const [value, setValue] = useState('');\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n const autoResize = useCallback(() => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n\n // Reset height to measure scroll height\n textarea.style.height = 'auto';\n\n const lineHeight = parseInt(\n getComputedStyle(textarea).lineHeight || '18',\n 10\n );\n const maxHeight = maxLines * lineHeight;\n const newHeight = Math.min(textarea.scrollHeight, maxHeight);\n\n textarea.style.height = `${newHeight}px`;\n }, [maxLines]);\n\n // Auto-resize on value change\n useEffect(() => {\n autoResize();\n }, [value, autoResize]);\n\n const clear = useCallback(() => {\n setValue('');\n const textarea = textareaRef.current;\n if (textarea) {\n textarea.style.height = 'auto';\n }\n }, []);\n\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n setValue(event.target.value);\n },\n []\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n const isSubmit =\n submitKey === 'enter'\n ? event.key === 'Enter' &&\n !event.shiftKey &&\n !event.ctrlKey &&\n !event.metaKey\n : event.key === 'Enter' && (event.ctrlKey || event.metaKey);\n\n if (isSubmit) {\n event.preventDefault();\n const trimmed = value.trim();\n if (trimmed || attachmentsCount > 0) {\n onSubmit?.(trimmed);\n clear();\n }\n }\n },\n [submitKey, value, onSubmit, clear, attachmentsCount]\n );\n\n return {\n value,\n setValue,\n clear,\n textareaRef,\n handleKeyDown,\n handleChange,\n };\n}\n"],"names":[],"mappings":";;;AASM;AAGJ;;AAOA;AAEA;AACE;AACA;;;AAGA;AAEA;AAIA;AACA;;AAGF;;;AAIE;AACF;AAEA;;AAEE;;AAEE;;;AAIJ;AAEI;;AAKJ;AAEI;AAEI;;;;AAIA;;;AAIF;AACA;AACE;AACA;;;AAGN;;;;;;;;;AAYJ;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatMessages.js","sources":["
|
|
1
|
+
{"version":3,"file":"useChatMessages.js","sources":["src/components/editor/ChatPanel/useChatMessages.ts"],"sourcesContent":["'use client';\n\nimport { useState, useCallback } from 'react';\n\nimport { useLatest } from '@/hooks/useLatest';\n\nimport type {\n ChatMessageData,\n UseChatMessagesOptions,\n UseChatMessagesReturn,\n} from './ChatPanel.types';\n\nexport function useChatMessages(\n options: UseChatMessagesOptions = {}\n): UseChatMessagesReturn {\n const { initialMessages = [], maxMessages } = options;\n const [messages, setMessages] = useState<ChatMessageData[]>(initialMessages);\n // Latest messages for synchronous reads in getMessage() without stale closures.\n const messagesRef = useLatest(messages);\n\n const trimToMax = useCallback(\n (msgs: ChatMessageData[]): ChatMessageData[] => {\n if (maxMessages !== undefined && msgs.length > maxMessages) {\n return msgs.slice(msgs.length - maxMessages);\n }\n return msgs;\n },\n [maxMessages]\n );\n\n const appendMessage = useCallback(\n (message: ChatMessageData) => {\n setMessages(prev => trimToMax([...prev, message]));\n },\n [trimToMax]\n );\n\n const updateMessage = useCallback(\n (\n id: string,\n update:\n | Partial<ChatMessageData>\n | ((prev: ChatMessageData) => Partial<ChatMessageData>)\n ) => {\n setMessages(prev =>\n prev.map(msg => {\n if (msg.id !== id) return msg;\n const partial = typeof update === 'function' ? update(msg) : update;\n return { ...msg, ...partial };\n })\n );\n },\n []\n );\n\n const removeMessage = useCallback((id: string) => {\n setMessages(prev => prev.filter(msg => msg.id !== id));\n }, []);\n\n const clearMessages = useCallback(() => {\n setMessages([]);\n }, []);\n\n const getMessage = useCallback(\n (id: string): ChatMessageData | undefined => {\n return messagesRef.current.find(msg => msg.id === id);\n },\n // messagesRef is a stable useLatest ref; listed to satisfy the rule.\n [messagesRef]\n );\n\n return {\n messages,\n setMessages,\n appendMessage,\n updateMessage,\n removeMessage,\n clearMessages,\n getMessage,\n };\n}\n"],"names":[],"mappings":";;;;AAYM;;;;AAMJ;AAEA;;;;AAKI;AACF;AAIF;AAEI;AACF;;;AAaM;AAAmB;AACnB;AACA;;;AAOR;;;AAIA;;;AAIA;AAEI;;;;;;;;;;;;;AAeN;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatScroll.js","sources":["
|
|
1
|
+
{"version":3,"file":"useChatScroll.js","sources":["src/components/editor/ChatPanel/useChatScroll.ts"],"sourcesContent":["'use client';\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\n\nimport { useResizeObserver } from '@/hooks/useResizeObserver';\n\nimport type {\n UseChatScrollOptions,\n UseChatScrollReturn,\n} from './ChatPanel.types';\n\nexport function useChatScroll(\n options: UseChatScrollOptions\n): UseChatScrollReturn {\n const { messages, enabled = true, threshold = 100 } = options;\n\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const scrollContentRef = useRef<HTMLDivElement>(null);\n const [isAtBottom, setIsAtBottom] = useState(true);\n const [hasNewMessages, setHasNewMessages] = useState(false);\n const prevMessageCountRef = useRef(messages.length);\n const isAtBottomRef = useRef(isAtBottom);\n const enabledRef = useRef(enabled);\n const lastContentHeightRef = useRef(0);\n\n // Keep refs in sync for use inside observer callbacks.\n useEffect(() => {\n isAtBottomRef.current = isAtBottom;\n }, [isAtBottom]);\n useEffect(() => {\n enabledRef.current = enabled;\n }, [enabled]);\n\n const checkIfAtBottom = useCallback(() => {\n const container = scrollContainerRef.current;\n if (!container) return true;\n\n const { scrollTop, scrollHeight, clientHeight } = container;\n return scrollHeight - scrollTop - clientHeight <= threshold;\n }, [threshold]);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior = 'auto') => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n container.scrollTo({\n top: container.scrollHeight,\n behavior,\n });\n setIsAtBottom(true);\n setHasNewMessages(false);\n }, []);\n\n const scrollTo = useCallback((opts: ScrollToOptions) => {\n const container = scrollContainerRef.current;\n if (!container) return;\n container.scrollTo(opts);\n }, []);\n\n const scrollToElement = useCallback(\n (el: HTMLElement, opts?: ScrollIntoViewOptions) => {\n el.scrollIntoView(opts);\n },\n []\n );\n\n // Listen for scroll events to track position\n useEffect(() => {\n const container = scrollContainerRef.current;\n if (!container) return;\n\n const handleScroll = () => {\n const atBottom = checkIfAtBottom();\n setIsAtBottom(atBottom);\n if (atBottom) {\n setHasNewMessages(false);\n }\n };\n\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => {\n container.removeEventListener('scroll', handleScroll);\n };\n }, [checkIfAtBottom]);\n\n // Seed the last-height baseline once the content node mounts so growth is\n // measured against the initial height, not zero.\n useEffect(() => {\n const content = scrollContentRef.current;\n if (!content) return;\n lastContentHeightRef.current = content.getBoundingClientRect().height;\n }, []);\n\n // Observe content growth — keeps the list pinned to the bottom during streaming\n // (when message text grows but `messages.length` stays constant).\n useResizeObserver(scrollContentRef, entry => {\n const nextHeight = entry.contentRect.height;\n const prevHeight = lastContentHeightRef.current;\n lastContentHeightRef.current = nextHeight;\n\n // Only react to growth — shrinks shouldn't force a scroll jump.\n if (nextHeight <= prevHeight) return;\n if (!enabledRef.current) return;\n\n if (isAtBottomRef.current) {\n scrollToBottom('auto');\n } else {\n setHasNewMessages(true);\n }\n });\n\n // Auto-scroll or show indicator on new messages. Fallback for mounts and\n // cleared lists where content height may not grow monotonically.\n useEffect(() => {\n const currentCount = messages.length;\n const prevCount = prevMessageCountRef.current;\n prevMessageCountRef.current = currentCount;\n\n if (currentCount <= prevCount) return;\n\n if (!enabled) return;\n\n if (isAtBottom) {\n // Use requestAnimationFrame for DOM to update first\n requestAnimationFrame(() => {\n scrollToBottom();\n });\n } else {\n // Reacts to an incoming-message event (count grew while scrolled away) —\n // event-driven, not derivable during render.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasNewMessages(true);\n }\n }, [messages.length, enabled, isAtBottom, scrollToBottom]);\n\n return {\n scrollContainerRef,\n scrollContentRef,\n isAtBottom,\n hasNewMessages,\n scrollToBottom,\n scrollTo,\n scrollToElement,\n };\n}\n"],"names":[],"mappings":";;;;AAWM;AAGJ;AAEA;AACA;;;;AAIA;AACA;AACA;;;AAIE;AACF;;AAEE;AACF;AAEA;AACE;AACA;AAAgB;;AAGhB;AACF;;AAGE;AACA;;;;;AAKC;;;;AAKH;AACE;AACA;;AACA;;;AAKE;;;;AAOF;AACA;;;AAGE;;;;;AAKF;AAEA;AACA;AACE;AACF;AACF;;;;AAKE;AACA;;;;;;AAMF;AACE;AACA;AACA;;;;;;AAMA;;;;;;AAKF;;;;AAKE;AACA;AACA;;;AAIA;;;;;AAKI;AACF;;;;;;;;AAOJ;;;;;;;;;;AAWF;;"}
|
|
@@ -7,7 +7,7 @@ import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
|
7
7
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
8
8
|
import { vars } from '../../../theme/contract.css.js';
|
|
9
9
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
10
|
-
import '
|
|
10
|
+
import '@vanilla-extract/css';
|
|
11
11
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
12
12
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
13
13
|
import '../../../hooks/useNavigationHistory/useNavigationHistory.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Minimap.js","sources":["../../../../../../src/components/editor/Minimap/Minimap.tsx"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiDA;AAEA;AACE;AACA;AACA;;AAGF;AACE;AACA;AACA;;AAYF;;;AAGA;AAEA;AACE;AACE;AACA;AACA;AACA;AACA;AACA;;;;AAKE;AACE;;;;AAIJ;AACA;;;;AAII;AACE;AACF;AACE;;;AAII;;;AAIR;;;AAIF;AAQA;AACE;AAEA;;AAWgC;;AAC3B;;AACA;AACL;AAEI;;;AAMI;AACA;;AAQ2B;;AAC9B;;;;AAGL;AACA;AAEI;;AAEE;;AAEE;;AAER;;AAMJ;AAEA;AACF;AAEA;;;;;AAKG;AACH;AAqBE;;;;;AAKE;AA2BJ;AAEA;;;;;;;;;;;;;;;;AAgBG;AACI;AA0BL;AACA;AAEA;;;AASM;AACA;AACI;AACA;AACA;AACD;;AAMT;;AAGE;AACF;;;;AAKI;AACD;AACH;AAEA;;AAIA;AACE;;;;;;;AAOA;;;;AAID;;AAID;AACA;AACA;AAEA;AACE;AACA;AACE;AACA;;;AAEA;;AAEA;AAEA;AACA;AACA;AACE;AACA;;AAEF;AAEA;AACE;;AAGA;;AAGA;;;;AAMF;;AAEE;;;;;;;AAOD;AACH;AACF;;;;;;;;;;;;AAYC;;AAGC;AACA;AACE;AACF;AACF;;;;;AAKE;;AAIE;AACF;AACA;AACA;AACE;AACF;AACF;;AAIA;;AAcA;AAyBF;AAEA;;"}
|
|
1
|
+
{"version":3,"file":"Minimap.js","sources":["src/components/editor/Minimap/Minimap.tsx"],"sourcesContent":["'use client';\n\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react';\n\nimport { resolveVarValue } from '@/components/primitives/canvas/canvasTheme';\nimport { useLatest } from '@/hooks';\nimport { vars } from '@/theme/contract.css';\nimport { cx } from '@/utils/cx';\n\nimport {\n minimapShellStyle,\n minimapBodyStyle,\n minimapCanvasStyle,\n minimapOverlayLayerStyle,\n titleOutsideStyle,\n titleInsideStyle,\n footerOutsideStyle,\n footerInsideStyle,\n cornerTopLeftStyle,\n cornerTopRightStyle,\n cornerBottomLeftStyle,\n cornerBottomRightStyle,\n ariaLiveRegionStyle,\n} from './Minimap.css';\nimport { MINIMAP_SLOT } from './Minimap.types';\nimport { MinimapStoreContext, useMinimapDragState } from './MinimapContext';\nimport { computeMinimapHeight } from './minimapCoords';\nimport { drawMinimap } from './minimapDrawing';\nimport { MinimapStore } from './MinimapStore';\nimport { useMinimapGestures } from './useMinimapGestures';\n\nimport type {\n MinimapCornerSide,\n MinimapFooterPlacement,\n MinimapInteractionConfig,\n MinimapProps,\n MinimapSlotKind,\n MinimapSlotMarker,\n MinimapTitlePlacement,\n} from './Minimap.types';\nimport type { MinimapDrawColors } from './minimapDrawing';\n\nconst DEFAULT_OUTSIDE_OVERLAY = 'rgba(0, 0, 0, 0.4)';\n\nconst DEFAULT_INTERACTIONS: Required<MinimapInteractionConfig> = {\n click: true,\n dragViewportRect: true,\n dragFromEmpty: true,\n};\n\nconst DISABLED_INTERACTIONS: Required<MinimapInteractionConfig> = {\n click: false,\n dragViewportRect: false,\n dragFromEmpty: false,\n};\n\ninterface CategorizedSlots {\n titleAbove: React.ReactNode;\n titleInside: React.ReactNode;\n footerBelow: React.ReactNode;\n footerInside: React.ReactNode;\n corners: Partial<Record<MinimapCornerSide, React.ReactNode>>;\n other: React.ReactNode[];\n}\n\nfunction getSlotKind(el: React.ReactElement): MinimapSlotKind | null {\n const marker = (el.type as Partial<MinimapSlotMarker>)[MINIMAP_SLOT];\n return marker ?? null;\n}\n\nfunction categorizeChildren(children: React.ReactNode): CategorizedSlots {\n const slots: CategorizedSlots = {\n titleAbove: null,\n titleInside: null,\n footerBelow: null,\n footerInside: null,\n corners: {},\n other: [],\n };\n\n React.Children.forEach(children, child => {\n if (!React.isValidElement(child)) {\n if (child !== null && child !== undefined && child !== false) {\n slots.other.push(child);\n }\n return;\n }\n const kind = getSlotKind(child);\n if (kind === null) {\n // Dev warning: a child whose displayName looks like a Minimap slot\n // (e.g. wrapped in React.memo) but lost the symbol marker.\n if (process.env['NODE_ENV'] !== 'production') {\n const displayName = (child.type as { displayName?: string } | undefined)\n ?.displayName;\n if (displayName?.startsWith('Minimap.')) {\n console.warn(\n `[Minimap] child \"${displayName}\" looks like a slot subcomponent ` +\n `but is missing the MINIMAP_SLOT symbol marker. It will render ` +\n `as a free-form overlay. If you wrapped a slot subcomponent ` +\n `(e.g. with React.memo), copy the symbol onto the wrapper.`\n );\n }\n }\n slots.other.push(child);\n return;\n }\n\n const props = child.props as {\n children?: React.ReactNode;\n placement?: MinimapTitlePlacement | MinimapFooterPlacement;\n side?: MinimapCornerSide;\n className?: string;\n style?: React.CSSProperties;\n };\n\n if (kind === 'title') {\n const placement: MinimapTitlePlacement =\n props.placement === 'top-inside' ? 'top-inside' : 'top-outside';\n const node = (\n <div\n className={cx(\n placement === 'top-inside' ? titleInsideStyle : titleOutsideStyle,\n props.className\n )}\n style={props.style}\n >\n {props.children}\n </div>\n );\n if (placement === 'top-inside') slots.titleInside = node;\n else slots.titleAbove = node;\n } else if (kind === 'footer') {\n const placement: MinimapFooterPlacement =\n props.placement === 'bottom-inside'\n ? 'bottom-inside'\n : 'bottom-outside';\n const node = (\n <div\n className={cx(\n placement === 'bottom-inside'\n ? footerInsideStyle\n : footerOutsideStyle,\n props.className\n )}\n style={props.style}\n >\n {props.children}\n </div>\n );\n if (placement === 'bottom-inside') slots.footerInside = node;\n else slots.footerBelow = node;\n } else {\n // kind is narrowed to 'corner' here (only remaining slot kind).\n const side: MinimapCornerSide = props.side ?? 'top-right';\n const cornerStyle =\n side === 'top-left'\n ? cornerTopLeftStyle\n : side === 'top-right'\n ? cornerTopRightStyle\n : side === 'bottom-left'\n ? cornerBottomLeftStyle\n : cornerBottomRightStyle;\n slots.corners[side] = (\n <div className={cx(cornerStyle, props.className)} style={props.style}>\n {props.children}\n </div>\n );\n }\n });\n\n return slots;\n}\n\n/**\n * The interactive body that hosts canvas + overlay layer + pointer/keyboard\n * handlers. Subscribes to the drag slice for its `data-dragging` attribute\n * + aria-live announcement so neither lives in React state on the outer\n * shell.\n */\nfunction MinimapBody({\n bodyRef,\n canvasRef,\n width,\n height,\n ariaLabel,\n disabled,\n handlers,\n overlayChildren,\n ariaLiveActive,\n}: {\n bodyRef: React.RefObject<HTMLDivElement | null>;\n canvasRef: React.RefObject<HTMLCanvasElement | null>;\n width: number;\n height: number;\n ariaLabel: string;\n disabled: boolean;\n handlers: ReturnType<typeof useMinimapGestures>['handlers'];\n overlayChildren: React.ReactNode;\n ariaLiveActive: boolean;\n}): React.ReactElement {\n const isDragging = useMinimapDragState();\n return (\n // The minimap body is a labelled landmark region that doubles as an\n // interactive pan/zoom surface (focusable, with pointer + key handlers).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <div\n ref={bodyRef}\n className={minimapBodyStyle}\n data-dragging={isDragging || undefined}\n data-disabled={disabled || undefined}\n role=\"region\"\n aria-label={ariaLabel}\n tabIndex={disabled ? -1 : 0}\n style={{ width, height }}\n onPointerDown={handlers.onPointerDown}\n onPointerMove={handlers.onPointerMove}\n onPointerUp={handlers.onPointerUp}\n onPointerCancel={handlers.onPointerCancel}\n onPointerLeave={handlers.onPointerLeave}\n onKeyDown={handlers.onKeyDown}\n >\n <canvas\n ref={canvasRef}\n className={minimapCanvasStyle}\n style={{ width, height }}\n />\n <div className={minimapOverlayLayerStyle}>{overlayChildren}</div>\n <div className={ariaLiveRegionStyle} aria-live=\"polite\" role=\"status\">\n {ariaLiveActive && isDragging ? 'Panning viewport' : ''}\n </div>\n </div>\n );\n}\n\n/**\n * Compact navigation widget for editor viewports. Renders a miniature of\n * the world content alongside a draggable rectangle that mirrors the main\n * viewport's visible region. Intended to be shared by NodeGraph, Timeline,\n * and any custom 2D editor surface.\n *\n * Designed as a controlled primitive — pass the current `transform` /\n * `viewportSize` from your `<Viewport>` and translate `onNavigate.worldPoint`\n * into a `viewport.centerOn(...)` call.\n *\n * Children may include `<Minimap.Title>`, `<Minimap.Footer>`,\n * `<Minimap.Corner>` slot subcomponents — any other nodes render as a\n * free-form overlay layer above the canvas body. Children can read live\n * state (hover position, hovered item id, transform) via\n * `useMinimapContext()` / `useMinimapHover()` / `useMinimapGeometry()` /\n * `useMinimapDragState()`.\n */\nexport const Minimap = ({\n items,\n worldBounds,\n transform,\n viewportSize,\n onNavigate,\n width = 200,\n minHeight = 60,\n maxHeight = 200,\n interactions = DEFAULT_INTERACTIONS,\n keyboardPanStep = 0.1,\n backgroundColor,\n defaultItemColor,\n viewportRectStroke,\n outsideOverlay = DEFAULT_OUTSIDE_OVERLAY,\n renderOverlay,\n disabled = false,\n ariaLabel = 'Minimap',\n className,\n style,\n testId,\n id,\n children,\n ref,\n ...rest\n}: MinimapProps): React.ReactElement => {\n const bodyRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const height = useMemo(\n () => computeMinimapHeight(width, worldBounds, minHeight, maxHeight),\n [width, worldBounds, minHeight, maxHeight]\n );\n const minimapSize = useMemo(() => ({ width, height }), [width, height]);\n\n const interactionsConfig = useMemo<Required<MinimapInteractionConfig>>(\n () =>\n interactions === false\n ? DISABLED_INTERACTIONS\n : {\n click: interactions.click ?? true,\n dragViewportRect: interactions.dragViewportRect ?? true,\n dragFromEmpty: interactions.dragFromEmpty ?? true,\n },\n [interactions]\n );\n\n // ── Store ──\n\n const store = useMemo(() => new MinimapStore(), []);\n\n useLayoutEffect(() => {\n store.setGeometry({ transform, viewportSize, worldBounds, minimapSize });\n }, [store, transform, viewportSize, worldBounds, minimapSize]);\n\n useLayoutEffect(() => {\n store.configureHandle({\n focus: () => bodyRef.current?.focus(),\n getElement: () => bodyRef.current,\n });\n }, [store]);\n\n useImperativeHandle(ref, () => store.handle, [store]);\n\n // ── Gestures ──\n\n const { handlers } = useMinimapGestures({\n containerRef: bodyRef,\n store,\n worldBounds,\n transform,\n viewportSize,\n minimapSize,\n items,\n interactions: interactionsConfig,\n keyboardPanStep,\n disabled,\n onNavigate,\n });\n\n // ── Draw — useLayoutEffect + scheduleDraw, theme resolved per-frame ──\n\n const renderOverlayRef = useLatest(renderOverlay);\n const itemsRef = useLatest(items);\n const rafRef = useRef<number>(0);\n\n const scheduleDraw = useCallback((): void => {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n const dpr =\n typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;\n const targetW = Math.max(1, Math.round(width * dpr));\n const targetH = Math.max(1, Math.round(height * dpr));\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW;\n canvas.height = targetH;\n }\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n\n const colors: MinimapDrawColors = {\n background:\n backgroundColor ??\n resolveVarValue(canvas, vars.colors.background.secondary),\n defaultItem:\n defaultItemColor ??\n resolveVarValue(canvas, vars.colors.accent.primary),\n viewportRectStroke:\n viewportRectStroke ??\n resolveVarValue(canvas, vars.colors.accent.primary),\n outsideOverlay,\n };\n\n drawMinimap({\n ctx,\n size: { width, height },\n worldBounds,\n transform,\n viewportSize,\n items: itemsRef.current,\n colors,\n renderOverlay: renderOverlayRef.current,\n });\n });\n }, [\n width,\n height,\n worldBounds,\n transform,\n viewportSize,\n backgroundColor,\n defaultItemColor,\n viewportRectStroke,\n outsideOverlay,\n itemsRef,\n renderOverlayRef,\n ]);\n\n useLayoutEffect(() => {\n scheduleDraw();\n return () => {\n cancelAnimationFrame(rafRef.current);\n };\n }, [scheduleDraw]);\n\n // Redraw when DPR changes (e.g. dragging to a different display).\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia(\n `(resolution: ${window.devicePixelRatio}dppx)`\n );\n const handler = (): void => {\n scheduleDraw();\n };\n mq.addEventListener('change', handler);\n return () => {\n mq.removeEventListener('change', handler);\n };\n }, [scheduleDraw]);\n\n // ── Slots ──\n\n const slots = useMemo(() => categorizeChildren(children), [children]);\n\n const overlayChildren = (\n <>\n {slots.titleInside}\n {slots.footerInside}\n {slots.corners['top-left']}\n {slots.corners['top-right']}\n {slots.corners['bottom-left']}\n {slots.corners['bottom-right']}\n {slots.other}\n </>\n );\n\n return (\n <MinimapStoreContext.Provider value={store}>\n <div\n className={cx(minimapShellStyle, className)}\n data-testid={testId}\n id={id}\n style={style}\n {...rest}\n >\n {slots.titleAbove}\n <MinimapBody\n bodyRef={bodyRef}\n canvasRef={canvasRef}\n width={width}\n height={height}\n ariaLabel={ariaLabel}\n disabled={disabled}\n handlers={handlers}\n overlayChildren={overlayChildren}\n ariaLiveActive={!disabled}\n />\n {slots.footerBelow}\n </div>\n </MinimapStoreContext.Provider>\n );\n};\n\nMinimap.displayName = 'Minimap';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiDA;AAEA;AACE;AACA;AACA;;AAGF;AACE;AACA;AACA;;AAYF;;;AAGA;AAEA;AACE;AACE;AACA;AACA;AACA;AACA;AACA;;;;AAKE;AACE;;;;AAIJ;AACA;;;;AAII;AACE;AACF;AACE;;;AAII;;;AAIR;;;AAIF;AAQA;AACE;AAEA;;AAWgC;;AAC3B;;AACA;AACL;AAEI;;;AAMI;AACA;;AAQ2B;;AAC9B;;;;AAGL;AACA;AAEI;;AAEE;;AAEE;;AAER;;AAMJ;AAEA;AACF;AAEA;;;;;AAKG;AACH;AAqBE;;;;;AAKE;AA2BJ;AAEA;;;;;;;;;;;;;;;;AAgBG;AACI;AA0BL;AACA;AAEA;;;AASM;AACA;AACI;AACA;AACA;AACD;;AAMT;;AAGE;AACF;;;;AAKI;AACD;AACH;AAEA;;AAIA;AACE;;;;;;;AAOA;;;;AAID;;AAID;AACA;AACA;AAEA;AACE;AACA;AACE;AACA;;;AAEA;;AAEA;AAEA;AACA;AACA;AACE;AACA;;AAEF;AAEA;AACE;;AAGA;;AAGA;;;;AAMF;;AAEE;;;;;;;AAOD;AACH;AACF;;;;;;;;;;;;AAYC;;AAGC;AACA;AACE;AACF;AACF;;;;;AAKE;;AAIE;AACF;AACA;AACA;AACE;AACF;AACF;;AAIA;;AAcA;AAyBF;AAEA;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Minimap.types.js","sources":["../../../../../../src/components/editor/Minimap/Minimap.types.ts"],"sourcesContent":[null],"names":[],"mappings":"AAyHA;AAEA;;;;;AAKG;AACI,MAAM,YAAY,GAAkB,MAAM,CAAC,GAAG,CAAC,mBAAmB;;;;"}
|
|
1
|
+
{"version":3,"file":"Minimap.types.js","sources":["src/components/editor/Minimap/Minimap.types.ts"],"sourcesContent":["import type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type {\n ViewportTransform,\n ViewportSize,\n WorldRect,\n} from '@/components/primitives/viewport';\nimport type { BaseComponent } from '@/types/common';\nimport type { Prettify } from '@/types/utilities';\nimport type React from 'react';\n\n// ─── Drawing info ───\n\n/**\n * Helpers and current state passed to `renderOverlay` and to custom item\n * `draw` callbacks. Exposes the same world ↔ minimap math the built-in\n * shapes use, so consumer drawing stays aligned with everything else.\n */\nexport interface MinimapDrawInfo {\n /** Minimap size in CSS pixels (canvas already DPR-scaled). */\n minimapSize: ViewportSize;\n /** World rectangle this minimap maps from. */\n worldBounds: WorldRect;\n /** Current main-viewport transform (mirrored). */\n transform: ViewportTransform;\n /** Current main-viewport size in CSS pixels (mirrored). */\n viewportSize: ViewportSize;\n /** Uniform world → minimap scale (px per world unit). */\n scale: number;\n /** Letterbox offset applied when minimap aspect ≠ worldBounds aspect. */\n offset: Point2D;\n /** Map a world point to a minimap CSS-pixel point. */\n worldToMinimap: (point: Point2D) => Point2D;\n /** Inverse of `worldToMinimap`. */\n minimapToWorld: (point: Point2D) => Point2D;\n}\n\n// ─── Items ───\n\ninterface MinimapItemBase {\n /** Stable identity. Used for hover hit-testing and future selection support. */\n id: string;\n /** Override draw color for this item. Falls back to `defaultItemColor`. */\n color?: string;\n}\n\nexport interface MinimapRectItem extends MinimapItemBase {\n type: 'rect';\n /** Top-left X in world units. */\n x: number;\n /** Top-left Y in world units. */\n y: number;\n /** Width in world units. */\n width: number;\n /** Height in world units. */\n height: number;\n}\n\nexport interface MinimapCircleItem extends MinimapItemBase {\n type: 'circle';\n /** Center X in world units. */\n cx: number;\n /** Center Y in world units. */\n cy: number;\n /** Radius in world units. */\n r: number;\n}\n\nexport interface MinimapLineItem extends MinimapItemBase {\n type: 'line';\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n /** Stroke width in minimap CSS pixels (does not scale with content). @default 1 */\n lineWidth?: number;\n}\n\n/**\n * Caller-defined item. `draw` is invoked with the minimap canvas context\n * and a `MinimapDrawInfo` object containing world ↔ minimap helpers.\n * `bounds` (world coords) is used for hover hit-testing.\n */\nexport interface MinimapCustomItem extends MinimapItemBase {\n type: 'custom';\n bounds: WorldRect;\n draw: (ctx: CanvasRenderingContext2D, info: MinimapDrawInfo) => void;\n}\n\n/** Discriminated union of all minimap item shapes. */\nexport type MinimapItem =\n | MinimapRectItem\n | MinimapCircleItem\n | MinimapLineItem\n | MinimapCustomItem;\n\n// ─── Interactions ───\n\nexport type MinimapNavigatePhase = 'click' | 'drag-start' | 'drag' | 'drag-end';\n\n/**\n * Info passed to `onNavigate` for every navigation event.\n *\n * `worldPoint` is the world-space point the user wants at the center\n * of the main viewport — call `viewport.centerOn(info.worldPoint)`\n * (or update your transform accordingly) to satisfy the request.\n */\nexport interface MinimapNavigateInfo {\n worldPoint: Point2D;\n phase: MinimapNavigatePhase;\n}\n\n/** Fine-grained gesture toggles. Pass `false` to `interactions` to disable everything. */\nexport interface MinimapInteractionConfig {\n /** Tap outside the viewport rect → `phase: 'click'`. @default true */\n click?: boolean;\n /** Drag the viewport rect itself → `phase: 'drag-*'`. @default true */\n dragViewportRect?: boolean;\n /** Drag starting outside the rect → immediately jumps + pans. @default true */\n dragFromEmpty?: boolean;\n}\n\n// ─── Slot markers ───\n\n/**\n * Symbol attached to `Minimap.Title` / `.Footer` / `.Corner` so the parent\n * `<Minimap>` can identify slot children without relying on `displayName`\n * (which gets clobbered by wrappers like `React.memo`, `React.forwardRef`,\n * or Vanilla Extract recipes).\n */\nexport const MINIMAP_SLOT: unique symbol = Symbol.for('etui.minimap.slot');\n\nexport type MinimapSlotKind = 'title' | 'footer' | 'corner';\n\nexport interface MinimapSlotMarker {\n [MINIMAP_SLOT]: MinimapSlotKind;\n}\n\nexport type MinimapTitlePlacement = 'top-outside' | 'top-inside';\nexport type MinimapFooterPlacement = 'bottom-outside' | 'bottom-inside';\nexport type MinimapCornerSide =\n | 'top-left'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-right';\n\n// ─── Imperative handle ───\n\n/**\n * Imperative handle exposed via `ref` on `<Minimap>` and `<ViewportMinimap>`.\n * Stable for the lifetime of the component.\n */\nexport interface MinimapHandle {\n /** Focus the minimap body so arrow keys start working. */\n focus(): void;\n /** Access the underlying body DOM element (the `role=\"region\"` div). */\n getElement(): HTMLDivElement | null;\n /** Convert a world-space point to minimap CSS-pixel coordinates. */\n worldToMinimap(point: Point2D): Point2D;\n /** Inverse of `worldToMinimap`. */\n minimapToWorld(point: Point2D): Point2D;\n}\n\n// ─── Props ───\n\nexport interface MinimapBaseProps extends Omit<\n BaseComponent,\n 'onChange' | 'ref'\n> {\n /** Items rendered as the content miniature. */\n items: ReadonlyArray<MinimapItem>;\n /**\n * World-space rectangle the minimap maps to. Use the exported\n * `computeBoundsFromItems(items, padding?)` helper if you don't already\n * track one yourself.\n */\n worldBounds: WorldRect;\n /** Current main-viewport transform — drives the viewport rect overlay. */\n transform: ViewportTransform;\n /** Current main-viewport size in CSS pixels — drives the viewport rect overlay. */\n viewportSize: ViewportSize;\n\n /**\n * Called when the user navigates via click, drag, or arrow keys.\n * `info.worldPoint` is the world-space point that should sit at the\n * center of the main viewport — pass it to `viewport.centerOn(...)`.\n */\n onNavigate?: (info: MinimapNavigateInfo) => void;\n\n /**\n * Minimap width in CSS pixels. Height is derived from `worldBounds`\n * aspect ratio and clamped to `[minHeight, maxHeight]`.\n * @default 200\n */\n width?: number;\n /** @default 60 */\n minHeight?: number;\n /** @default 200 */\n maxHeight?: number;\n\n /**\n * Gesture configuration. Pass `false` to disable all interactions.\n * @default { click: true, dragViewportRect: true, dragFromEmpty: true }\n */\n interactions?: MinimapInteractionConfig | false;\n\n /**\n * Keyboard pan step, as a fraction of the current main-viewport's\n * world-space extent per arrow-key press. Shift × 5.\n * @default 0.1\n */\n keyboardPanStep?: number;\n\n /** Override background color. Defaults to theme `--etui-color-bg-secondary`. */\n backgroundColor?: string;\n /** Default item color. Defaults to theme accent. */\n defaultItemColor?: string;\n /** Viewport-rect outline color. Defaults to theme accent. */\n viewportRectStroke?: string;\n /**\n * Dimmed overlay color covering the area outside the viewport rect.\n * @default 'rgba(0, 0, 0, 0.4)'\n */\n outsideOverlay?: string;\n\n /**\n * Custom canvas drawing pass executed after items and before the\n * viewport-rect shroud + outline. Use for backdrops, playheads, grid\n * overlays, selection regions — anything that should sit between items\n * and the viewport-rect chrome.\n */\n renderOverlay?: (\n ctx: CanvasRenderingContext2D,\n info: MinimapDrawInfo\n ) => void;\n\n /** Disable interactions and dim the minimap. @default false */\n disabled?: boolean;\n\n /** @default 'Minimap' */\n ariaLabel?: string;\n\n /**\n * Slot children. Pass `<Minimap.Title>`, `<Minimap.Footer>`,\n * `<Minimap.Corner>` subcomponents for chrome, or arbitrary nodes for\n * absolute overlays inside the canvas body. Children that aren't\n * recognised slot markers render as a free-form overlay layer.\n */\n children?: React.ReactNode;\n\n /** Imperative handle. */\n ref?: React.Ref<MinimapHandle>;\n}\n\nexport type MinimapProps = Prettify<MinimapBaseProps>;\n\n// ─── Subcomponent props ───\n\nexport interface MinimapTitleProps {\n children?: React.ReactNode;\n /** @default 'top-outside' */\n placement?: MinimapTitlePlacement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport interface MinimapFooterProps {\n children?: React.ReactNode;\n /** @default 'bottom-outside' */\n placement?: MinimapFooterPlacement;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport interface MinimapCornerProps {\n children?: React.ReactNode;\n /** Which corner of the canvas body to anchor in. @default 'top-right' */\n side?: MinimapCornerSide;\n className?: string;\n style?: React.CSSProperties;\n}\n\n// ─── MinimapContext value ───\n\n/**\n * Live state available to children of a `<Minimap>` via `useMinimapContext()`.\n *\n * For perf-conscious consumers, prefer the per-slice hooks\n * (`useMinimapHover`, `useMinimapGeometry`, `useMinimapDragState`) — each\n * subscribes to a single slice and re-renders only when that slice\n * changes. `useMinimapContext()` re-renders on every store mutation.\n */\nexport interface MinimapContextValue {\n worldBounds: WorldRect;\n minimapSize: ViewportSize;\n transform: ViewportTransform;\n viewportSize: ViewportSize;\n /** Current pointer position in world coordinates, or null when not hovering. */\n hoverWorldPoint: Point2D | null;\n /** Id of the item currently under the pointer (hit-test), or null. */\n hoveredItemId: string | null;\n /** True during an active drag (rect or pan). */\n isDragging: boolean;\n /** Uniform world → minimap scale. */\n scale: number;\n /** Letterbox offset. */\n offset: Point2D;\n /** Same helpers exposed in `MinimapDrawInfo`, for symmetry. */\n worldToMinimap: (point: Point2D) => Point2D;\n minimapToWorld: (point: Point2D) => Point2D;\n}\n"],"names":[],"mappings":"AAyHA;AAEA;;;;;AAKG;AACI,MAAM,YAAY,GAAkB,MAAM,CAAC,GAAG,CAAC,mBAAmB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimapContext.js","sources":["
|
|
1
|
+
{"version":3,"file":"MinimapContext.js","sources":["src/components/editor/Minimap/MinimapContext.ts"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useSyncExternalStore } from 'react';\n\nimport type { MinimapContextValue } from './Minimap.types';\nimport type {\n MinimapGeometryState,\n MinimapHoverState,\n MinimapStore,\n} from './MinimapStore';\n\nexport const MinimapStoreContext = createContext<MinimapStore | null>(null);\n\nfunction useMinimapStoreInternal(): MinimapStore {\n const store = useContext(MinimapStoreContext);\n if (!store) {\n throw new Error(\n 'useMinimap* hooks must be called inside a <Minimap> component'\n );\n }\n return store;\n}\n\n/**\n * Subscribe to **all** Minimap state. Convenient catch-all but re-renders\n * on every store mutation. For perf-sensitive consumers, prefer the\n * slice-specific hooks (`useMinimapHover`, `useMinimapGeometry`,\n * `useMinimapDragState`).\n */\nexport function useMinimapContext(): MinimapContextValue {\n const store = useMinimapStoreInternal();\n return useSyncExternalStore(store.subscribe, store.getSnapshot);\n}\n\n/**\n * Subscribe to the hover slice. Re-renders only when the pointer position\n * or hovered item id changes.\n */\nexport function useMinimapHover(): MinimapHoverState {\n const store = useMinimapStoreInternal();\n return useSyncExternalStore(store.subscribeHover, store.getHover);\n}\n\n/**\n * Subscribe to the geometry slice (transform / sizes / bounds). Re-renders\n * only on geometry mutations.\n */\nexport function useMinimapGeometry(): MinimapGeometryState {\n const store = useMinimapStoreInternal();\n return useSyncExternalStore(store.subscribeGeometry, store.getGeometry);\n}\n\n/**\n * Subscribe to the drag slice — `true` while a pan/rect-drag gesture is\n * in flight. Re-renders only on drag-state transitions.\n */\nexport function useMinimapDragState(): boolean {\n const store = useMinimapStoreInternal();\n return useSyncExternalStore(store.subscribeDrag, store.getIsDragging);\n}\n"],"names":[],"mappings":";;;;AAaA;AACE;;AAEE;;AAIF;AACF;AAEA;;;;;AAKG;;AAED;;AAEF;AAEA;;;AAGG;;AAED;;AAEF;AAEA;;;AAGG;;AAED;;AAEF;AAEA;;;AAGG;;AAED;;AAEF;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimapCorner.js","sources":["
|
|
1
|
+
{"version":3,"file":"MinimapCorner.js","sources":["src/components/editor/Minimap/MinimapCorner.tsx"],"sourcesContent":["import { MINIMAP_SLOT } from './Minimap.types';\n\nimport type { MinimapCornerProps } from './Minimap.types';\n\n/**\n * Small chrome block anchored in one of the four corners of the Minimap\n * canvas body. Typical use cases: coordinate readouts, zoom-level chips,\n * status badges. Picked out of `<Minimap>` children by the `MINIMAP_SLOT`\n * symbol — does not render itself in place.\n */\nconst MinimapCornerImpl: (props: MinimapCornerProps) => null = () => null;\n\nexport const MinimapCorner = Object.assign(MinimapCornerImpl, {\n displayName: 'Minimap.Corner',\n [MINIMAP_SLOT]: 'corner' as const,\n});\n"],"names":[],"mappings":";;AAIA;;;;;AAKG;AACH,MAAM,iBAAiB,GAAwC,MAAM,IAAI;MAE5D,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;AAC5D,IAAA,WAAW,EAAE,gBAAgB;IAC7B,CAAC,YAAY,GAAG,QAAiB;AAClC,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimapFooter.js","sources":["
|
|
1
|
+
{"version":3,"file":"MinimapFooter.js","sources":["src/components/editor/Minimap/MinimapFooter.tsx"],"sourcesContent":["import { MINIMAP_SLOT } from './Minimap.types';\n\nimport type { MinimapFooterProps } from './Minimap.types';\n\n/**\n * Footer strip rendered below (or inside the bottom of) the Minimap\n * canvas body. Picked out of `<Minimap>` children by the `MINIMAP_SLOT`\n * symbol — does not render itself in place, so its tree position has no\n * effect on its placement.\n */\nconst MinimapFooterImpl: (props: MinimapFooterProps) => null = () => null;\n\nexport const MinimapFooter = Object.assign(MinimapFooterImpl, {\n displayName: 'Minimap.Footer',\n [MINIMAP_SLOT]: 'footer' as const,\n});\n"],"names":[],"mappings":";;AAIA;;;;;AAKG;AACH,MAAM,iBAAiB,GAAwC,MAAM,IAAI;MAE5D,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;AAC5D,IAAA,WAAW,EAAE,gBAAgB;IAC7B,CAAC,YAAY,GAAG,QAAiB;AAClC,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimapStore.js","sources":["../../../../../../src/components/editor/Minimap/MinimapStore.ts"],"sourcesContent":[null],"names":["worldToMinimapFn","minimapToWorldFn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MinimapStore.js","sources":["src/components/editor/Minimap/MinimapStore.ts"],"sourcesContent":["import {\n computeMinimapOffset,\n computeMinimapScale,\n minimapToWorld as minimapToWorldFn,\n worldToMinimap as worldToMinimapFn,\n} from './minimapCoords';\n\nimport type { MinimapContextValue, MinimapHandle } from './Minimap.types';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type {\n ViewportSize,\n ViewportTransform,\n WorldRect,\n} from '@/components/primitives/viewport';\n\nconst IDENTITY_TRANSFORM: ViewportTransform = { x: 0, y: 0, zoom: 1 };\nconst ZERO_SIZE: ViewportSize = { width: 0, height: 0 };\nconst ZERO_RECT: WorldRect = { x: 0, y: 0, width: 0, height: 0 };\n\n/** Snapshot of the geometry slice — the data needed to position anything. */\nexport interface MinimapGeometryState {\n transform: ViewportTransform;\n viewportSize: ViewportSize;\n worldBounds: WorldRect;\n minimapSize: ViewportSize;\n}\n\n/** Snapshot of the hover slice. */\nexport interface MinimapHoverState {\n hoverWorldPoint: Point2D | null;\n hoveredItemId: string | null;\n}\n\n/**\n * Single source of truth for Minimap runtime state — geometry, hover,\n * drag. Designed for React's `useSyncExternalStore`: each slice has its\n * own subscribe/get pair so subscribers re-render only when their slice\n * changes (not on every store mutation).\n *\n * Wzorowane 1:1 na `primitives/viewport/ViewportStore.ts`.\n */\nexport class MinimapStore {\n private geometry: MinimapGeometryState = {\n transform: IDENTITY_TRANSFORM,\n viewportSize: ZERO_SIZE,\n worldBounds: ZERO_RECT,\n minimapSize: ZERO_SIZE,\n };\n private hover: MinimapHoverState = {\n hoverWorldPoint: null,\n hoveredItemId: null,\n };\n private isDragging = false;\n private snapshot: MinimapContextValue = this.computeSnapshot();\n\n private allListeners = new Set<() => void>();\n private geometryListeners = new Set<() => void>();\n private hoverListeners = new Set<() => void>();\n private dragListeners = new Set<() => void>();\n\n // ── Public read API (arrow functions so they can be passed as callbacks) ──\n\n getSnapshot = (): MinimapContextValue => this.snapshot;\n getGeometry = (): MinimapGeometryState => this.geometry;\n getHover = (): MinimapHoverState => this.hover;\n getIsDragging = (): boolean => this.isDragging;\n\n // ── Subscriptions ──\n\n subscribe = (cb: () => void): (() => void) => {\n this.allListeners.add(cb);\n return () => {\n this.allListeners.delete(cb);\n };\n };\n\n subscribeGeometry = (cb: () => void): (() => void) => {\n this.geometryListeners.add(cb);\n return () => {\n this.geometryListeners.delete(cb);\n };\n };\n\n subscribeHover = (cb: () => void): (() => void) => {\n this.hoverListeners.add(cb);\n return () => {\n this.hoverListeners.delete(cb);\n };\n };\n\n subscribeDrag = (cb: () => void): (() => void) => {\n this.dragListeners.add(cb);\n return () => {\n this.dragListeners.delete(cb);\n };\n };\n\n // ── Mutators ──\n\n setGeometry(partial: Partial<MinimapGeometryState>): void {\n const next: MinimapGeometryState = {\n transform: partial.transform ?? this.geometry.transform,\n viewportSize: partial.viewportSize ?? this.geometry.viewportSize,\n worldBounds: partial.worldBounds ?? this.geometry.worldBounds,\n minimapSize: partial.minimapSize ?? this.geometry.minimapSize,\n };\n if (\n next.transform === this.geometry.transform &&\n sizeEqual(next.viewportSize, this.geometry.viewportSize) &&\n rectEqual(next.worldBounds, this.geometry.worldBounds) &&\n sizeEqual(next.minimapSize, this.geometry.minimapSize)\n ) {\n return;\n }\n this.geometry = next;\n this.snapshot = this.computeSnapshot();\n this.geometryListeners.forEach(cb => {\n cb();\n });\n this.allListeners.forEach(cb => {\n cb();\n });\n }\n\n setHover(next: MinimapHoverState): void {\n if (\n hoverPointEqual(next.hoverWorldPoint, this.hover.hoverWorldPoint) &&\n next.hoveredItemId === this.hover.hoveredItemId\n ) {\n return;\n }\n this.hover = next;\n this.snapshot = this.computeSnapshot();\n this.hoverListeners.forEach(cb => {\n cb();\n });\n this.allListeners.forEach(cb => {\n cb();\n });\n }\n\n setIsDragging(next: boolean): void {\n if (next === this.isDragging) return;\n this.isDragging = next;\n this.snapshot = this.computeSnapshot();\n this.dragListeners.forEach(cb => {\n cb();\n });\n this.allListeners.forEach(cb => {\n cb();\n });\n }\n\n // ── Imperative handle ──\n\n /**\n * Stable handle whose methods proxy to the current store state. The\n * handle reference is stable for the lifetime of the store.\n */\n readonly handle: MinimapHandle = {\n focus: (): void => {\n this.focusElement?.();\n },\n getElement: (): HTMLDivElement | null => this.elementGetter?.() ?? null,\n worldToMinimap: (p: Point2D): Point2D =>\n worldToMinimapFn(p, this.geometry.worldBounds, this.geometry.minimapSize),\n minimapToWorld: (p: Point2D): Point2D =>\n minimapToWorldFn(p, this.geometry.worldBounds, this.geometry.minimapSize),\n };\n\n /** Wired up by `Minimap.tsx` so the handle knows which element to act on. */\n configureHandle(config: {\n focus: () => void;\n getElement: () => HTMLDivElement | null;\n }): void {\n this.focusElement = config.focus;\n this.elementGetter = config.getElement;\n }\n\n private focusElement: (() => void) | null = null;\n private elementGetter: (() => HTMLDivElement | null) | null = null;\n\n private computeSnapshot(): MinimapContextValue {\n const { worldBounds, minimapSize, transform, viewportSize } = this.geometry;\n const scale = computeMinimapScale(worldBounds, minimapSize);\n const offset = computeMinimapOffset(worldBounds, minimapSize, scale);\n return {\n worldBounds,\n minimapSize,\n transform,\n viewportSize,\n hoverWorldPoint: this.hover.hoverWorldPoint,\n hoveredItemId: this.hover.hoveredItemId,\n isDragging: this.isDragging,\n scale,\n offset,\n worldToMinimap: (p: Point2D): Point2D =>\n worldToMinimapFn(p, worldBounds, minimapSize),\n minimapToWorld: (p: Point2D): Point2D =>\n minimapToWorldFn(p, worldBounds, minimapSize),\n };\n }\n}\n\nfunction sizeEqual(a: ViewportSize, b: ViewportSize): boolean {\n return a.width === b.width && a.height === b.height;\n}\n\nfunction rectEqual(a: WorldRect, b: WorldRect): boolean {\n return (\n a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height\n );\n}\n\nfunction hoverPointEqual(a: Point2D | null, b: Point2D | null): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return a.x === b.x && a.y === b.y;\n}\n"],"names":["worldToMinimapFn","minimapToWorldFn"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MinimapTitle.js","sources":["
|
|
1
|
+
{"version":3,"file":"MinimapTitle.js","sources":["src/components/editor/Minimap/MinimapTitle.tsx"],"sourcesContent":["import { MINIMAP_SLOT } from './Minimap.types';\n\nimport type { MinimapTitleProps } from './Minimap.types';\n\n/**\n * Title strip rendered above (or inside the top of) the Minimap canvas\n * body. Picked out of `<Minimap>` children by the `MINIMAP_SLOT` symbol —\n * does not render itself in place, so its tree position has no effect on\n * its placement.\n */\nconst MinimapTitleImpl: (props: MinimapTitleProps) => null = () => null;\n\nexport const MinimapTitle = Object.assign(MinimapTitleImpl, {\n displayName: 'Minimap.Title',\n [MINIMAP_SLOT]: 'title' as const,\n});\n"],"names":[],"mappings":";;AAIA;;;;;AAKG;AACH,MAAM,gBAAgB,GAAuC,MAAM,IAAI;MAE1D,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE;AAC1D,IAAA,WAAW,EAAE,eAAe;IAC5B,CAAC,YAAY,GAAG,OAAgB;AACjC,CAAA;;;;"}
|
|
@@ -11,7 +11,7 @@ import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
|
11
11
|
import { useResizeObserver } from '../../../hooks/useResizeObserver/useResizeObserver.js';
|
|
12
12
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
13
13
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
14
|
-
import '
|
|
14
|
+
import '@vanilla-extract/css';
|
|
15
15
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
16
16
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
17
17
|
import '../../../hooks/useNavigationHistory/useNavigationHistory.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewportMinimap.js","sources":["
|
|
1
|
+
{"version":3,"file":"ViewportMinimap.js","sources":["src/components/editor/Minimap/ViewportMinimap.tsx"],"sourcesContent":["'use client';\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\n\nimport { useViewportContext } from '@/components/primitives/viewport';\nimport { useLatest, useResizeObserver } from '@/hooks';\n\nimport { Minimap } from './Minimap';\n\nimport type {\n MinimapHandle,\n MinimapNavigateInfo,\n MinimapProps,\n} from './Minimap.types';\n\nexport type ViewportMinimapPlacement =\n | 'top-left'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-right'\n | {\n top?: number | string;\n right?: number | string;\n bottom?: number | string;\n left?: number | string;\n width?: number | string;\n height?: number | string;\n };\n\nexport interface ViewportMinimapProps extends Omit<\n MinimapProps,\n 'transform' | 'viewportSize' | 'ref'\n> {\n /**\n * Anchored position inside the parent `<Viewport>`. Use a preset for\n * the four corners, or an object for custom anchoring.\n * @default 'bottom-right'\n */\n placement?: ViewportMinimapPlacement;\n /**\n * Distance (CSS px) from the viewport edge when using a preset placement.\n * Ignored when `placement` is an object.\n * @default 12\n */\n margin?: number;\n /**\n * When true, the minimap width tracks the wrapper's measured width via\n * ResizeObserver. The wrapper size must be controlled externally (e.g.\n * via custom `placement` or a parent container). The `width` prop, if\n * provided, becomes a fallback used until the first measurement lands.\n * @default false\n */\n responsive?: boolean;\n /** Imperative handle (same shape as `<Minimap>`'s). */\n ref?: React.Ref<MinimapHandle>;\n}\n\nfunction placementToStyle(\n placement: ViewportMinimapPlacement,\n margin: number\n): React.CSSProperties {\n if (typeof placement === 'object') {\n return { position: 'absolute', pointerEvents: 'auto', ...placement };\n }\n const style: React.CSSProperties = {\n position: 'absolute',\n pointerEvents: 'auto',\n };\n if (placement.startsWith('top')) style.top = margin;\n else style.bottom = margin;\n if (placement.endsWith('left')) style.left = margin;\n else style.right = margin;\n return style;\n}\n\n/**\n * Auto-bound minimap for use inside a `<Viewport>`. Reads live `transform`\n * and `size` from `useViewportContext()`, positions itself in a corner\n * (or custom anchor), and wires `onNavigate` to the viewport handle's\n * `centerOn`. Falls back to the manual `<Minimap>` if you need the\n * minimap outside the Viewport tree.\n *\n * Recognized by `<Viewport>` as an overlay child — drop it among layers\n * and world/overlay siblings without an explicit `<ViewportOverlay>` wrapper.\n */\nexport const ViewportMinimap = ({\n placement = 'bottom-right',\n margin = 12,\n responsive = false,\n width: widthProp,\n onNavigate: userOnNavigate,\n ref,\n ...minimapProps\n}: ViewportMinimapProps): React.ReactElement => {\n const { transform, size, handle } = useViewportContext();\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [measuredWidth, setMeasuredWidth] = useState<number | null>(null);\n\n useResizeObserver(\n wrapperRef,\n entry => {\n setMeasuredWidth(entry.contentRect.width);\n },\n { enabled: responsive }\n );\n\n const wrapperStyle = useMemo(\n () => placementToStyle(placement, margin),\n [placement, margin]\n );\n\n const effectiveWidth = responsive\n ? (measuredWidth ?? widthProp ?? 200)\n : widthProp;\n\n const userOnNavigateRef = useLatest(userOnNavigate);\n const handleNavigate = useCallback(\n (info: MinimapNavigateInfo): void => {\n handle.centerOn(info.worldPoint);\n userOnNavigateRef.current?.(info);\n },\n [handle, userOnNavigateRef]\n );\n\n return (\n <div ref={wrapperRef} style={wrapperStyle}>\n <Minimap\n {...minimapProps}\n ref={ref}\n transform={transform}\n viewportSize={size}\n width={effectiveWidth}\n onNavigate={handleNavigate}\n />\n </div>\n );\n};\n\nViewportMinimap.displayName = 'ViewportMinimap';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAyDA;AAIE;AACE;;AAEF;AACE;AACA;;AAEF;AAAiC;;AAC5B;AACL;AAAgC;;AAC3B;AACL;AACF;AAEA;;;;;;;;;AASG;AACI;;AAUL;;AAGA;AAGI;AACF;;;AAUA;;AAGF;AACA;AAEI;AACA;AACF;AAIF;AAYF;AAEA;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computeBoundsFromItems.js","sources":["
|
|
1
|
+
{"version":3,"file":"computeBoundsFromItems.js","sources":["src/components/editor/Minimap/computeBoundsFromItems.ts"],"sourcesContent":["import type { MinimapItem } from './Minimap.types';\nimport type { WorldRect } from '@/components/primitives/viewport';\n\n/**\n * Compute the tight axis-aligned bounding box of a set of minimap items,\n * with optional uniform padding (in world units) on every side.\n *\n * An empty input returns a zero-area rect at the origin so the minimap\n * can still render a meaningful surface.\n */\nexport function computeBoundsFromItems(\n items: ReadonlyArray<MinimapItem>,\n padding: number = 0\n): WorldRect {\n if (items.length === 0) {\n return { x: 0, y: 0, width: 0, height: 0 };\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const item of items) {\n let l = 0;\n let t = 0;\n let r = 0;\n let b = 0;\n switch (item.type) {\n case 'rect':\n l = item.x;\n t = item.y;\n r = item.x + item.width;\n b = item.y + item.height;\n break;\n case 'circle':\n l = item.cx - item.r;\n t = item.cy - item.r;\n r = item.cx + item.r;\n b = item.cy + item.r;\n break;\n case 'line':\n l = Math.min(item.x1, item.x2);\n t = Math.min(item.y1, item.y2);\n r = Math.max(item.x1, item.x2);\n b = Math.max(item.y1, item.y2);\n break;\n case 'custom':\n l = item.bounds.x;\n t = item.bounds.y;\n r = item.bounds.x + item.bounds.width;\n b = item.bounds.y + item.bounds.height;\n break;\n }\n if (l < minX) minX = l;\n if (t < minY) minY = t;\n if (r > maxX) maxX = r;\n if (b > maxY) maxY = b;\n }\n\n return {\n x: minX - padding,\n y: minY - padding,\n width: maxX - minX + 2 * padding,\n height: maxY - minY + 2 * padding,\n };\n}\n"],"names":[],"mappings":"AAGA;;;;;;AAMG;SACa,sBAAsB,CACpC,KAAiC,EACjC,UAAkB,CAAC,EAAA;AAEnB,IAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AACtB,QAAA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IAC5C;IAEA,IAAI,IAAI,GAAG,QAAQ;IACnB,IAAI,IAAI,GAAG,QAAQ;AACnB,IAAA,IAAI,IAAI,GAAG,CAAC,QAAQ;AACpB,IAAA,IAAI,IAAI,GAAG,CAAC,QAAQ;AAEpB,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,IAAI,CAAC,GAAG,CAAC;QACT,IAAI,CAAC,GAAG,CAAC;QACT,IAAI,CAAC,GAAG,CAAC;QACT,IAAI,CAAC,GAAG,CAAC;AACT,QAAA,QAAQ,IAAI,CAAC,IAAI;AACf,YAAA,KAAK,MAAM;AACT,gBAAA,CAAC,GAAG,IAAI,CAAC,CAAC;AACV,gBAAA,CAAC,GAAG,IAAI,CAAC,CAAC;gBACV,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK;gBACvB,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM;gBACxB;AACF,YAAA,KAAK,QAAQ;gBACX,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;gBACpB,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;gBACpB,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;gBACpB,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;gBACpB;AACF,YAAA,KAAK,MAAM;AACT,gBAAA,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;AAC9B,gBAAA,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;AAC9B,gBAAA,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;AAC9B,gBAAA,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC9B;AACF,YAAA,KAAK,QAAQ;AACX,gBAAA,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AACjB,gBAAA,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;AACjB,gBAAA,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK;AACrC,gBAAA,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;gBACtC;;QAEJ,IAAI,CAAC,GAAG,IAAI;YAAE,IAAI,GAAG,CAAC;QACtB,IAAI,CAAC,GAAG,IAAI;YAAE,IAAI,GAAG,CAAC;QACtB,IAAI,CAAC,GAAG,IAAI;YAAE,IAAI,GAAG,CAAC;QACtB,IAAI,CAAC,GAAG,IAAI;YAAE,IAAI,GAAG,CAAC;IACxB;IAEA,OAAO;QACL,CAAC,EAAE,IAAI,GAAG,OAAO;QACjB,CAAC,EAAE,IAAI,GAAG,OAAO;AACjB,QAAA,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO;AAChC,QAAA,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO;KAClC;AACH;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["
|
|
1
|
+
{"version":3,"file":"index.js","sources":["src/components/editor/Minimap/index.ts"],"sourcesContent":["import { Minimap as MinimapBase } from './Minimap';\nimport { MinimapCorner } from './MinimapCorner';\nimport { MinimapFooter } from './MinimapFooter';\nimport { MinimapTitle } from './MinimapTitle';\n\ntype MinimapCompound = typeof MinimapBase & {\n Title: typeof MinimapTitle;\n Footer: typeof MinimapFooter;\n Corner: typeof MinimapCorner;\n};\n\nconst MinimapWithSlots = MinimapBase as MinimapCompound;\nMinimapWithSlots.Title = MinimapTitle;\nMinimapWithSlots.Footer = MinimapFooter;\nMinimapWithSlots.Corner = MinimapCorner;\n\nexport const Minimap = MinimapWithSlots;\nexport { MinimapTitle, MinimapFooter, MinimapCorner };\nexport { ViewportMinimap } from './ViewportMinimap';\nexport { computeBoundsFromItems } from './computeBoundsFromItems';\nexport {\n useMinimapContext,\n useMinimapHover,\n useMinimapGeometry,\n useMinimapDragState,\n} from './MinimapContext';\nexport { MINIMAP_SLOT } from './Minimap.types';\n\nexport type {\n MinimapProps,\n MinimapItem,\n MinimapRectItem,\n MinimapCircleItem,\n MinimapLineItem,\n MinimapCustomItem,\n MinimapNavigateInfo,\n MinimapNavigatePhase,\n MinimapInteractionConfig,\n MinimapDrawInfo,\n MinimapContextValue,\n MinimapHandle,\n MinimapSlotKind,\n MinimapSlotMarker,\n MinimapTitleProps,\n MinimapFooterProps,\n MinimapCornerProps,\n MinimapTitlePlacement,\n MinimapFooterPlacement,\n MinimapCornerSide,\n} from './Minimap.types';\nexport type { MinimapGeometryState, MinimapHoverState } from './MinimapStore';\nexport type {\n ViewportMinimapProps,\n ViewportMinimapPlacement,\n} from './ViewportMinimap';\n"],"names":["MinimapBase"],"mappings":";;;;;;;AAWA,MAAM,gBAAgB,GAAGA,SAA8B;AACvD,gBAAgB,CAAC,KAAK,GAAG,YAAY;AACrC,gBAAgB,CAAC,MAAM,GAAG,aAAa;AACvC,gBAAgB,CAAC,MAAM,GAAG,aAAa;AAEhC,MAAM,OAAO,GAAG;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minimapCoords.js","sources":["
|
|
1
|
+
{"version":3,"file":"minimapCoords.js","sources":["src/components/editor/Minimap/minimapCoords.ts"],"sourcesContent":["import type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type {\n ViewportTransform,\n ViewportSize,\n WorldRect,\n} from '@/components/primitives/viewport';\n\n/** Axis-aligned rectangle in minimap (CSS-pixel) coordinates. */\nexport interface MinimapScreenRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Derive minimap height from a width + `worldBounds` aspect ratio,\n * clamped to `[minHeight, maxHeight]`.\n *\n * When `worldBounds` is zero-area, falls back to `minHeight` (the minimap\n * still renders a usable surface so users see the viewport rect).\n */\nexport function computeMinimapHeight(\n width: number,\n worldBounds: WorldRect,\n minHeight: number,\n maxHeight: number\n): number {\n if (worldBounds.width <= 0 || worldBounds.height <= 0) {\n return minHeight;\n }\n const ratio = worldBounds.height / worldBounds.width;\n const raw = width * ratio;\n return Math.min(maxHeight, Math.max(minHeight, raw));\n}\n\n/**\n * Uniform scale that fits `worldBounds` inside `minimapSize`, preserving\n * the world aspect ratio. If the minimap was clamped (e.g. height hit\n * `maxHeight`), the resulting content is letterboxed.\n */\nexport function computeMinimapScale(\n worldBounds: WorldRect,\n minimapSize: ViewportSize\n): number {\n if (worldBounds.width <= 0 || worldBounds.height <= 0) {\n return 1;\n }\n return Math.min(\n minimapSize.width / worldBounds.width,\n minimapSize.height / worldBounds.height\n );\n}\n\n/** Letterbox offset (each side) when world and minimap aspect ratios differ. */\nexport function computeMinimapOffset(\n worldBounds: WorldRect,\n minimapSize: ViewportSize,\n scale: number\n): Point2D {\n const usedW = worldBounds.width * scale;\n const usedH = worldBounds.height * scale;\n return {\n x: (minimapSize.width - usedW) / 2,\n y: (minimapSize.height - usedH) / 2,\n };\n}\n\n/** Map a world point to minimap CSS pixel coordinates. */\nexport function worldToMinimap(\n point: Point2D,\n worldBounds: WorldRect,\n minimapSize: ViewportSize\n): Point2D {\n const scale = computeMinimapScale(worldBounds, minimapSize);\n const offset = computeMinimapOffset(worldBounds, minimapSize, scale);\n return {\n x: offset.x + (point.x - worldBounds.x) * scale,\n y: offset.y + (point.y - worldBounds.y) * scale,\n };\n}\n\n/** Inverse of `worldToMinimap`: minimap CSS point → world point. */\nexport function minimapToWorld(\n point: Point2D,\n worldBounds: WorldRect,\n minimapSize: ViewportSize\n): Point2D {\n // Zero-area bounds have no meaningful inverse mapping — collapse everything\n // to the bounds origin so navigation still emits a stable point.\n if (worldBounds.width <= 0 || worldBounds.height <= 0) {\n return { x: worldBounds.x, y: worldBounds.y };\n }\n const scale = computeMinimapScale(worldBounds, minimapSize);\n const offset = computeMinimapOffset(worldBounds, minimapSize, scale);\n return {\n x: worldBounds.x + (point.x - offset.x) / scale,\n y: worldBounds.y + (point.y - offset.y) / scale,\n };\n}\n\n/**\n * Viewport rect (in minimap CSS px) for a given main-viewport transform\n * and size. The world-space region visible in the main viewport is at\n * `(-tx / zoom, -ty / zoom)` with size `viewportSize / zoom`.\n */\nexport function getViewportRectOnMinimap(\n transform: ViewportTransform,\n viewportSize: ViewportSize,\n worldBounds: WorldRect,\n minimapSize: ViewportSize\n): MinimapScreenRect {\n const scale = computeMinimapScale(worldBounds, minimapSize);\n const offset = computeMinimapOffset(worldBounds, minimapSize, scale);\n const zoom = transform.zoom === 0 ? 1 : transform.zoom;\n\n const worldX = -transform.x / zoom;\n const worldY = -transform.y / zoom;\n const worldW = viewportSize.width / zoom;\n const worldH = viewportSize.height / zoom;\n\n return {\n x: offset.x + (worldX - worldBounds.x) * scale,\n y: offset.y + (worldY - worldBounds.y) * scale,\n width: worldW * scale,\n height: worldH * scale,\n };\n}\n\n/** Current world-space center of the main viewport. */\nexport function getViewportCenterWorld(\n transform: ViewportTransform,\n viewportSize: ViewportSize\n): Point2D {\n const zoom = transform.zoom === 0 ? 1 : transform.zoom;\n return {\n x: (-transform.x + viewportSize.width / 2) / zoom,\n y: (-transform.y + viewportSize.height / 2) / zoom,\n };\n}\n\n/**\n * Build the shared coordinate helpers used by built-in drawing,\n * `renderOverlay`, and custom items. `transform`/`viewportSize` are not\n * needed by the helpers themselves but are passed downstream alongside\n * this bundle to form the public `MinimapDrawInfo`.\n */\nexport function buildDrawInfo(\n worldBounds: WorldRect,\n minimapSize: ViewportSize\n): {\n scale: number;\n offset: Point2D;\n worldToMinimap: (point: Point2D) => Point2D;\n minimapToWorld: (point: Point2D) => Point2D;\n} {\n const scale = computeMinimapScale(worldBounds, minimapSize);\n const offset = computeMinimapOffset(worldBounds, minimapSize, scale);\n return {\n scale,\n offset,\n worldToMinimap: (p: Point2D) => worldToMinimap(p, worldBounds, minimapSize),\n minimapToWorld: (p: Point2D) => minimapToWorld(p, worldBounds, minimapSize),\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minimapDrawing.js","sources":["
|
|
1
|
+
{"version":3,"file":"minimapDrawing.js","sources":["src/components/editor/Minimap/minimapDrawing.ts"],"sourcesContent":["import { buildDrawInfo, getViewportRectOnMinimap } from './minimapCoords';\n\nimport type { MinimapDrawInfo, MinimapItem } from './Minimap.types';\nimport type { MinimapScreenRect } from './minimapCoords';\nimport type {\n ViewportTransform,\n ViewportSize,\n WorldRect,\n} from '@/components/primitives/viewport';\n\nexport interface MinimapDrawColors {\n background: string;\n defaultItem: string;\n viewportRectStroke: string;\n outsideOverlay: string;\n}\n\nexport interface MinimapDrawInput {\n ctx: CanvasRenderingContext2D;\n size: ViewportSize;\n worldBounds: WorldRect;\n transform: ViewportTransform;\n viewportSize: ViewportSize;\n items: ReadonlyArray<MinimapItem>;\n colors: MinimapDrawColors;\n renderOverlay?: (\n ctx: CanvasRenderingContext2D,\n info: MinimapDrawInfo\n ) => void;\n}\n\n/**\n * Render a full minimap frame: background → items → caller `renderOverlay`\n * → dimmed shroud around the viewport rect → viewport rect outline. The\n * caller is responsible for DPR scaling on `ctx` before invoking.\n */\nexport function drawMinimap(input: MinimapDrawInput): void {\n const {\n ctx,\n size,\n worldBounds,\n transform,\n viewportSize,\n items,\n colors,\n renderOverlay,\n } = input;\n\n ctx.clearRect(0, 0, size.width, size.height);\n ctx.fillStyle = colors.background;\n ctx.fillRect(0, 0, size.width, size.height);\n\n const helpers = buildDrawInfo(worldBounds, size);\n const info: MinimapDrawInfo = {\n minimapSize: size,\n worldBounds,\n transform,\n viewportSize,\n ...helpers,\n };\n\n ctx.save();\n ctx.beginPath();\n ctx.rect(0, 0, size.width, size.height);\n ctx.clip();\n\n for (const item of items) {\n const color = item.color ?? colors.defaultItem;\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n\n switch (item.type) {\n case 'rect': {\n const topLeft = info.worldToMinimap({ x: item.x, y: item.y });\n ctx.fillRect(\n topLeft.x,\n topLeft.y,\n Math.max(1, item.width * info.scale),\n Math.max(1, item.height * info.scale)\n );\n break;\n }\n case 'circle': {\n const center = info.worldToMinimap({ x: item.cx, y: item.cy });\n const r = Math.max(0.5, item.r * info.scale);\n ctx.beginPath();\n ctx.arc(center.x, center.y, r, 0, Math.PI * 2);\n ctx.fill();\n break;\n }\n case 'line': {\n const a = info.worldToMinimap({ x: item.x1, y: item.y1 });\n const b = info.worldToMinimap({ x: item.x2, y: item.y2 });\n ctx.lineWidth = item.lineWidth ?? 1;\n ctx.beginPath();\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n ctx.stroke();\n break;\n }\n case 'custom': {\n ctx.save();\n item.draw(ctx, info);\n ctx.restore();\n break;\n }\n }\n }\n\n if (renderOverlay) {\n ctx.save();\n renderOverlay(ctx, info);\n ctx.restore();\n }\n\n ctx.restore();\n\n const vr = getViewportRectOnMinimap(\n transform,\n viewportSize,\n worldBounds,\n size\n );\n drawOutsideOverlay(ctx, size, vr, colors.outsideOverlay);\n\n ctx.strokeStyle = colors.viewportRectStroke;\n ctx.lineWidth = 1;\n const strokeW = Math.max(0, vr.width - 1);\n const strokeH = Math.max(0, vr.height - 1);\n ctx.strokeRect(vr.x + 0.5, vr.y + 0.5, strokeW, strokeH);\n}\n\nfunction drawOutsideOverlay(\n ctx: CanvasRenderingContext2D,\n size: ViewportSize,\n rect: MinimapScreenRect,\n color: string\n): void {\n const rl = Math.max(0, Math.min(size.width, rect.x));\n const rt = Math.max(0, Math.min(size.height, rect.y));\n const rr = Math.max(0, Math.min(size.width, rect.x + rect.width));\n const rb = Math.max(0, Math.min(size.height, rect.y + rect.height));\n\n ctx.fillStyle = color;\n if (rt > 0) ctx.fillRect(0, 0, size.width, rt);\n if (rb < size.height) ctx.fillRect(0, rb, size.width, size.height - rb);\n if (rl > 0 && rt < rb) ctx.fillRect(0, rt, rl, rb - rt);\n if (rr < size.width && rt < rb) {\n ctx.fillRect(rr, rt, size.width - rr, rb - rt);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"minimapHitTest.js","sources":["
|
|
1
|
+
{"version":3,"file":"minimapHitTest.js","sources":["src/components/editor/Minimap/minimapHitTest.ts"],"sourcesContent":["import type { MinimapItem } from './Minimap.types';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type { WorldRect } from '@/components/primitives/viewport';\n\n/** Distance from point P to line segment A-B (in world units). */\nfunction distancePointToSegment(p: Point2D, a: Point2D, b: Point2D): number {\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const lenSq = dx * dx + dy * dy;\n if (lenSq === 0) {\n const ex = p.x - a.x;\n const ey = p.y - a.y;\n return Math.hypot(ex, ey);\n }\n let t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / lenSq;\n t = Math.max(0, Math.min(1, t));\n const cx = a.x + t * dx;\n const cy = a.y + t * dy;\n return Math.hypot(p.x - cx, p.y - cy);\n}\n\n/**\n * Hit-test a world point against the item list, returning the topmost\n * (last-drawn) match. `lineToleranceWorld` is the picking radius (world\n * units) used for line items.\n */\nexport function hitTestItems(\n worldPoint: Point2D,\n items: ReadonlyArray<MinimapItem>,\n lineToleranceWorld: number\n): string | null {\n for (let i = items.length - 1; i >= 0; i -= 1) {\n const item = items[i];\n if (!item) continue;\n if (pointHitsItem(worldPoint, item, lineToleranceWorld)) {\n return item.id;\n }\n }\n return null;\n}\n\nfunction pointHitsItem(\n p: Point2D,\n item: MinimapItem,\n lineToleranceWorld: number\n): boolean {\n switch (item.type) {\n case 'rect':\n return (\n p.x >= item.x &&\n p.x <= item.x + item.width &&\n p.y >= item.y &&\n p.y <= item.y + item.height\n );\n case 'circle': {\n const dx = p.x - item.cx;\n const dy = p.y - item.cy;\n return dx * dx + dy * dy <= item.r * item.r;\n }\n case 'line':\n return (\n distancePointToSegment(\n p,\n { x: item.x1, y: item.y1 },\n { x: item.x2, y: item.y2 }\n ) <= lineToleranceWorld\n );\n case 'custom':\n return inWorldRect(p, item.bounds);\n }\n}\n\nfunction inWorldRect(p: Point2D, rect: WorldRect): boolean {\n return (\n p.x >= rect.x &&\n p.x <= rect.x + rect.width &&\n p.y >= rect.y &&\n p.y <= rect.y + rect.height\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -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":"useMinimapGestures.js","sources":["../../../../../../src/components/editor/Minimap/useMinimapGestures.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;AA2BA;AACA;AACA;AAqCA;AAIE;;AACA;;AAEF;AAEA;AAIE;AAGF;AAEA;;;;;;;;;;AAUG;AACG;AAGJ;;;;;;;;;;;AAaA;AAEA;AAEI;AACF;AAIF;;AAGM;;;AAGF;AACA;AACA;;;;AAMA;AACA;;AAEE;;AAED;;AAKL;;;AAGI;AACA;;;AAGA;AACA;AACA;AACA;AACA;AAEA;;;AASA;AAEA;;;;AAIE;AACE;AACA;;;AAEG;;;;;AAIA;;;;;;;AAOP;;;;AAKE;;;AAIF;;AAEE;;;AAEK;AACL;;;;AAIJ;;;;;;;;;;AAWC;AAGH;AAEI;AACA;;;;;AAKA;AACA;;AAEA;AACA;AACA;;;AAIA;AAEA;AACE;;AACA;AACE;AACA;;;;;;AAKA;;;;AAKJ;;AAEA;;;;;;;AAQA;AACA;AACE;AACE;AACA;AACD;AACD;AACD;AACH;;;;;;;;AASC;AAGH;;AACwB;;AAExB;;AAII;AACA;;AACA;;AAEE;;;AAIA;AACA;;AAEA;AACE;;;AAMK;;;;AAGA;;AAEL;AACA;AACE;AACE;AACA;AACD;AACD;AACD;;;AAIL;AACA;AACF;AAIF;AAEI;AACF;AAIF;AAEI;AACF;AAIF;;;;;AAKI;AACE;;;AAGA;;;AAGA;;;AAGA;;;AAGA;;;;AAKF;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACE;AACE;AACA;AACD;AACD;AACD;AACH;AAIF;AAEI;AACA;AACA;AACA;AACA;AACA;AACD;;;;;;;AAQA;;AAIL;;"}
|
|
1
|
+
{"version":3,"file":"useMinimapGestures.js","sources":["src/components/editor/Minimap/useMinimapGestures.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useRef } from 'react';\n\nimport { useLatest } from '@/hooks';\n\nimport {\n getViewportCenterWorld,\n getViewportRectOnMinimap,\n minimapToWorld,\n} from './minimapCoords';\nimport { hitTestItems } from './minimapHitTest';\n\nimport type {\n MinimapInteractionConfig,\n MinimapItem,\n MinimapNavigateInfo,\n} from './Minimap.types';\nimport type { MinimapStore } from './MinimapStore';\nimport type { Point2D } from '@/components/primitives/canvas/canvas.types';\nimport type {\n ViewportSize,\n ViewportTransform,\n WorldRect,\n} from '@/components/primitives/viewport';\nimport type React from 'react';\n\nconst CLICK_THRESHOLD_PX = 3;\n/** Hover line-picking tolerance, in minimap CSS px. Translated to world units per gesture. */\nconst LINE_HIT_TOLERANCE_MINIMAP_PX = 4;\n\ninterface UseMinimapGesturesOptions {\n containerRef: React.RefObject<HTMLDivElement | null>;\n store: MinimapStore;\n worldBounds: WorldRect;\n transform: ViewportTransform;\n viewportSize: ViewportSize;\n minimapSize: ViewportSize;\n items: ReadonlyArray<MinimapItem>;\n interactions: Required<MinimapInteractionConfig>;\n keyboardPanStep: number;\n disabled: boolean;\n onNavigate: ((info: MinimapNavigateInfo) => void) | undefined;\n}\n\ntype GestureMode = 'pending-click' | 'drag-rect' | 'drag-pan' | 'cancelled';\n\ninterface PointerState {\n pointerId: number;\n mode: GestureMode;\n startScreen: Point2D;\n /** Drag-rect only: world-space offset from viewport center at drag-start. */\n grabOffsetWorld?: Point2D;\n}\n\ninterface UseMinimapGesturesReturn {\n handlers: {\n onPointerDown: (e: React.PointerEvent<HTMLDivElement>) => void;\n onPointerMove: (e: React.PointerEvent<HTMLDivElement>) => void;\n onPointerUp: (e: React.PointerEvent<HTMLDivElement>) => void;\n onPointerCancel: (e: React.PointerEvent<HTMLDivElement>) => void;\n onPointerLeave: (e: React.PointerEvent<HTMLDivElement>) => void;\n onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => void;\n };\n}\n\nfunction getLocalPointerPosition(\n e: React.PointerEvent<HTMLDivElement>,\n container: HTMLDivElement | null\n): Point2D {\n if (!container) return { x: 0, y: 0 };\n const rect = container.getBoundingClientRect();\n return { x: e.clientX - rect.left, y: e.clientY - rect.top };\n}\n\nfunction pointInRect(\n p: Point2D,\n r: { x: number; y: number; width: number; height: number }\n): boolean {\n return (\n p.x >= r.x && p.x <= r.x + r.width && p.y >= r.y && p.y <= r.y + r.height\n );\n}\n\n/**\n * Pointer + keyboard gesture machine for `<Minimap>`. All live props and\n * the `onNavigate` callback are read through `useLatest` refs so the\n * returned handlers are stable for the lifetime of the component —\n * pointer event listeners never re-attach on prop changes.\n *\n * Hover state and drag state are written directly to the `MinimapStore`,\n * not local React state, so slice subscribers (`useMinimapHover`,\n * `useMinimapDragState`) re-render independently and don't see the rest\n * of the world thrash.\n */\nexport function useMinimapGestures(\n opts: UseMinimapGesturesOptions\n): UseMinimapGesturesReturn {\n const { containerRef, store } = opts;\n\n // Live refs — handlers always see the latest values without re-binding.\n const worldBoundsRef = useLatest(opts.worldBounds);\n const transformRef = useLatest(opts.transform);\n const viewportSizeRef = useLatest(opts.viewportSize);\n const minimapSizeRef = useLatest(opts.minimapSize);\n const itemsRef = useLatest(opts.items);\n const interactionsRef = useLatest(opts.interactions);\n const keyboardPanStepRef = useLatest(opts.keyboardPanStep);\n const disabledRef = useLatest(opts.disabled);\n const onNavigateRef = useLatest(opts.onNavigate);\n\n const stateRef = useRef<PointerState | null>(null);\n\n const emit = useCallback(\n (info: MinimapNavigateInfo): void => {\n onNavigateRef.current?.(info);\n },\n [onNavigateRef]\n );\n\n const updateHover = useCallback(\n (screen: Point2D | null): void => {\n if (!screen) {\n store.setHover({ hoverWorldPoint: null, hoveredItemId: null });\n return;\n }\n const worldBounds = worldBoundsRef.current;\n const minimapSize = minimapSizeRef.current;\n const items = itemsRef.current;\n const worldPoint = minimapToWorld(screen, worldBounds, minimapSize);\n const scaleX =\n worldBounds.width > 0 ? minimapSize.width / worldBounds.width : 1;\n const scaleY =\n worldBounds.height > 0 ? minimapSize.height / worldBounds.height : 1;\n const scale = Math.min(scaleX, scaleY) || 1;\n const tolerance = LINE_HIT_TOLERANCE_MINIMAP_PX / scale;\n store.setHover({\n hoverWorldPoint: worldPoint,\n hoveredItemId: hitTestItems(worldPoint, items, tolerance),\n });\n },\n [store, worldBoundsRef, minimapSizeRef, itemsRef]\n );\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent<HTMLDivElement>): void => {\n if (disabledRef.current || e.button !== 0) return;\n const container = containerRef.current;\n if (!container) return;\n\n const screen = getLocalPointerPosition(e, container);\n const worldBounds = worldBoundsRef.current;\n const minimapSize = minimapSizeRef.current;\n const transform = transformRef.current;\n const viewportSize = viewportSizeRef.current;\n const interactions = interactionsRef.current;\n\n const viewportRect = getViewportRectOnMinimap(\n transform,\n viewportSize,\n worldBounds,\n minimapSize\n );\n const inside = pointInRect(screen, viewportRect);\n\n let mode: GestureMode | null = null;\n let grabOffsetWorld: Point2D | undefined;\n\n if (inside && interactions.dragViewportRect) {\n mode = 'drag-rect';\n const pointerWorld = minimapToWorld(screen, worldBounds, minimapSize);\n const center = getViewportCenterWorld(transform, viewportSize);\n grabOffsetWorld = {\n x: pointerWorld.x - center.x,\n y: pointerWorld.y - center.y,\n };\n } else if (!inside && interactions.click) {\n // Tap-vs-drag is resolved on pointermove / pointerup.\n // dragFromEmpty (if enabled) takes over after the click threshold.\n mode = 'pending-click';\n } else if (!inside && interactions.dragFromEmpty) {\n mode = 'drag-pan';\n } else {\n return;\n }\n\n e.preventDefault();\n container.setPointerCapture(e.pointerId);\n\n stateRef.current = {\n pointerId: e.pointerId,\n mode,\n startScreen: screen,\n grabOffsetWorld,\n };\n\n if (mode === 'drag-pan') {\n const worldPoint = minimapToWorld(screen, worldBounds, minimapSize);\n store.setIsDragging(true);\n emit({ worldPoint, phase: 'drag-start' });\n } else if (mode === 'drag-rect') {\n store.setIsDragging(true);\n const center = getViewportCenterWorld(transform, viewportSize);\n emit({ worldPoint: center, phase: 'drag-start' });\n }\n },\n [\n containerRef,\n disabledRef,\n interactionsRef,\n transformRef,\n viewportSizeRef,\n worldBoundsRef,\n minimapSizeRef,\n store,\n emit,\n ]\n );\n\n const handlePointerMove = useCallback(\n (e: React.PointerEvent<HTMLDivElement>): void => {\n const container = containerRef.current;\n if (!container) return;\n const screen = getLocalPointerPosition(e, container);\n // Always update hover state — independent of gesture capture.\n updateHover(screen);\n\n const state = stateRef.current;\n if (state?.pointerId !== e.pointerId) return;\n\n const worldBounds = worldBoundsRef.current;\n const minimapSize = minimapSizeRef.current;\n const interactions = interactionsRef.current;\n\n const dx = screen.x - state.startScreen.x;\n const dy = screen.y - state.startScreen.y;\n const moved = Math.hypot(dx, dy) >= CLICK_THRESHOLD_PX;\n\n if (state.mode === 'pending-click') {\n if (!moved) return;\n if (interactions.dragFromEmpty) {\n state.mode = 'drag-pan';\n store.setIsDragging(true);\n const worldPoint = minimapToWorld(screen, worldBounds, minimapSize);\n emit({ worldPoint, phase: 'drag-start' });\n } else {\n // Threshold exceeded but drag-from-empty is disabled — cancel the click.\n state.mode = 'cancelled';\n }\n return;\n }\n\n if (state.mode === 'cancelled') return;\n\n if (state.mode === 'drag-pan') {\n const worldPoint = minimapToWorld(screen, worldBounds, minimapSize);\n emit({ worldPoint, phase: 'drag' });\n return;\n }\n\n // Only 'drag-rect' remains after the early returns above.\n const pointerWorld = minimapToWorld(screen, worldBounds, minimapSize);\n const offset = state.grabOffsetWorld ?? { x: 0, y: 0 };\n emit({\n worldPoint: {\n x: pointerWorld.x - offset.x,\n y: pointerWorld.y - offset.y,\n },\n phase: 'drag',\n });\n },\n [\n containerRef,\n worldBoundsRef,\n minimapSizeRef,\n interactionsRef,\n store,\n emit,\n updateHover,\n ]\n );\n\n const handlePointerLeave = useCallback((): void => {\n if (stateRef.current) return; // keep hover during drag (pointer capture)\n updateHover(null);\n }, [updateHover]);\n\n const endGesture = useCallback(\n (e: React.PointerEvent<HTMLDivElement>, cancelled: boolean): void => {\n const state = stateRef.current;\n if (state?.pointerId !== e.pointerId) return;\n const container = containerRef.current;\n if (container?.hasPointerCapture(e.pointerId)) {\n container.releasePointerCapture(e.pointerId);\n }\n\n if (!cancelled) {\n const worldBounds = worldBoundsRef.current;\n const minimapSize = minimapSizeRef.current;\n const screen = getLocalPointerPosition(e, container);\n if (state.mode === 'pending-click') {\n const worldPoint = minimapToWorld(\n state.startScreen,\n worldBounds,\n minimapSize\n );\n emit({ worldPoint, phase: 'click' });\n } else if (state.mode === 'drag-pan') {\n const worldPoint = minimapToWorld(screen, worldBounds, minimapSize);\n emit({ worldPoint, phase: 'drag-end' });\n } else if (state.mode === 'drag-rect') {\n const pointerWorld = minimapToWorld(screen, worldBounds, minimapSize);\n const offset = state.grabOffsetWorld ?? { x: 0, y: 0 };\n emit({\n worldPoint: {\n x: pointerWorld.x - offset.x,\n y: pointerWorld.y - offset.y,\n },\n phase: 'drag-end',\n });\n }\n }\n\n stateRef.current = null;\n store.setIsDragging(false);\n },\n [containerRef, worldBoundsRef, minimapSizeRef, store, emit]\n );\n\n const handlePointerUp = useCallback(\n (e: React.PointerEvent<HTMLDivElement>): void => {\n endGesture(e, false);\n },\n [endGesture]\n );\n\n const handlePointerCancel = useCallback(\n (e: React.PointerEvent<HTMLDivElement>): void => {\n endGesture(e, true);\n },\n [endGesture]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>): void => {\n if (disabledRef.current) return;\n let dx = 0;\n let dy = 0;\n switch (e.key) {\n case 'ArrowLeft':\n dx = -1;\n break;\n case 'ArrowRight':\n dx = 1;\n break;\n case 'ArrowUp':\n dy = -1;\n break;\n case 'ArrowDown':\n dy = 1;\n break;\n default:\n return;\n }\n e.preventDefault();\n\n const transform = transformRef.current;\n const viewportSize = viewportSizeRef.current;\n const keyboardPanStep = keyboardPanStepRef.current;\n\n const zoom = transform.zoom === 0 ? 1 : transform.zoom;\n const worldViewW = viewportSize.width / zoom;\n const worldViewH = viewportSize.height / zoom;\n const stepMul = e.shiftKey ? 5 : 1;\n const stepW = worldViewW * keyboardPanStep * stepMul;\n const stepH = worldViewH * keyboardPanStep * stepMul;\n\n const currentCenter = getViewportCenterWorld(transform, viewportSize);\n emit({\n worldPoint: {\n x: currentCenter.x + dx * stepW,\n y: currentCenter.y + dy * stepH,\n },\n phase: 'click',\n });\n },\n [disabledRef, transformRef, viewportSizeRef, keyboardPanStepRef, emit]\n );\n\n const handlers = useMemo(\n () => ({\n onPointerDown: handlePointerDown,\n onPointerMove: handlePointerMove,\n onPointerUp: handlePointerUp,\n onPointerCancel: handlePointerCancel,\n onPointerLeave: handlePointerLeave,\n onKeyDown: handleKeyDown,\n }),\n [\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n handlePointerCancel,\n handlePointerLeave,\n handleKeyDown,\n ]\n );\n\n return { handlers };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AA2BA;AACA;AACA;AAqCA;AAIE;;AACA;;AAEF;AAEA;AAIE;AAGF;AAEA;;;;;;;;;;AAUG;AACG;AAGJ;;;;;;;;;;;AAaA;AAEA;AAEI;AACF;AAIF;;AAGM;;;AAGF;AACA;AACA;;;;AAMA;AACA;;AAEE;;AAED;;AAKL;;;AAGI;AACA;;;AAGA;AACA;AACA;AACA;AACA;AAEA;;;AASA;AAEA;;;;AAIE;AACE;AACA;;;AAEG;;;;;AAIA;;;;;;;AAOP;;;;AAKE;;;AAIF;;AAEE;;;AAEK;AACL;;;;AAIJ;;;;;;;;;;AAWC;AAGH;AAEI;AACA;;;;;AAKA;AACA;;AAEA;AACA;AACA;;;AAIA;AAEA;AACE;;AACA;AACE;AACA;;;;;;AAKA;;;;AAKJ;;AAEA;;;;;;;AAQA;AACA;AACE;AACE;AACA;AACD;AACD;AACD;AACH;;;;;;;;AASC;AAGH;;AACwB;;AAExB;;AAII;AACA;;AACA;;AAEE;;;AAIA;AACA;;AAEA;AACE;;;AAMK;;;;AAGA;;AAEL;AACA;AACE;AACE;AACA;AACD;AACD;AACD;;;AAIL;AACA;AACF;AAIF;AAEI;AACF;AAIF;AAEI;AACF;AAIF;;;;;AAKI;AACE;;;AAGA;;;AAGA;;;AAGA;;;AAGA;;;;AAKF;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACE;AACE;AACA;AACD;AACD;AACD;AACH;AAIF;AAEI;AACA;AACA;AACA;AACA;AACA;AACD;;;;;;;AAQA;;AAIL;;"}
|
|
@@ -11,7 +11,7 @@ import { useControlledState } from '../../../hooks/useControlledState/useControl
|
|
|
11
11
|
import { useLatest } from '../../../hooks/useLatest/useLatest.js';
|
|
12
12
|
import '../../../hooks/useBreakpoint/useBreakpoint.js';
|
|
13
13
|
import './../../../assets/src/theme/lightTheme.css.ts.vanilla-Ct6f9Iym.css';
|
|
14
|
-
import '
|
|
14
|
+
import '@vanilla-extract/css';
|
|
15
15
|
import './../../../assets/src/theme/darkTheme.css.ts.vanilla-BHZ3ecRn.css';
|
|
16
16
|
import './../../../assets/src/theme/globalScrollbars.css.ts.vanilla-BAJwnUEJ.css';
|
|
17
17
|
import '../../../hooks/useNavigationHistory/useNavigationHistory.js';
|