@refinelyai/feedback-widget
v0.0.4
Published
A highly customizable feedback widget library with star ratings and text input - works on web and React Native
Maintainers
Readme
@refinelyai/feedback-widget
A highly customizable feedback widget library with star ratings and text input that works seamlessly across web and React Native platforms.
Features
- 🌐 Cross-Platform: Works on web browsers and React Native
- ⭐ Star Rating System: Customizable star ratings with labels
- 📝 Text Input: Multi-line text input with character counting
- 🎨 Highly Customizable: Extensive styling and behavior options
- 🔄 React Hooks: Built-in React hooks for easy integration
- 📦 Multiple Entry Points: Choose the right bundle for your platform
- 🚀 TypeScript Support: Full TypeScript support with type definitions
Installation
npm install @refinelyai/feedback-widgetQuick Start
Web Usage
import { FeedbackWidget } from '@refinelyai/feedback-widget';
const widget = new FeedbackWidget('#feedback-container', {
apiKey: 'your-api-key',
apiUrl: 'get-your-api-on-https://refinelyai.netlify.app',
customization: {
title: 'Rate your experience',
layout: 'vertical'
}
});React Usage
import { FeedbackWidget } from '@refinelyai/feedback-widget/react';
function App() {
return (
<FeedbackWidget
apiKey="your-api-key"
apiUrl="get-your-api-on-https://refinelyai.netlify.app"
customization={{
title: 'Rate your experience',
layout: 'vertical'
}}
onSuccess={(response) => console.log('Success:', response)}
onError={(error) => console.error('Error:', error)}
/>
);
}React Native Usage
import { FeedbackWidget } from '@refinelyai/feedback-widget/react-native';
function App() {
return (
<FeedbackWidget
apiKey="your-api-key"
apiUrl="https://your-api.com/feedback"
customization={{
title: 'Rate your experience',
layout: 'vertical'
}}
onSuccess={(response) => console.log('Success:', response)}
onError={(error) => console.error('Error:', error)}
/>
);
}Entry Points
The library provides multiple entry points for different use cases:
- Main:
@refinelyai/feedback-widget- Web version (backward compatibility) - Web:
@refinelyai/feedback-widget/web- Web-specific implementation - React:
@refinelyai/feedback-widget/react- React components and hooks - React Native:
@refinelyai/feedback-widget/react-native- React Native components
Configuration
FeedbackConfig
interface FeedbackConfig {
apiKey: string;
apiUrl: string;
customization?: FeedbackCustomization;
}FeedbackCustomization
interface FeedbackCustomization {
// Container styling
containerStyle?: Record<string, any>;
containerClassName?: string;
// Title/Header
title?: string;
titleStyle?: Record<string, any>;
titleClassName?: string;
// Star rating customization
starRating?: {
maxStars?: number;
starSize?: string | number;
starColor?: string;
starActiveColor?: string;
starHoverColor?: string;
showLabels?: boolean;
labels?: string[];
labelStyle?: Record<string, any>;
labelClassName?: string;
};
// Text input customization
textInput?: {
placeholder?: string;
maxLength?: number;
rows?: number;
style?: Record<string, any>;
className?: string;
label?: string;
labelStyle?: Record<string, any>;
labelClassName?: string;
};
// Submit button customization
submitButton?: {
text?: string;
style?: Record<string, any>;
className?: string;
loadingText?: string;
successText?: string;
errorText?: string;
};
// Layout options
layout?: 'vertical' | 'horizontal';
spacing?: string | number;
// Callbacks
onSubmit?: (data: FeedbackData) => void;
onSuccess?: (response: any) => void;
onError?: (error: Error) => void;
}React Hooks
useFeedbackWidget
import { useFeedbackWidget } from '@refinelyai/feedback-widget/react';
function MyComponent() {
const {
rating,
setRating,
text,
setText,
isSubmitting,
submitFeedback,
reset
} = useFeedbackWidget({
apiKey: 'your-api-key',
apiUrl: 'https://your-api.com/feedback'
});
const handleSubmit = async () => {
try {
const response = await submitFeedback();
console.log('Success:', response);
} catch (error) {
console.error('Error:', error);
}
};
return (
<div>
{/* Your custom UI */}
<button onClick={handleSubmit} disabled={isSubmitting}>
Submit
</button>
</div>
);
}Examples
Basic Web Widget
<!DOCTYPE html>
<html>
<head>
<title>Feedback Widget Demo</title>
</head>
<body>
<div id="feedback-container"></div>
<script type="module">
import { FeedbackWidget } from '@refinelyai/feedback-widget';
const widget = new FeedbackWidget('#feedback-container', {
apiKey: 'your-api-key',
apiUrl: 'https://your-api.com/feedback',
customization: {
title: 'How was your experience?',
layout: 'vertical',
starRating: {
maxStars: 5,
labels: ['Terrible', 'Poor', 'Okay', 'Good', 'Excellent']
},
textInput: {
placeholder: 'Tell us more about your experience...',
maxLength: 500
}
}
});
</script>
</body>
</html>React Component with Custom Styling
import { FeedbackWidget } from '@refinelyai/feedback-widget/dist/react';
function CustomFeedbackWidget() {
return (
<FeedbackWidget
apiKey="your-api-key"
apiUrl="https://your-api.com/feedback"
customization={{
title: 'We value your feedback!',
titleStyle: {
color: '#2c3e50',
fontSize: '20px'
},
starRating: {
starSize: 28,
starColor: '#ecf0f1',
starActiveColor: '#f39c12',
labels: ['Not satisfied', 'Could be better', 'Okay', 'Good', 'Excellent!']
},
textInput: {
placeholder: 'Share your thoughts with us...',
style: {
borderColor: '#3498db',
borderRadius: '8px'
}
},
submitButton: {
text: 'Send Feedback',
style: {
backgroundColor: '#3498db',
borderRadius: '8px'
}
}
}}
onSuccess={(response) => {
alert('Thank you for your feedback!');
}}
onError={(error) => {
alert('Sorry, something went wrong. Please try again.');
}}
/>
);
}React Native with Custom Theme
import { FeedbackWidget } from '@refinelyai/feedback-widget/dist/react-native';
function MobileFeedbackWidget() {
return (
<FeedbackWidget
apiKey="your-api-key"
apiUrl="https://your-api.com/feedback"
customization={{
title: 'Rate our app!',
starRating: {
starSize: 32,
starColor: '#e0e0e0',
starActiveColor: '#ffd700',
labels: ['Poor', 'Fair', 'Good', 'Very Good', 'Excellent']
},
textInput: {
placeholder: 'What can we improve?',
maxLength: 300
},
submitButton: {
text: 'Submit Review',
loadingText: 'Sending...',
successText: 'Thanks!'
}
}}
style={{
margin: 20,
borderRadius: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3
}}
/>
);
}API Reference
FeedbackWidget Class (Web)
class FeedbackWidget {
constructor(container: HTMLElement | string, config: FeedbackConfig, events?: FeedbackEvents);
reset(): void;
setRating(rating: number): void;
setText(text: string): void;
getRating(): number;
getText(): string;
}FeedbackWidget Component (React/React Native)
interface FeedbackWidgetProps extends FeedbackConfig {
onRatingChange?: (rating: number) => void;
onTextChange?: (text: string) => void;
onSubmit?: (data: FeedbackData) => void;
onSuccess?: (response: FeedbackResponse) => void;
onError?: (error: Error) => void;
onReset?: () => void;
style?: any;
}useFeedbackWidget Hook
function useFeedbackWidget(config: FeedbackConfig): {
rating: number;
setRating: (rating: number) => void;
text: string;
setText: (text: string) => void;
isSubmitting: boolean;
submitFeedback: () => Promise<FeedbackResponse | null>;
reset: () => void;
}Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
React Native Support
- React Native 0.60+
- Expo SDK 36+
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
