|
3 | 3 | // ======================================== |
4 | 4 | // Displays DeepWiki documentation content with table of contents |
5 | 5 |
|
6 | | -import { useMemo, useState } from 'react'; |
| 6 | +import { useMemo, useState, useCallback } from 'react'; |
7 | 7 | import { useIntl } from 'react-intl'; |
8 | 8 | import { FileText, Hash, Clock, Sparkles, AlertCircle, Link2, Check } from 'lucide-react'; |
9 | 9 | import { Card } from '@/components/ui/Card'; |
10 | 10 | import { Badge } from '@/components/ui/Badge'; |
11 | | -import { Button } from '@/components/ui/Button'; |
12 | 11 | import { cn } from '@/lib/utils'; |
13 | 12 | import type { DeepWikiSymbol, DeepWikiDoc } from '@/hooks/useDeepWiki'; |
14 | 13 |
|
@@ -276,20 +275,41 @@ export function DocumentViewer({ |
276 | 275 | </h4> |
277 | 276 | <nav className="space-y-1"> |
278 | 277 | {symbols.map(symbol => ( |
279 | | - <a |
| 278 | + <div |
280 | 279 | key={symbol.name} |
281 | | - href={`#${symbol.anchor.replace('#', '')}`} |
282 | | - className={cn( |
283 | | - 'block text-xs py-1.5 px-2 rounded transition-colors', |
284 | | - 'text-muted-foreground hover:text-foreground hover:bg-muted/50', |
285 | | - 'font-mono' |
286 | | - )} |
| 280 | + className="group flex items-center gap-1" |
287 | 281 | > |
288 | | - <span className={cn('mr-1', getSymbolTypeColor(symbol.type))}> |
289 | | - {getSymbolTypeIcon(symbol.type)} |
290 | | - </span> |
291 | | - {symbol.name} |
292 | | - </a> |
| 282 | + <a |
| 283 | + href={`#${symbol.anchor.replace('#', '')}`} |
| 284 | + className={cn( |
| 285 | + 'flex-1 text-xs py-1.5 px-2 rounded transition-colors', |
| 286 | + 'text-muted-foreground hover:text-foreground hover:bg-muted/50', |
| 287 | + 'font-mono' |
| 288 | + )} |
| 289 | + > |
| 290 | + <span className={cn('mr-1', getSymbolTypeColor(symbol.type))}> |
| 291 | + {getSymbolTypeIcon(symbol.type)} |
| 292 | + </span> |
| 293 | + {symbol.name} |
| 294 | + </a> |
| 295 | + <button |
| 296 | + onClick={() => copyDeepLink(symbol.name, symbol.anchor)} |
| 297 | + className={cn( |
| 298 | + 'opacity-0 group-hover:opacity-100 p-1 rounded transition-all', |
| 299 | + 'hover:bg-muted/50', |
| 300 | + copiedSymbol === symbol.name |
| 301 | + ? 'text-green-500' |
| 302 | + : 'text-muted-foreground hover:text-foreground' |
| 303 | + )} |
| 304 | + title={copiedSymbol === symbol.name ? 'Copied!' : 'Copy deep link'} |
| 305 | + > |
| 306 | + {copiedSymbol === symbol.name ? ( |
| 307 | + <Check className="w-3 h-3" /> |
| 308 | + ) : ( |
| 309 | + <Link2 className="w-3 h-3" /> |
| 310 | + )} |
| 311 | + </button> |
| 312 | + </div> |
293 | 313 | ))} |
294 | 314 | </nav> |
295 | 315 | </div> |
|
0 commit comments