### Install MarkdownViewer Package Source: https://github.com/yasintz/md-viewer/blob/main/README.md Installs the MarkdownViewer package using npm. This is the first step to integrate the component into your React project. ```bash npm install @yt/md-viewer ``` -------------------------------- ### React MarkdownViewer Usage Example Source: https://github.com/yasintz/md-viewer/blob/main/src/README.md Demonstrates how to integrate the MarkdownViewer component into a React application. It shows setting up state for comments and passing necessary props for file tree, markdown content, and comment management callbacks. ```tsx import { MarkdownViewer } from './modules/MarkdownViewer'; import type { FileTreeNode, Comment, CommentReply } from './modules/MarkdownViewer'; import { useState } from 'react'; function App() { const [comments, setComments] = useState([]); const folderTree: FileTreeNode[] = [ { name: 'example.md', path: 'example.md', type: 'file', }, ]; const handleCommentAdd = (comment: Comment) => { setComments([...comments, comment]); }; const handleCommentDelete = (id: string) => { setComments(comments.filter((c) => c.id !== id)); }; const handleCommentUpdate = (id: string, text: string) => { setComments( comments.map((c) => (c.id === id ? { ...c, text } : c)) ); }; const handleCommentReply = (commentId: string, reply: CommentReply) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: [...(c.replies || []), reply] } : c ) ); }; return ( ); } ``` -------------------------------- ### Install Peer Dependencies for MarkdownViewer Source: https://github.com/yasintz/md-viewer/blob/main/README.md Installs the required peer dependencies for the MarkdownViewer component, such as React, ReactDOM, and various Radix UI components. These are essential for the component's functionality. ```bash npm install react react-dom @radix-ui/react-dialog @radix-ui/react-select @radix-ui/react-slot ``` -------------------------------- ### MarkdownViewer Component Usage in React with TypeScript Source: https://context7.com/yasintz/md-viewer/llms.txt Demonstrates how to use the MarkdownViewer component in a React application. It shows state management for comments, file selection, and handling various comment-related events. This example assumes you have the '@yt/md-viewer' library installed and its styles imported. ```tsx import { MarkdownViewer } from '@yt/md-viewer'; import '@yt/md-viewer/styles'; import { useState } from 'react'; import type { FileTreeNode, Comment, CommentReply } from '@yt/md-viewer'; function App() { const [comments, setComments] = useState([]); const [selectedFile, setSelectedFile] = useState('example.md'); const folderTree: FileTreeNode[] = [ { name: 'docs', path: 'docs', type: 'directory', children: [ { name: 'example.md', path: 'docs/example.md', type: 'file' }, { name: 'guide.md', path: 'docs/guide.md', type: 'file' } ] } ]; const markdownContent = `# Hello World This is **markdown** content with \`code\` and more. ## Features - Text selection - Comments with replies - Export functionality`; const handleCommentAdd = (comment: Comment) => { setComments([...comments, comment]); }; const handleCommentDelete = (id: string) => { setComments(comments.filter((c) => c.id !== id)); }; const handleCommentUpdate = (id: string, text: string) => { setComments( comments.map((c) => (c.id === id ? { ...c, text } : c)) ); }; const handleCommentReply = (commentId: string, reply: CommentReply) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: [...(c.replies || []), reply] } : c ) ); }; const handleReplyUpdate = (commentId: string, replyId: string, text: string) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: c.replies.map((r) => r.id === replyId ? { ...r, text } : r ) } : c ) ); }; const handleReplyDelete = (commentId: string, replyId: string) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: c.replies.filter((r) => r.id !== replyId) } : c ) ); }; const handleExportComments = (comments: Comment[]) => { const markdown = comments.map(c => `**${c.selectedText}** (Line ${c.line}): ${c.text}` ).join('\n\n'); console.log('Exported:', markdown); }; return ( ); } ``` -------------------------------- ### TypeScript Core Types and Usage Source: https://context7.com/yasintz/md-viewer/llms.txt Defines essential TypeScript interfaces for integrating with the Markdown Viewer component library, including FileTreeNode, Comment, CommentReply, and CommentHistory. It demonstrates example usage for state management and provides utility functions for type guarding and filtering comments. ```tsx import type { FileTreeNode, Comment, CommentReply, CommentHistory } from '@yt/md-viewer'; // Example usage with all types interface AppState { files: FileTreeNode[]; currentComments: Comment[]; history: CommentHistory[]; } const exampleState: AppState = { files: [ { name: 'README.md', path: 'README.md', type: 'file' }, { name: 'src', path: 'src', type: 'directory', children: [ { name: 'index.ts', path: 'src/index.ts', type: 'file' } ] } ], currentComments: [ { id: '1', text: 'Main comment text', selectedText: 'highlighted portion', line: 42, column: 8, timestamp: 1703001234567, replies: [ { id: '1-1', text: 'Reply text', timestamp: 1703001345678 } ] } ], history: [ { id: 'h1', fileName: 'README.md', filePath: 'README.md', comments: [], savedAt: 1703000000000 } ] }; // Type guard example function isDirectory(node: FileTreeNode): boolean { return node.type === 'directory' && !!node.children; } // Filter function example function getFileComments( comments: Comment[], line: number ): Comment[] { return comments.filter(c => c.line === line); } ``` -------------------------------- ### useComments Hook for Comment Management in React Source: https://context7.com/yasintz/md-viewer/llms.txt The `useComments` hook provides state management for comment editing, replying, and related UI interactions within a React application. It handles states for editing comments and replies, managing input text, and orchestrating actions like saving, canceling, and starting edits/replies. It requires an initial set of comments and optionally accepts functions for updating comments and replies. ```tsx import { useComments } from '@yt/md-viewer'; import type { Comment, CommentReply } from '@yt/md-viewer'; function CommentManager() { const [comments, setComments] = useState([ { id: '1', text: 'Initial comment', selectedText: 'highlighted text', line: 5, column: 10, timestamp: Date.now(), replies: [] } ]); const { editingCommentId, editingReplyId, editText, replyingToCommentId, replyText, setEditText, setReplyText, handleStartEdit, handleStartEditReply, handleSaveEdit, handleCancelEdit, handleStartReply, handleSaveReply, handleCancelReply } = useComments(); const updateComment = (id: string, text: string) => { setComments(comments.map(c => c.id === id ? { ...c, text } : c)); }; const updateReply = (commentId: string, replyId: string, text: string) => { setComments( comments.map(c => c.id === commentId ? { ...c, replies: c.replies.map(r => r.id === replyId ? { ...r, text } : r) } : c ) ); }; const addReply = (commentId: string, reply: CommentReply) => { setComments( comments.map(c => c.id === commentId ? { ...c, replies: [...c.replies, reply] } : c ) ); }; return (
{comments.map(comment => (
{editingCommentId === comment.id && !editingReplyId ? (
setEditText(e.target.value)} />
) : (

{comment.text}

)} {replyingToCommentId === comment.id && (
setReplyText(e.target.value)} placeholder="Write a reply..." />
)} {comment.replies.map(reply => (
{editingCommentId === comment.id && editingReplyId === reply.id ? (
setEditText(e.target.value)} />
) : (

{reply.text}

)}
))}
))}
); } ``` -------------------------------- ### Integrate MarkdownViewer Component in React Source: https://github.com/yasintz/md-viewer/blob/main/README.md Demonstrates how to use the MarkdownViewer component in a React application. It includes setting up state for comments, defining the folder tree, and handling comment-related callbacks. ```tsx import { MarkdownViewer } from '@yt/md-viewer'; import '@yt/md-viewer/styles'; // Import Tailwind styles import type { FileTreeNode, Comment, CommentReply } from '@yt/md-viewer'; import { useState } from 'react'; function App() { const [comments, setComments] = useState([]); const folderTree: FileTreeNode[] = [ { name: 'example.md', path: 'example.md', type: 'file', }, ]; const handleCommentAdd = (comment: Comment) => { setComments([...comments, comment]); }; const handleCommentDelete = (id: string) => { setComments(comments.filter((c) => c.id !== id)); }; const handleCommentUpdate = (id: string, text: string) => { setComments( comments.map((c) => (c.id === id ? { ...c, text } : c)) ); }; const handleCommentReply = (commentId: string, reply: CommentReply) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: [...(c.replies || []), reply] } : c ) ); }; return ( ); } ``` -------------------------------- ### Alternative MarkdownViewer Style Import Source: https://github.com/yasintz/md-viewer/blob/main/README.md Provides an alternative method to import MarkdownViewer styles directly from the CSS file. This can be useful if the main style import does not work as expected. ```tsx import '@yt/md-viewer/src/styles.css'; ``` -------------------------------- ### Import MarkdownViewer Styles Source: https://github.com/yasintz/md-viewer/blob/main/README.md Imports the necessary Tailwind CSS styles for the MarkdownViewer component. This should be done once in your application's entry point or main layout component. ```tsx import '@yt/md-viewer/styles'; ``` -------------------------------- ### MarkdownViewer Component API Source: https://context7.com/yasintz/md-viewer/llms.txt The main component for rendering markdown content with commenting capabilities, file navigation, and table of contents. ```APIDOC ## MarkdownViewer Component ### Description The main component for rendering markdown content with commenting capabilities, file navigation, and table of contents. ### Usage ```tsx import { MarkdownViewer } from '@yt/md-viewer'; import '@yt/md-viewer/styles'; import { useState } from 'react'; import type { FileTreeNode, Comment, CommentReply } from '@yt/md-viewer'; function App() { const [comments, setComments] = useState([]); const [selectedFile, setSelectedFile] = useState('example.md'); const folderTree: FileTreeNode[] = [ { name: 'docs', path: 'docs', type: 'directory', children: [ { name: 'example.md', path: 'docs/example.md', type: 'file' }, { name: 'guide.md', path: 'docs/guide.md', type: 'file' } ] } ]; const markdownContent = `# Hello World This is **markdown** content with `code` and more. ## Features - Text selection - Comments with replies - Export functionality`; const handleCommentAdd = (comment: Comment) => { setComments([...comments, comment]); }; const handleCommentDelete = (id: string) => { setComments(comments.filter((c) => c.id !== id)); }; const handleCommentUpdate = (id: string, text: string) => { setComments( comments.map((c) => (c.id === id ? { ...c, text } : c)) ); }; const handleCommentReply = (commentId: string, reply: CommentReply) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: [...(c.replies || []), reply] } : c ) ); }; const handleReplyUpdate = (commentId: string, replyId: string, text: string) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: c.replies.map((r) => r.id === replyId ? { ...r, text } : r ) } : c ) ); }; const handleReplyDelete = (commentId: string, replyId: string) => { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: c.replies.filter((r) => r.id !== replyId) } : c ) ); }; const handleExportComments = (comments: Comment[]) => { const markdown = comments.map(c => `**${c.selectedText}** (Line ${c.line}): ${c.text}` ).join('\n\n'); console.log('Exported:', markdown); }; return ( ); } ``` ### Props - **folderTree** (FileTreeNode[]) - Required - The file structure for navigation. - **markdownContent** (string) - Required - The markdown content to render. - **comments** (Comment[]) - Optional - An array of existing comments. - **onCommentAdd** ((comment: Comment) => void) - Optional - Callback when a new comment is added. - **onCommentDelete** ((id: string) => void) - Optional - Callback when a comment is deleted. - **onCommentUpdate** ((id: string, text: string) => void) - Optional - Callback when a comment is updated. - **onCommentReply** ((commentId: string, reply: CommentReply) => void) - Optional - Callback when a reply is added to a comment. - **onReplyUpdate** ((commentId: string, replyId: string, text: string) => void) - Optional - Callback when a reply is updated. - **onReplyDelete** ((commentId: string, replyId: string) => void) - Optional - Callback when a reply is deleted. - **selectedFilePath** (string | null) - Optional - The currently selected file path. - **onFileSelect** ((filePath: string) => void) - Optional - Callback when a file is selected. - **onExportComments** ((comments: Comment[]) => void) - Optional - Callback when comments are exported. ``` -------------------------------- ### Export Comments to Markdown with Clipboard and Download (TypeScript) Source: https://context7.com/yasintz/md-viewer/llms.txt Provides functions to generate markdown exports from comment data, copy the markdown to the clipboard, and trigger a download of the markdown file. It relies on the '@yt/md-viewer' library and accepts an array of 'Comment' objects as input. The output is markdown-formatted text, which can be directly used or downloaded. ```tsx import { generateMarkdownExport, copyMarkdownToClipboard, downloadMarkdown } from '@yt/md-viewer'; import type { Comment } from '@yt/md-viewer'; function ExportExample() { const comments: Comment[] = [ { id: '1', text: 'Great explanation!', selectedText: 'This is important', line: 10, column: 5, timestamp: Date.now(), replies: [ { id: '2', text: 'I agree', timestamp: Date.now() } ] }, { id: '3', text: 'Needs clarification', selectedText: 'confusing part', line: 25, column: 15, timestamp: Date.now(), replies: [] } ]; const handleExportToClipboard = async () => { const markdown = generateMarkdownExport(comments); try { await copyMarkdownToClipboard(markdown); // Alert shown by function: "Markdown copied to clipboard!" } catch (error) { console.error('Failed to copy:', error); } }; const handleDownload = () => { const markdown = generateMarkdownExport(comments); downloadMarkdown(markdown); // Downloads file: markdown-review-{timestamp}.md }; const handleCustomExport = () => { const markdown = generateMarkdownExport(comments); console.log(markdown); /* Output: # Comments ## Comment 1 **Selected Text:** > This is important **Position:** Line 10, Column 5 **Comment:** Great explanation! I agree --- ## Comment 2 **Selected Text:** > confusing part **Position:** Line 25, Column 15 **Comment:** Needs clarification --- */ }; return (
); } ``` -------------------------------- ### Highlight Comments in HTML with Position Awareness (TypeScript) Source: https://context7.com/yasintz/md-viewer/llms.txt This function highlights commented text within rendered HTML content, enabling position-aware highlighting. It takes HTML content (converted from markdown) and an array of 'Comment' objects as input. The output is HTML with specific sections marked for commenting, allowing interactive comment handling. ```tsx import { highlightCommentsInHtml } from '@yt/md-viewer'; import type { Comment } from '@yt/md-viewer'; import { marked } from 'marked'; function HighlightedPreview() { const markdownContent = `# Documentation This is an important section that needs review. Another paragraph with relevant information.`; const comments: Comment[] = [ { id: 'c1', text: 'Please review this', selectedText: 'important section', line: 3, column: 12, timestamp: Date.now(), replies: [] }, { id: 'c2', text: 'Update this info', selectedText: 'relevant information', line: 5, column: 20, timestamp: Date.now(), replies: [] } ]; // Convert markdown to HTML const htmlContent = marked.parse(markdownContent) as string; // Apply comment highlights const highlightedHtml = highlightCommentsInHtml(htmlContent, comments); const handleCommentClick = (commentId: string) => { console.log('Clicked comment:', commentId); // Scroll to comment in sidebar or show details }; return (
{ const target = e.target as HTMLElement; if (target.classList.contains('comment-highlight')) { const commentId = target.getAttribute('data-comment-id'); if (commentId) handleCommentClick(commentId); } }} />
); } ``` -------------------------------- ### Comment Interface Definition Source: https://github.com/yasintz/md-viewer/blob/main/src/README.md Defines the structure for a single comment. Includes text, selection details, line/column anchoring, timestamp, and nested replies. ```typescript interface Comment { id: string; text: string; selectedText: string; line: number; column: number; timestamp: number; replies: CommentReply[]; } ``` -------------------------------- ### Use Text Selection Hook with React TSX Source: https://context7.com/yasintz/md-viewer/llms.txt Demonstrates the implementation of the `useTextSelection` hook in a React component using TypeScript. This hook helps manage text selection events, track selected text, and determine its position within the source markdown. It requires the `markdownContent` as input and accepts a callback function to handle the selection details. ```tsx import { useTextSelection } from '@yt/md-viewer'; function CustomViewer() { const markdownContent = `# Document\n\nSample text for selection.`; const handleSelection = (text: string, position: { line: number; column: number }) => { console.log(`Selected "${text}" at line ${position.line}, col ${position.column}`); }; const { previewRef, commentIconPosition, selectedText, selectionPosition, handleTextSelection, handleCommentIconClick, clearSelection } = useTextSelection(handleSelection, markdownContent); return (

Select text to see position data.

{markdownContent}

{commentIconPosition && ( )} {selectedText && (

Selected: {selectedText}

Position: Line {selectionPosition?.line}, Column {selectionPosition?.column}

)}
); } ``` -------------------------------- ### FileTreeNode Interface Definition Source: https://github.com/yasintz/md-viewer/blob/main/src/README.md Defines the structure for representing nodes in the file tree. Each node can be a file or a directory and may contain child nodes. ```typescript interface FileTreeNode { name: string; path: string; type: 'file' | 'directory'; children?: FileTreeNode[]; } ``` -------------------------------- ### CommentReply Interface Definition Source: https://github.com/yasintz/md-viewer/blob/main/src/README.md Defines the structure for a reply to a comment. Includes a unique ID, the reply text, and a timestamp. ```typescript interface CommentReply { id: string; text: string; timestamp: number; } ``` -------------------------------- ### Define FileTreeNode Type Source: https://github.com/yasintz/md-viewer/blob/main/README.md Defines the TypeScript interface for a file tree node, used to represent files and directories within the navigation structure. It includes name, path, type, and optional children. ```typescript interface FileTreeNode { name: string; path: string; type: 'file' | 'directory'; children?: FileTreeNode[]; } ``` -------------------------------- ### Define CommentReply Type Source: https://github.com/yasintz/md-viewer/blob/main/README.md Defines the TypeScript interface for a reply to a comment, containing its ID, text content, and timestamp. ```typescript interface CommentReply { id: string; text: string; timestamp: number; } ``` -------------------------------- ### Define Comment Type Source: https://github.com/yasintz/md-viewer/blob/main/README.md Defines the TypeScript interface for a comment, including its unique ID, text content, the selected text it refers to, line and column number, timestamp, and associated replies. ```typescript interface Comment { id: string; text: string; selectedText: string; line: number; column: number; timestamp: number; replies: CommentReply[]; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.