import { type ReactNode } from "react"; import { FolderOpen } from "lucide-react"; import { FileTree, type FileEntry } from "~/client/components/file-tree"; import { ScrollArea } from "~/client/components/ui/scroll-area"; import { cn } from "~/client/lib/utils"; type PaginationState = { hasMore: boolean; isLoadingMore: boolean; }; export type FileBrowserUiProps = { className?: string; treeContainerClassName?: string; treeClassName?: string; useScrollArea?: boolean; scrollAreaClassName?: string; stateClassName?: string; loadingMessage?: string; emptyMessage?: string; emptyDescription?: string; emptyIcon?: ReactNode; withCheckboxes?: boolean; selectedPaths?: Set; onSelectionChange?: (paths: Set) => void; foldersOnly?: boolean; selectableFolders?: boolean; onFolderSelect?: (folderPath: string) => void; selectedFolder?: string; onFileSelect?: (filePath: string) => void; selectedFile?: string; showSelectedPathFooter?: boolean; selectedPath?: string; selectedPathLabel?: string; }; type FileBrowserProps = FileBrowserUiProps & { isLoading: boolean; isEmpty: boolean; errorMessage?: string; fileArray: FileEntry[]; expandedFolders: Set; loadingFolders: Set; onFolderExpand: (folderPath: string) => void | Promise; onFolderHover: (folderPath: string) => void; onLoadMore: (folderPath: string) => void | Promise; getFolderPagination: (folderPath: string) => PaginationState; }; export const FileBrowser = (props: FileBrowserProps) => { const { className, treeContainerClassName, treeClassName, useScrollArea = false, scrollAreaClassName, stateClassName, loadingMessage = "Loading files...", emptyMessage = "No files found.", emptyDescription, emptyIcon, withCheckboxes = false, selectedPaths, onSelectionChange, foldersOnly = false, selectableFolders = false, onFolderSelect, selectedFolder, onFileSelect, selectedFile, showSelectedPathFooter = false, selectedPath, selectedPathLabel = "Selected path:", isLoading, isEmpty, errorMessage, fileArray, expandedFolders, loadingFolders, onFolderExpand, onFolderHover, onLoadMore, getFolderPagination, } = props; const resolvedSelectedPath = selectedPath ?? selectedFolder; const resolvedEmptyIcon = emptyIcon === undefined ? : emptyIcon; let body: ReactNode; if (isLoading) { body = (

{loadingMessage}

); } else if (errorMessage) { body = (

{errorMessage}

); } else if (isEmpty) { body = (
{resolvedEmptyIcon}

{emptyMessage}

{emptyDescription &&

{emptyDescription}

}
); } else { body = ( ); } const bodyWithScroll = useScrollArea ? {body} : body; return (
{bodyWithScroll}
{showSelectedPathFooter && resolvedSelectedPath && (
{selectedPathLabel}
{resolvedSelectedPath}
)}
); };