UNPKG

@asafarim/markdown-explorer-viewer

Version:

A reusable React component for exploring and viewing markdown files with file tree navigation

123 lines (122 loc) 3.86 kB
import React, { ReactNode } from 'react'; export interface FileNode { name: string; path: string; type: 'file' | 'folder'; children?: FileNode[]; content?: string; lastModified?: string; size?: number; metadata?: Record<string, any>; } export interface FileTreeData { [path: string]: FileNode; } export interface MarkdownExplorerProps { /** Root path for the file tree or virtual file map */ rootPath?: string; /** Virtual file tree data (alternative to rootPath) */ fileTree?: FileNode; /** Theme preference */ theme?: 'light' | 'dark' | 'auto'; /** Custom CSS class name */ className?: string; /** Initial route to navigate to */ initialRoute?: string; /** Callback when navigation occurs */ onNavigate?: (path: string, node: FileNode) => void; /** Enable search functionality */ enableSearch?: boolean; /** Search placeholder text */ searchPlaceholder?: string; /** Show file icons */ showIcons?: boolean; /** Show file tree by default */ showFileTree?: boolean; /** Custom file icon renderer */ renderFileIcon?: (node: FileNode) => ReactNode; /** Custom folder icon renderer */ renderFolderIcon?: (node: FileNode) => ReactNode; /** Maximum width for the file tree sidebar */ sidebarWidth?: string; /** Enable breadcrumbs */ showBreadcrumbs?: boolean; /** Custom markdown components */ markdownComponents?: Record<string, React.ComponentType<any>>; /** Custom content fetcher for files that don't have content pre-loaded */ contentFetcher?: (filePath: string) => Promise<string>; /** Custom renderer for folder content */ renderFolderContent?: (props: { currentNode: FileNode; onNodeClick: (node: FileNode) => void; }) => ReactNode; /** Disable auto-selection of first file in folder */ disableAutoSelect?: boolean; } export interface FileTreeProps { /** File tree data */ fileTree: FileNode; /** Current selected path */ currentPath?: string; /** Theme */ theme?: 'light' | 'dark' | 'auto'; /** Click handler for files/folders */ onNodeClick: (node: FileNode) => void; /** Enable search */ enableSearch?: boolean; /** Search placeholder */ searchPlaceholder?: string; /** Show icons */ showIcons?: boolean; /** Custom file icon renderer */ renderFileIcon?: (node: FileNode) => ReactNode; /** Custom folder icon renderer */ renderFolderIcon?: (node: FileNode) => ReactNode; /** Custom class name */ className?: string; } export interface MarkdownViewerProps { /** Markdown content to render */ content: string; /** Theme */ theme?: 'light' | 'dark' | 'auto'; /** Custom class name */ className?: string; /** Custom markdown components */ components?: Record<string, React.ComponentType<any>>; /** File path for context */ filePath?: string; /** Frontmatter metadata */ metadata?: Record<string, any>; } export interface BreadcrumbsProps { /** Current path */ path: string; /** Root path */ rootPath?: string; /** Theme */ theme?: 'light' | 'dark' | 'auto'; /** Click handler for breadcrumb items */ onPathClick: (path: string) => void; /** Custom class name */ className?: string; } export interface SearchProps { /** Search query */ query: string; /** Search change handler */ onQueryChange: (query: string) => void; /** Placeholder text */ placeholder?: string; /** Theme */ theme?: 'light' | 'dark' | 'auto'; /** Custom class name */ className?: string; } export interface NavigationState { currentPath: string; currentNode: FileNode | null; history: string[]; historyIndex: number; } export type Theme = 'light' | 'dark' | 'auto';