From dd481e0c7d362f47e94cada560927960faaa3b91 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 10 May 2026 11:54:37 +0200 Subject: [PATCH] feat(documents): FolderBreadcrumb header crumb trail Renders the current folder's path as a clickable breadcrumb with a Home affordance back to "All documents". Each ancestor is clickable to navigate up; the last segment is the current folder (non-clickable, foreground colour). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../documents/folder-breadcrumb.tsx | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/components/documents/folder-breadcrumb.tsx diff --git a/src/components/documents/folder-breadcrumb.tsx b/src/components/documents/folder-breadcrumb.tsx new file mode 100644 index 00000000..dd7acd3b --- /dev/null +++ b/src/components/documents/folder-breadcrumb.tsx @@ -0,0 +1,73 @@ +'use client'; + +import { ChevronRight, Home } from 'lucide-react'; + +import { useDocumentFolders, type FolderNode } from '@/hooks/use-document-folders'; + +interface FolderBreadcrumbProps { + selectedFolderId: string | null | undefined; + onSelect: (folderId: string | null | undefined) => void; +} + +function findPath(tree: FolderNode[], id: string): FolderNode[] | null { + for (const node of tree) { + if (node.id === id) return [node]; + const inChild = findPath(node.children, id); + if (inChild) return [node, ...inChild]; + } + return null; +} + +export function FolderBreadcrumb({ selectedFolderId, onSelect }: FolderBreadcrumbProps) { + const { data: tree = [] } = useDocumentFolders(); + + let label: string; + let path: FolderNode[] = []; + if (selectedFolderId === undefined) { + label = 'All documents'; + } else if (selectedFolderId === null) { + label = 'Root'; + } else { + path = findPath(tree, selectedFolderId) ?? []; + label = path.at(-1)?.name ?? 'Folder'; + } + + return ( + + ); +}