aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVidya Rupak <[email protected]>2025-12-21 21:40:35 -0700
committerVidya Rupak <[email protected]>2025-12-21 21:40:35 -0700
commit696f5bbffa6aa0cff0dbb1d5afd8963ca72372b1 (patch)
treef7c20a9fabc88befb2781accdd0614ee06b0e014
parentadded popover cards for doc and memory to open next to the selected node. (diff)
downloadsupermemory-696f5bbffa6aa0cff0dbb1d5afd8963ca72372b1.tar.xz
supermemory-696f5bbffa6aa0cff0dbb1d5afd8963ca72372b1.zip
updated changelog and refactored popover logic to eliminate unnecessary calculations during smooth pan/zoom animations
-rw-r--r--packages/memory-graph/CHANGELOG.md14
-rw-r--r--packages/memory-graph/src/components/memory-graph.tsx97
2 files changed, 65 insertions, 46 deletions
diff --git a/packages/memory-graph/CHANGELOG.md b/packages/memory-graph/CHANGELOG.md
index c6bee6cf..20ed454a 100644
--- a/packages/memory-graph/CHANGELOG.md
+++ b/packages/memory-graph/CHANGELOG.md
@@ -2,6 +2,20 @@
## Visual & Layout Improvements (2025-12-21)
+### Smart Positioning Node Popover
+**Feature:** Clicking nodes now shows a floating popover with detailed information, positioned near the node with smart viewport edge detection.
+
+**Implementation:**
+- DOM-based popover
+- Auto-positions to avoid viewport edges
+- Click-outside to close
+- Shows all node metadata: title, summary (2-line truncation), type, memory count, URL, creation date, and ID
+- For memories: includes space, expiration date (if applicable), and forgotten status
+
+**Files Changed:**
+- `src/components/node-popover.tsx` - New popover component
+- `src/components/memory-graph.tsx` - Smart positioning logic
+
### Document Type Icons on Cards
**Feature:** Document cards now display type-specific icons centered on the card for better visual identification.
diff --git a/packages/memory-graph/src/components/memory-graph.tsx b/packages/memory-graph/src/components/memory-graph.tsx
index f4194396..98340f4e 100644
--- a/packages/memory-graph/src/components/memory-graph.tsx
+++ b/packages/memory-graph/src/components/memory-graph.tsx
@@ -405,6 +405,49 @@ export const MemoryGraph = ({
return nodes.find((n) => n.id === selectedNode) || null
}, [selectedNode, nodes])
+ // Calculate popover position (memoized for performance)
+ const popoverPosition = useMemo(() => {
+ if (!selectedNodeData) return null
+
+ // Calculate screen position of the node
+ const screenX = selectedNodeData.x * zoom + panX
+ const screenY = selectedNodeData.y * zoom + panY
+
+ // Popover dimensions (estimated)
+ const popoverWidth = 320
+ const popoverHeight = 400
+ const offset = 40
+ const padding = 16
+
+ // Smart positioning: flip to other side if would go off-screen
+ let popoverX = screenX + offset
+ let popoverY = screenY - 20
+
+ // Check right edge
+ if (popoverX + popoverWidth > containerSize.width - padding) {
+ // Flip to left side of node
+ popoverX = screenX - popoverWidth - offset
+ }
+
+ // Check left edge
+ if (popoverX < padding) {
+ popoverX = padding
+ }
+
+ // Check bottom edge
+ if (popoverY + popoverHeight > containerSize.height - padding) {
+ // Move up
+ popoverY = containerSize.height - popoverHeight - padding
+ }
+
+ // Check top edge
+ if (popoverY < padding) {
+ popoverY = padding
+ }
+
+ return { x: popoverX, y: popoverY }
+ }, [selectedNodeData, zoom, panX, containerSize.width, containerSize.height])
+
// Viewport-based loading: load more when most documents are visible (optional)
const checkAndLoadMore = useCallback(() => {
if (
@@ -532,52 +575,14 @@ export const MemoryGraph = ({
/>
{/* Node popover - positioned near clicked node */}
- {selectedNodeData && (() => {
- // Calculate screen position of the node
- const screenX = selectedNodeData.x * zoom + panX
- const screenY = selectedNodeData.y * zoom + panY
-
- // Popover dimensions (estimated)
- const popoverWidth = 300
- const popoverHeight = 200
- const offset = 40
- const padding = 16
-
- // Smart positioning: flip to other side if would go off-screen
- let popoverX = screenX + offset
- let popoverY = screenY - 20
-
- // Check right edge
- if (popoverX + popoverWidth > containerSize.width - padding) {
- // Flip to left side of node
- popoverX = screenX - popoverWidth - offset
- }
-
- // Check left edge
- if (popoverX < padding) {
- popoverX = padding
- }
-
- // Check bottom edge
- if (popoverY + popoverHeight > containerSize.height - padding) {
- // Move up
- popoverY = containerSize.height - popoverHeight - padding
- }
-
- // Check top edge
- if (popoverY < padding) {
- popoverY = padding
- }
-
- return (
- <NodePopover
- node={selectedNodeData}
- x={popoverX}
- y={popoverY}
- onClose={() => setSelectedNode(null)}
- />
- )
- })()}
+ {selectedNodeData && popoverPosition && (
+ <NodePopover
+ node={selectedNodeData}
+ x={popoverPosition.x}
+ y={popoverPosition.y}
+ onClose={() => setSelectedNode(null)}
+ />
+ )}
{/* Show welcome screen when no memories exist */}
{!isLoading &&