import React, { ReactNode } from 'react'; import * as Ariakit from '@ariakit/react'; import { ChevronDown, Paperclip } from 'lucide-react'; import { VisuallyHidden } from '@ariakit/react'; import { useLocalize } from '~/hooks'; import { cn } from '~/utils'; export interface SourceData { link: string; title?: string; attribution?: string; snippet?: string; } interface SourceHovercardProps { source: SourceData; label: string; onMouseEnter?: () => void; onMouseLeave?: () => void; onClick?: (e: React.MouseEvent) => void; isFile?: boolean; isLocalFile?: boolean; children?: ReactNode; } /** Helper to get domain favicon */ function getFaviconUrl(domain: string) { return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`; } /** Helper to get clean domain name */ export function getCleanDomain(url: string) { const domain = url.replace(/(^\w+:|^)\/\//, '').split('/')[0]; return domain.startsWith('www.') ? domain.substring(4) : domain; } export function FaviconImage({ domain, className = '' }: { domain: string; className?: string }) { return (
{domain}
); } export function SourceHovercard({ source, label, onMouseEnter, onMouseLeave, onClick, isFile = false, isLocalFile = false, children, }: SourceHovercardProps) { const localize = useLocalize(); const domain = getCleanDomain(source.link || ''); return ( {label} ) : ( {label} ) } /> {localize('com_citation_more_details', { label })} {children} {!children && ( <> {isFile ? (
) : ( )} {isFile ? ( ) : ( {source.attribution || domain} )}
{isFile ? ( <> {source.snippet && ( {source.snippet} )} ) : ( <>

{source.title || source.link}

{source.snippet && ( {source.snippet} )} )} )}
); }