Skip to content

Commit f61299b

Browse files
committed
fix: legend positioning, smooth 60fps animations, improved Tests button UX
1 parent 61816bb commit f61299b

4 files changed

Lines changed: 75 additions & 9 deletions

File tree

frontend/src/components/DependencyGraph/DirectoryNode.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ function DirectoryNodeComponent({ data }: NodeProps<DirectoryNodeData>) {
4545

4646
<div
4747
className={cn(
48-
'px-3 py-2.5 rounded-lg border-2 transition-all duration-200 min-w-[180px]',
49-
'hover:scale-[1.02] hover:shadow-md cursor-pointer',
48+
'px-3 py-2.5 rounded-lg border-2 min-w-[180px]',
49+
'transition-all duration-200 ease-out',
50+
'hover:scale-[1.02] hover:shadow-md active:scale-[0.98]',
51+
'cursor-pointer select-none',
5052
stateStyle
5153
)}
5254
>
@@ -59,7 +61,7 @@ function DirectoryNodeComponent({ data }: NodeProps<DirectoryNodeData>) {
5961
{data.label}/
6062
</span>
6163
<ChevronRight className={cn(
62-
'w-3.5 h-3.5 text-zinc-400 transition-transform',
64+
'w-3.5 h-3.5 text-zinc-400 transition-transform duration-200 ease-out',
6365
data.isExpanded && 'rotate-90'
6466
)} />
6567
</div>

frontend/src/components/DependencyGraph/GraphToolbar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ function GraphToolbarComponent({
6363
</Button>
6464

6565
<Button
66-
variant="secondary"
66+
variant={showTests ? 'secondary' : 'outline'}
6767
size="sm"
6868
onClick={onToggleTests}
69-
className={cn('h-8', !showTests && 'opacity-60')}
69+
className={cn('h-8', !showTests && 'opacity-70 line-through')}
70+
title={showTests ? 'Click to hide test files' : 'Click to show test files'}
7071
>
7172
{showTests ? <Eye className="w-3.5 h-3.5 mr-1.5" /> : <EyeOff className="w-3.5 h-3.5 mr-1.5" />}
7273
Tests

frontend/src/components/DependencyGraph/index.tsx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,15 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
133133
if (!showTests) {
134134
nodeIds = nodeIds.filter((id: string) => {
135135
const fileName = id.split('/').pop() || ''
136-
return !fileName.includes('.test.') && !fileName.includes('_test.') && !fileName.includes('.spec.')
136+
const pathLower = id.toLowerCase()
137+
// Filter out test files by filename pattern OR by being in tests/ directory
138+
const isTestFile = fileName.includes('.test.') ||
139+
fileName.includes('_test.') ||
140+
fileName.includes('.spec.') ||
141+
fileName.startsWith('test_') ||
142+
pathLower.includes('/tests/') ||
143+
pathLower.startsWith('tests/')
144+
return !isTestFile
137145
})
138146
}
139147

@@ -445,7 +453,7 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
445453
/>
446454

447455
<div className="flex overflow-hidden" style={{ height: '600px' }}>
448-
<div style={{ flex: 1, height: '600px' }}>
456+
<div className="relative" style={{ flex: 1, height: '600px' }}>
449457
<ReactFlow
450458
nodes={nodes}
451459
edges={edges}
@@ -458,6 +466,17 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
458466
minZoom={0.1}
459467
maxZoom={2}
460468
defaultEdgeOptions={{ type: 'smoothstep' }}
469+
proOptions={{ hideAttribution: true }}
470+
panOnScroll
471+
selectionOnDrag
472+
panOnDrag={[1, 2]}
473+
zoomOnScroll
474+
zoomOnPinch
475+
zoomOnDoubleClick
476+
nodesDraggable={false}
477+
nodesConnectable={false}
478+
elementsSelectable
479+
snapToGrid={false}
461480
>
462481
<Background color={isDark ? '#27272a' : '#d4d4d8'} gap={20} size={1} />
463482
<Controls
@@ -466,8 +485,8 @@ function DependencyGraphInner({ repoId, apiUrl, apiKey }: DependencyGraphProps)
466485
/>
467486
</ReactFlow>
468487

469-
{/* Legend */}
470-
<Card className="absolute bottom-4 left-4 bg-white/90 dark:bg-zinc-900/90 backdrop-blur-sm">
488+
{/* Legend - positioned bottom-right to avoid Controls overlap */}
489+
<Card className="absolute bottom-4 right-4 bg-white/90 dark:bg-zinc-900/90 backdrop-blur-sm z-10 min-w-[180px]">
471490
<CardContent className="px-4 py-3 text-xs">
472491
<div className="font-medium text-zinc-700 dark:text-zinc-300 mb-2">Legend</div>
473492
<div className="space-y-1.5">

frontend/src/index.css

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,3 +508,47 @@ html {
508508
.scrollbar-thin::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: var(--radius-full); }
509509
.scrollbar-thin::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); }
510510
}
511+
512+
/* ReactFlow smooth animations - 60fps optimized */
513+
.react-flow {
514+
--rf-node-transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
515+
}
516+
517+
.react-flow__node {
518+
transition: transform 0.15s ease-out, opacity 0.15s ease-out, filter 0.15s ease-out;
519+
will-change: transform;
520+
}
521+
522+
.react-flow__node:hover {
523+
filter: brightness(1.05);
524+
}
525+
526+
.react-flow__edge path {
527+
transition: stroke 0.15s ease-out, stroke-width 0.15s ease-out, opacity 0.15s ease-out;
528+
}
529+
530+
.react-flow__viewport {
531+
transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
532+
will-change: transform;
533+
}
534+
535+
.react-flow__pane {
536+
cursor: grab;
537+
}
538+
539+
.react-flow__pane:active {
540+
cursor: grabbing;
541+
}
542+
543+
/* Smooth zoom controls */
544+
.react-flow__controls {
545+
transition: opacity 0.2s ease-out;
546+
}
547+
548+
.react-flow__controls button {
549+
transition: background-color 0.15s ease-out, transform 0.1s ease-out;
550+
}
551+
552+
.react-flow__controls button:active {
553+
transform: scale(0.95);
554+
}

0 commit comments

Comments
 (0)