@treditpackage/feedback
v1.0.0
Published
A lightweight, customizable React feedback widget for collecting user feedback with built-in image upload support.
Readme
@treditpackage/feedback
A lightweight, customizable React feedback widget for collecting user feedback with built-in image upload support.
✨ Features
- 🎯 Customizable feedback types: Provide your own dropdown options
- 📸 Image upload with drag-and-drop and clipboard paste (Ctrl+V)
- ✅ Form validation with inline error messages
- 🛡️ Honeypot spam protection built-in
- 🎨 Fully customizable via CSS variables
- 📱 Responsive design - works on mobile and desktop
- ⚡ Lightweight - minimal dependencies
- 🔧 Flexible positioning - fixed side button or inline top bar
- 🎭 Custom button variants - 8 pre-built styles
- 🚫 No notification system dependency - handle success/error your way
- 🔌 Custom submit handler - full control over form submission with
onSubmitcallback
📦 Installation
npm install @treditpackage/feedback antdPeer Dependencies
react >= 17react-dom >= 17
🚀 Quick Start
import { FeedbackWidget } from "@treditpackage/feedback";
function App() {
return (
<div>
<YourAppContent />
{/* Fixed feedback button on right side */}
<FeedbackWidget triggerPosition="right-side" simulationMode="random" />
</div>
);
}✨ Styles are automatically included — no need for separate CSS imports!
📖 API Reference
FeedbackWidget Props
| Prop | Type | Default | Description |
| ----------------- | --------------------------------------------------------- | ----------------------- | ------------------------------------------------ |
| triggerPosition | "right-side" \| "top-bar" | "right-side" | Position of the trigger button |
| simulationMode | "success" \| "error" \| "random" | "random" | Mock submission behavior for testing |
| triggerVariant | ButtonVariant | "primary" | Style variant for trigger button |
| submitVariant | ButtonVariant | "primary" | Style variant for submit button |
| feedbackOptions | Array<{value: string, label: string}> | [{Bug}, {Suggestion}] | Custom options for feedback type dropdown |
| onSubmit | (data: FeedbackSubmissionData) => void \| Promise<void> | undefined | Callback fired on form submission with form data |
Button Variants
Available variants: primary, secondary, danger, success, warning, info, ghost, outline
Example with Custom Variants
<FeedbackWidget
triggerPosition="right-side"
triggerVariant="info"
submitVariant="success"
simulationMode="success"
/>Custom Feedback Options
Customize the feedback type dropdown with your own options:
const customOptions = [
{ value: "Bug", label: "🐛 Bug Report" },
{ value: "Feature", label: "✨ Feature Request" },
{ value: "Question", label: "❓ Question" },
{ value: "Praise", label: "👏 Praise" },
];
<FeedbackWidget feedbackOptions={customOptions} triggerPosition="right-side" />;Handle Form Submission
Use the onSubmit callback to receive form data and integrate with your backend:
import { FeedbackWidget } from "@treditpackage/feedback";
import type { FeedbackSubmissionData } from "@treditpackage/feedback";
function App() {
const handleFeedbackSubmit = async (data: FeedbackSubmissionData) => {
// Access all form data
console.log(data.feedbackType); // e.g., "Bug"
console.log(data.message); // User's message
console.log(data.imageFile); // File object or undefined
console.log(data.sourcePath); // Current page path
// Send to your API
const formData = new FormData();
formData.append("type", data.feedbackType);
formData.append("message", data.message);
if (data.imageFile) {
formData.append("image", data.imageFile);
}
const response = await fetch("/api/feedback", {
method: "POST",
body: formData,
});
if (response.ok) {
// Show success notification
alert("Thank you for your feedback!");
} else {
throw new Error("Submission failed");
}
};
return (
<div>
<YourContent />
<FeedbackWidget
onSubmit={handleFeedbackSubmit}
triggerPosition="right-side"
/>
</div>
);
}🎨 Customization
CSS Variables
Override these CSS variables to match your brand:
:root {
/* Background & borders */
--feedback-bg: rgba(8, 28, 53, 0.96);
--feedback-border: rgba(148, 163, 184, 0.6);
/* Text colors */
--feedback-text: #e7f1ff;
--feedback-muted: #94a3b8;
/* Accent color */
--feedback-accent: #bc88ff;
--feedback-accent-text: #020b18;
/* Button styles */
--feedback-button-bg: #bc88ff;
--feedback-button-text: #020b18;
--feedback-button-hover-bg: #a66ff7;
}Dark/Light Theme Example
/* Light theme */
.light-theme {
--feedback-bg: rgba(255, 255, 255, 0.98);
--feedback-text: #1a202c;
--feedback-border: rgba(0, 0, 0, 0.1);
--feedback-accent: #4f46e5;
}
/* Dark theme */
.dark-theme {
--feedback-bg: rgba(17, 24, 39, 0.98);
--feedback-text: #f9fafb;
--feedback-border: rgba(255, 255, 255, 0.1);
--feedback-accent: #818cf8;
}💡 Usage Examples
Fixed Side Button
<FeedbackWidget triggerPosition="right-side" triggerVariant="primary" />Creates a fixed button on the right edge of the screen.
Top Bar Inline Button
<nav>
<Logo />
<NavLinks />
<FeedbackWidget triggerPosition="top-bar" triggerVariant="ghost" />
</nav>Renders an inline button suitable for navigation bars.
Testing Different Scenarios
// Always succeed
<FeedbackWidget simulationMode="success" />
// Always fail (for error handling testing)
<FeedbackWidget simulationMode="error" />
// Random (75% success, 25% error)
<FeedbackWidget simulationMode="random" />🔧 Advanced Usage
Backend Integration
Use the onSubmit callback to send feedback to your backend API:
import { FeedbackWidget } from "@treditpackage/feedback";
import type { FeedbackSubmissionData } from "@treditpackage/feedback";
function App() {
const handleSubmit = async (data: FeedbackSubmissionData) => {
const formData = new FormData();
formData.append("type", data.feedbackType);
formData.append("message", data.message);
formData.append("path", data.sourcePath || "");
if (data.imageFile) {
formData.append("screenshot", data.imageFile);
}
const response = await fetch("/api/feedback", {
method: "POST",
body: formData,
});
if (!response.ok) {
throw new Error("Failed to submit feedback");
}
// Optionally return data from your API
const result = await response.json();
console.log("Feedback ID:", result.id);
};
return <FeedbackWidget onSubmit={handleSubmit} />;
}With Notification System Integration
import { FeedbackWidget } from "@treditpackage/feedback";
import type { FeedbackSubmissionData } from "@treditpackage/feedback";
import { toast } from "your-toast-library";
function App() {
const handleSubmit = async (data: FeedbackSubmissionData) => {
try {
await fetch("/api/feedback", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
toast.success("Thank you for your feedback!");
} catch (error) {
toast.error("Failed to submit feedback. Please try again.");
throw error; // Re-throw to prevent form reset
}
};
return <FeedbackWidget onSubmit={handleSubmit} />;
}Handling Success/Error
The widget automatically handles form submission and resets on success. When you provide the onSubmit callback, you have full control over the submission process:
const handleSubmit = async (data: FeedbackSubmissionData) => {
try {
await sendToBackend(data);
// Show success message with your notification system
showNotification("Feedback submitted!", "success");
} catch (error) {
// Handle errors your way
showNotification("Failed to submit feedback", "error");
throw error; // Re-throw to prevent form reset
}
};
<FeedbackWidget onSubmit={handleSubmit} />;Note: If onSubmit is not provided, the widget uses its default mock submission service with simulationMode for testing purposes.
📝 TypeScript Support
Full TypeScript support with exported types:
import type {
FeedbackType,
FeedbackSubmission,
FeedbackSubmissionData, // New! Data passed to onSubmit callback
ButtonVariant,
} from "@treditpackage/feedback";FeedbackSubmissionData Interface
interface FeedbackSubmissionData {
feedbackType: string; // Selected feedback type
message: string; // User's message
imageFile?: File; // Uploaded image (if any)
sourcePath?: string; // Current page path
}🎯 Features Detail
Image Upload
- Drag & drop files onto the dropzone
- Click to browse file selection
- Clipboard paste (Ctrl+V / Cmd+V)
- Image preview with remove option
- Accepts: PNG, JPG, JPEG, GIF, WebP (max 5MB)
Form Validation
- Required field validation
- Character limits (10-500 chars for message)
- Image size validation
- Real-time error messages
Spam Protection
Includes invisible honeypot field that bots typically fill out, helping filter spam submissions.
🎨 CSS & Styling
Automatic CSS Bundling
All styles are automatically bundled into the main package output. When you import the component, CSS is applied automatically — no additional imports required.
import { FeedbackWidget } from "@treditpackage/feedback";
// ✅ Styles are already included!Manual CSS Imports (Optional)
If you prefer to manage CSS imports explicitly, you can import the CSS files directly:
import { FeedbackWidget } from "@treditpackage/feedback";
import "@treditpackage/feedback/feedback.css";
import "@treditpackage/feedback/select.css";This approach is useful if you want to:
- Control the order of CSS imports in your application
- Dynamically load styles conditionally
- Use CSS preprocessors or CSS-in-JS solutions
CSS Files Included
The package includes the following CSS files:
- feedback.css - Widget layout, colors, spacing, and animations
- select.css - Select dropdown component styles
Both files are automatically bundled into index.js, but are also available for separate import.
Override Styles with CSS Variables
To customize the appearance, override CSS variables in your global styles or component:
:root {
--feedback-bg: rgba(8, 28, 53, 0.96);
--feedback-text: #e7f1ff;
--feedback-accent: #bc88ff;
/* ... other variables */
}See the Customization section for all available CSS variables.
📦 Package Structure
dist/
├── index.js # Main component exports (includes bundled CSS)
└── index.d.ts # TypeScript definitions🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
MIT © [Tredit]
🐛 Issues
Found a bug? Please open an issue with:
- Steps to reproduce
- Expected behavior
- Actual behavior
- Screenshots (if applicable)
🚀 Roadmap
- [ ] Email field option
- [ ] Custom field support
- [ ] Analytics integration
- [ ] File attachment support (non-image files)
- [ ] Multi-language support
- [ ] Accessibility improvements (WCAG 2.1 AA)
Made with ❤️ by Tredit
