my-rag-library
v2.0.3
Published
A lightweight React component library providing FileUploader and RAGChatbot components.
Maintainers
Readme
my-rag-library
A lightweight React component library providing two production-ready components:
- FileUploader: drag-and-drop + button-based file uploader with per-file progress and POST FormData.
- RAGChatbot: minimal chat UI for RAG backends, with streaming support and citations panel.
Built with TypeScript and Vite (library mode). React is a peer dependency and not bundled.
Install
npm install my-rag-library
# or
yarn add my-rag-libraryPeer deps required in your app:
{
"react": ">=17 || >=18",
"react-dom": ">=17 || >=18"
}Import
import { FileUploader, RAGChatbot } from "my-rag-library";Components (design control)
FileUploader
Props:
interface FileUploaderProps {
endpoint: string; // POST endpoint for file uploads
onUpload?: (result: any) => void;
themeColor?: string;
multiple?: boolean;
className?: string;
style?: React.CSSProperties;
unstyled?: boolean; // if true, renders without inline styles
onProgress?: (file: File, p: number) => void;
classNames?: {
// optional CSS class hooks
container?: string;
dropzone?: string;
button?: string;
list?: string;
fileItem?: string;
progressTrack?: string;
progressBar?: string;
status?: string;
message?: string;
};
components?: {
// optional slot overrides (render-props)
Container?: (p: React.PropsWithChildren<{ className?: string; style?: React.CSSProperties }>) => React.ReactNode;
Dropzone?: (p: { isDragging: boolean; onDrop: any; onDragOver: any; onDragLeave: any; children: React.ReactNode; className?: string; style?: React.CSSProperties }) => React.ReactNode;
BrowseButton?: (p: { onClick: () => void; className?: string; style?: React.CSSProperties }) => React.ReactNode;
FileItem?: (p: { entry: FileProgress; themeColor: string; className?: string; style?: React.CSSProperties }) => React.ReactNode;
Message?: (p: { type: "success" | "error"; text?: string; className?: string; style?: React.CSSProperties }) => React.ReactNode;
};
}Behavior:
- Drag & drop zone
- Browse button
- Per-file progress via XMLHttpRequest
- POST with FormData:
form.append("file", file) - Success and error messaging
Example (default UI):
<FileUploader endpoint="https://your-api.example.com/upload" themeColor="#6366f1" multiple onUpload={(result) => console.log("Upload result:", result)} />Headless hook:
import { useFileUploader } from "my-rag-library";
function CustomUploader() {
const { inputRef, drag, browse, handleFiles, filesProgress, message } = useFileUploader({ endpoint: "/api/upload" });
return (
<div>
<div onDrop={drag.onDrop} onDragOver={drag.onDragOver} onDragLeave={drag.onDragLeave} className="my-dropzone">
<button onClick={browse}>Pick files</button>
<input ref={inputRef} type="file" multiple onChange={(e) => handleFiles(e.target.files)} style={{ display: "none" }} />
</div>
{filesProgress.map((fp) => (
<div key={fp.file.name}>
{fp.file.name} - {fp.progress}%
</div>
))}
{message.type && <div>{message.text}</div>}
</div>
);
}RAGChatbot
Props:
interface RAGChatbotProps {
endpoint: string; // POST endpoint for chat requests
title?: string;
theme?: "light" | "dark";
width?: string;
height?: string;
className?: string;
style?: React.CSSProperties;
unstyled?: boolean; // remove inline styles for full control
classNames?: {
container?: string;
header?: string;
title?: string;
messages?: string;
messageRow?: string;
avatar?: string;
bubble?: string;
sources?: string;
inputRow?: string;
input?: string;
sendButton?: string;
error?: string;
};
components?: {
Container?: (p: React.PropsWithChildren<{ className?: string; style?: React.CSSProperties }>) => React.ReactNode;
Header?: (p: { title: string; className?: string }) => React.ReactNode;
Message?: (p: { id: string; role: "user" | "assistant" | "system"; content: string; isSending: boolean }) => React.ReactNode;
Sources?: (p: { forMessageId: string; items: Array<{ title?: string; url?: string; id?: string | number; snippet?: string }> }) => React.ReactNode;
InputArea?: (p: { value: string; onChange: (v: string) => void; onSubmit: () => void; disabled: boolean; className?: string }) => React.ReactNode;
Error?: (p: { text: string }) => React.ReactNode;
};
}Behavior:
- Sends messages as JSON:
{ "query": "..." } - Displays chat bubbles for user and assistant
- Supports streaming (text/event-stream or chunked text)
- Displays citations/sources if returned by backend:
{ answer, sources }
Example (default UI):
<RAGChatbot endpoint="https://your-api.example.com/chat" title="Docs Assistant" theme="light" width="100%" height="600px" />Headless hook:
import { useRAGChatbot } from "my-rag-library";
function CustomChat() {
const { input, setInput, messages, isSending, error, sendMessage } = useRAGChatbot({ endpoint: "/api/chat" });
return (
<div>
<ul>
{messages.map((m) => (
<li key={m.id}>
<b>{m.role}:</b> {m.content}
</li>
))}
</ul>
<input value={input} onChange={(e) => setInput(e.target.value)} onKeyDown={(e) => e.key === "Enter" && sendMessage()} />
<button disabled={isSending || !input.trim()} onClick={sendMessage}>
Send
</button>
{error && <div>{error}</div>}
</div>
);
}Your backend can return either streaming text or JSON:
- Non-streaming JSON expected shape:
{ "answer": "text...", "sources": [{ "title": "...", "url": "..." }] } - Streaming:
text/event-streamor chunked text; component concatenates chunks
Theming / Styling
FileUploaderacceptsthemeColorfor primary accents.RAGChatbotsupportstheme="light" | "dark".- Both components accept
classNameandstylefor further control.
Passing Endpoints
Provide absolute or relative URLs via the endpoint prop:
<FileUploader endpoint="/api/upload" />
<RAGChatbot endpoint="/api/chat" />Local Development
npm install
npm run dev # Vite dev server (for playground usage if you add one)
npm run build # builds the library to /distBuild outputs:
- ESM:
dist/my-rag-library.es.js - UMD:
dist/my-rag-library.umd.cjs - Types:
dist/index.d.ts
Publish to npm
- Update
package.jsonversion. - Make sure you are logged in:
npm login- Build and publish:
npm run build
npm publish --access publicExample Usage
import React from "react";
import { FileUploader, RAGChatbot } from "my-rag-library";
export default function App() {
return (
<div style={{ display: "grid", gap: 24, maxWidth: 800, margin: "40px auto" }}>
<FileUploader endpoint="https://your-api.example.com/upload" themeColor="#3b82f6" multiple onUpload={(res) => console.log(res)} />
<RAGChatbot endpoint="https://your-api.example.com/chat" title="RAG Assistant" theme="light" width="100%" height="600px" />
</div>
);
}License
MIT
