Files
drive/apps/drive-web/src/directories/directory-path-breadcrumb.tsx

110 lines
2.6 KiB
TypeScript
Raw Normal View History

import type { Id } from "@fileone/convex/dataModel"
2025-10-03 23:23:05 +00:00
import type {
DirectoryHandle,
2025-10-05 15:01:55 +00:00
DirectoryPathComponent,
} from "@fileone/convex/filesystem"
2025-10-18 19:55:14 +00:00
import type { DirectoryInfo } from "@fileone/convex/types"
2025-10-03 23:23:05 +00:00
import { Link } from "@tanstack/react-router"
2025-10-18 19:55:14 +00:00
import type { PrimitiveAtom } from "jotai"
import { Fragment } from "react"
2025-10-03 23:23:05 +00:00
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
2025-10-18 19:55:14 +00:00
} from "@/components/ui/breadcrumb"
2025-10-03 23:23:05 +00:00
import {
Tooltip,
TooltipContent,
TooltipTrigger,
2025-10-18 19:55:14 +00:00
} from "@/components/ui/tooltip"
import type { FileDragInfo } from "@/files/use-file-drop"
import { useFileDrop } from "@/files/use-file-drop"
import { cn } from "@/lib/utils"
2025-10-03 23:23:05 +00:00
2025-10-18 19:55:14 +00:00
export function DirectoryPathBreadcrumb({
directory,
2025-10-05 15:01:55 +00:00
rootLabel,
directoryUrlFn,
2025-10-18 19:55:14 +00:00
fileDragInfoAtom,
2025-10-05 15:01:55 +00:00
}: {
2025-10-18 19:55:14 +00:00
directory: DirectoryInfo
2025-10-05 15:01:55 +00:00
rootLabel: string
directoryUrlFn: (directory: Id<"directories">) => string
2025-10-18 19:55:14 +00:00
fileDragInfoAtom: PrimitiveAtom<FileDragInfo | null>
2025-10-05 15:01:55 +00:00
}) {
2025-10-18 19:55:14 +00:00
const breadcrumbItems: React.ReactNode[] = [
<FilePathBreadcrumbItem
key={directory.path[0].handle.id}
component={directory.path[0]}
rootLabel={rootLabel}
directoryUrlFn={directoryUrlFn}
fileDragInfoAtom={fileDragInfoAtom}
/>,
]
2025-10-03 23:23:05 +00:00
for (let i = 1; i < directory.path.length - 1; i++) {
breadcrumbItems.push(
<Fragment key={directory.path[i]?.handle.id}>
<BreadcrumbSeparator />
<FilePathBreadcrumbItem
component={directory.path[i]!}
rootLabel={rootLabel}
2025-10-05 15:01:55 +00:00
directoryUrlFn={directoryUrlFn}
2025-10-18 19:55:14 +00:00
fileDragInfoAtom={fileDragInfoAtom}
/>
2025-10-03 23:23:05 +00:00
</Fragment>,
)
}
return (
<Breadcrumb>
<BreadcrumbList>
{breadcrumbItems}
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>{directory.name}</BreadcrumbPage>{" "}
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
)
}
function FilePathBreadcrumbItem({
component,
rootLabel,
2025-10-05 15:01:55 +00:00
directoryUrlFn,
2025-10-18 19:55:14 +00:00
fileDragInfoAtom,
}: {
2025-10-05 15:01:55 +00:00
component: DirectoryPathComponent
rootLabel: string
2025-10-05 15:01:55 +00:00
directoryUrlFn: (directory: Id<"directories">) => string
2025-10-18 19:55:14 +00:00
fileDragInfoAtom: PrimitiveAtom<FileDragInfo | null>
}) {
2025-10-03 23:23:05 +00:00
const { isDraggedOver, dropHandlers } = useFileDrop({
destItem: component.handle as DirectoryHandle,
2025-10-18 19:55:14 +00:00
dragInfoAtom: fileDragInfoAtom,
2025-10-03 23:23:05 +00:00
})
const dirName = component.name || rootLabel
2025-10-03 23:23:05 +00:00
return (
<Tooltip open={isDraggedOver}>
<TooltipTrigger asChild>
<BreadcrumbItem
className={cn({ "bg-muted": isDraggedOver })}
{...dropHandlers}
>
<BreadcrumbLink asChild>
2025-10-05 15:01:55 +00:00
<Link to={directoryUrlFn(component.handle.id)}>
2025-10-03 23:23:05 +00:00
{dirName}
</Link>
</BreadcrumbLink>
</BreadcrumbItem>
</TooltipTrigger>
<TooltipContent>Move to {dirName}</TooltipContent>
</Tooltip>
)
}