import type { MouseEvent, ReactNode } from "react"; import { FileCode2 } from "lucide-react"; import { useLocation } from "@/lib/router"; import { cn } from "@/lib/utils"; import type { ParsedWorkspaceFileRef } from "@/lib/workspace-file-parser"; import { formatWorkspaceFileRefDisplay } from "@/lib/workspace-file-parser"; import { useFileViewer, writeFileViewerStateToSearch, } from "@/context/FileViewerContext"; export interface WorkspaceFileLinkProps { workspaceFileRef: ParsedWorkspaceFileRef; /** Override the rendered label. Defaults to `path:line:col`. */ label?: ReactNode; className?: string; /** Optional override if the consumer wants to customize activation. */ onOpen?: (ref: ParsedWorkspaceFileRef) => void; showIcon?: boolean; title?: string; } export function WorkspaceFileLink({ workspaceFileRef, label, className, onOpen, showIcon = true, title, }: WorkspaceFileLinkProps) { const viewer = useFileViewer(); const location = useLocation(); const display = typeof label !== "undefined" ? label : formatWorkspaceFileRefDisplay(workspaceFileRef); const canOpen = !!(onOpen || viewer); const lineSuffix = workspaceFileRef.line ? ` line ${workspaceFileRef.line}${workspaceFileRef.column ? ` column ${workspaceFileRef.column}` : ""}` : ""; const ariaLabel = canOpen ? `Open ${workspaceFileRef.path}${lineSuffix} in the file viewer` : `Workspace file ${workspaceFileRef.path}${lineSuffix}`; const tooltip = title ?? (canOpen ? `Open ${workspaceFileRef.path}${lineSuffix} in the file viewer` : `Workspace file ${workspaceFileRef.path}${lineSuffix}`); const deepLinkSearch = writeFileViewerStateToSearch(location.search, { path: workspaceFileRef.path, line: workspaceFileRef.line ?? null, column: workspaceFileRef.column ?? null, workspace: "auto", }); const href = canOpen ? `${location.pathname}${deepLinkSearch}${location.hash}` : "#"; const handleClick = (event: MouseEvent) => { if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { return; } if (event.button !== 0) return; if (!canOpen) return; event.preventDefault(); if (onOpen) onOpen(workspaceFileRef); else viewer?.open(workspaceFileRef); }; return ( {showIcon ? ); }