@xcelsior/ui-comments
v1.0.15
Published
A flexible and customizable comments system UI component for React applications.
Downloads
93
Readme
@excelsior/ui-comments
A flexible and customizable comments system UI component for React applications.
Features
- 🎨 Modern and responsive design
- 🌓 Dark mode support
- 📝 Markdown support for comments
- 🖼️ Image upload support with S3 integration
- 🔄 Nested replies support
- 👍 Reactions (likes/dislikes)
- ⚡ Real-time updates with React Query
- 📱 Mobile-friendly
- 🎭 Comprehensive Storybook documentation
- 🔧 Highly configurable
Installation
pnpm add @excelsior/ui-commentsUsage
Basic Example
import { Thread } from '@excelsior/ui-comments';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<Thread
apiKey="your-api-key"
apiUrl="https://api.example.com"
threadId="your-thread-id"
title="Article Title"
url="https://example.com/article"
settings={{
allowReplies: true,
maxDepth: 3,
}}
onThreadCreate={(thread) => console.log('Thread created:', thread)}
/>
</QueryClientProvider>
);
}Manual Thread Management
If you need more control over the thread creation process, you can use the Comments component directly:
import { Comments } from '@excelsior/ui-comments';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
const config = {
apiKey: 'your-api-key',
apiUrl: 'https://api.example.com',
threadId: 'your-thread-id',
settings: {
allowReplies: true,
maxDepth: 3,
},
};
return (
<QueryClientProvider client={queryClient}>
<Comments config={config} />
</QueryClientProvider>
);
}Configuration Options
The Comments component accepts a configuration object with the following properties:
interface CommentsConfig {
apiKey: string; // Your API key for authentication
apiUrl: string; // Base URL of your comments API
threadId: string; // Unique identifier for the comment thread
initialThread?: Thread; // Optional initial thread data
imageUpload?: { // Optional image upload configuration
uploadUrl: string; // URL endpoint for generating presigned upload URLs
maxFileSize?: number; // Maximum file size in bytes (default: 5MB)
allowedTypes?: string[]; // Allowed MIME types (default: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'])
headers?: Record<string, string>; // Additional headers for API requests
};
settings?: {
allowReplies: boolean; // Enable/disable reply functionality
maxDepth?: number; // Maximum nesting level for replies
};
onCommentCreate?: (comment: Comment) => void; // Callback when a comment is created
onCommentUpdate?: (comment: Comment) => void; // Callback when a comment is updated
onCommentDelete?: (commentId: string) => void; // Callback when a comment is deleted
onReactionAdd?: (commentId: string, type: 'like' | 'dislike') => void; // Callback when a reaction is added
}Image Upload Configuration
To enable image uploads in comments, configure the imageUpload option:
import { Comments } from '@excelsior/ui-comments';
function App() {
const config = {
apiKey: 'your-api-key',
apiUrl: 'https://api.example.com',
threadId: 'your-thread-id',
imageUpload: {
uploadUrl: 'https://api.example.com/api/images/upload-url', // Your presigned URL endpoint
maxFileSize: 5 * 1024 * 1024, // 5MB limit
allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
headers: {
'X-API-Key': 'your-api-key', // Include API key for authentication
},
},
settings: {
allowReplies: true,
},
};
return <Comments config={config} />;
}When image upload is configured, users will see an image upload button (🖼️) in the comment form. Clicking it allows them to select and upload images, which are automatically inserted as markdown in their comment.
Individual Components
You can also use the individual components for more granular control:
import { CommentItem, CommentForm, useComments } from '@excelsior/ui-comments';
function CustomComments() {
const { comments, createComment, deleteComment, addReaction } = useComments({
config: {
apiKey: 'your-api-key',
apiUrl: 'https://api.example.com',
threadId: 'your-thread-id',
},
});
return (
<div>
<CommentForm
onSubmit={createComment.mutate}
isLoading={createComment.isPending}
/>
{comments?.map(comment => (
<CommentItem
key={comment.id}
comment={comment}
onDelete={deleteComment.mutate}
onReaction={addReaction.mutate}
/>
))}
</div>
);
}Development
Running Storybook
pnpm storybookBuilding the Package
pnpm buildRunning Tests
pnpm testAPI Reference
Components
Thread
The recommended component for most use cases. It handles thread creation and initialization automatically.
Props:
interface ThreadProps {
apiKey: string; // Your API key for authentication
apiUrl: string; // Base URL of your comments API
threadId: string; // Unique identifier for the thread
title: string; // Thread title
url: string; // URL associated with the thread
settings?: {
allowReplies?: boolean; // Enable/disable replies
requireApproval?: boolean; // Require moderation
maxDepth?: number; // Maximum nesting level
};
onThreadCreate?: (thread: Thread) => void; // Called when thread is created
onThreadUpdate?: (thread: Thread) => void; // Called when thread is updated
}Comments
The base component that provides a complete comments system. Use this if you need more control over thread management.
CommentItem
A component for displaying individual comments.
CommentForm
A form component for submitting new comments.
Hooks
useComments
A hook that provides comment-related operations and state management.
Contributing
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request
License
MIT
