import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList } from "@/components/ui/breadcrumb"; import { type BreadcrumbItem as BreadcrumbItemType } from "@/hooks/useBreadcrumb"; import { AnimatePresence, motion, type Variants } from "framer-motion"; import { useNavigate, useSearch } from "@tanstack/react-router"; import { useBreadcrumbPath } from "@/hooks/useBreadcrumb"; import { pointerIntersection } from "@dnd-kit/collision"; import { SourceSelector } from "./source-selector"; import { useDroppable } from "@dnd-kit/react"; import { HomeIcon } from "lucide-react"; import { cn } from "@/lib/utils"; // Define animation variants for slide-in/slide-out const variants: Variants = { hidden: { opacity: 0, x: -10 }, // Starts hidden, slightly to the right visible: { opacity: 1, x: 0, transition: { type: "spring", // Use a spring animation for a natural feel stiffness: 250, damping: 30, }, }, exit: { opacity: 0, x: -20, transition: { ease: "easeInOut", duration: 0.2, // Faster exit }, }, }; export function FileBreadcrumb() { const searchParams = useSearch({ from: "/_protected/dashboard/$providerSlug/$accountId" }); const navigate = useNavigate({ from: "/dashboard/$providerSlug/$accountId" }); const currentFileId = searchParams.folderId || ""; const { data } = useBreadcrumbPath(currentFileId); // Handle clicking a folder navigation function handleFolderClick(id: string) { navigate({ search: { ...searchParams, folderId: id }, }); } // Handle clicking the home icon to remove folderId function handleHomeClick() { if (!searchParams.folderId) return; const { folderId, ...restSearchParams } = searchParams; navigate({ search: restSearchParams, }); } const { ref: droppableRef, isDropTarget } = useDroppable({ id: `droppable-root`, accept: "files", data: { id: "root" }, collisionDetector: pointerIntersection, }); return ( <>
{/* Source Dropdown */}
{/* Separator after home if there are breadcrumb items */} {data && data.length > 0 && ( / )} {/* Breadcrumb items */} {data?.map((item, index) => ( ))}
); } function FileBreadcrumbItem({ item, handleFolderClick, showSeparator, }: { item: BreadcrumbItemType; handleFolderClick: (id: string) => void; showSeparator: boolean; }) { const { ref: droppableRef, isDropTarget } = useDroppable({ id: `droppable-${item.id}`, accept: "files", data: { id: item.id }, collisionDetector: pointerIntersection, }); return (
{showSeparator ? ( ) : ( )} {showSeparator && ( / )}
); } type FileBreadcrumbItemProps = { isDropTarget?: boolean; item: BreadcrumbItemType; handleFolderClick: (id: string) => void; ref?: React.Ref; }; function FileBreadcrumbItemLink({ isDropTarget, item, handleFolderClick, ref }: FileBreadcrumbItemProps) { return ( handleFolderClick(item.id)} className="flex items-center gap-2 rounded-md p-1 text-nowrap" > {item.name} ); }