@madajoe6969/microfeedback-vue
v1.0.0
Published
Vue widget component for MicroFeedback with unified styling
Maintainers
Readme
@my-better-t-app/embed-vue
Vue widget component for MicroFeedback with unified styling and Vue 2/3 compatibility.
Features
- 🎨 Unified Styling: Uses the same style renderer as dashboard preview and other embed packages
- 🔄 Vue 2 & 3 Compatible: Works with both Vue 2.7+ and Vue 3
- 📱 Responsive Design: Adapts to mobile, tablet, and desktop screens
- ♿ Accessible: WCAG 2.1 AA compliant with keyboard navigation and screen reader support
- 🎯 Floating & Inline Modes: Can be displayed as a floating widget or inline component
- 🎨 CSS Variables: Uses CSS custom properties for easy theming and customization
- 🔧 TypeScript Support: Full TypeScript definitions included
Installation
bun add @my-better-t-app/embed-vueQuick Start
Vue 3 (Composition API)
<template>
<MicroFeedbackWidget
widget-id="your-widget-id"
api-key="your-api-key"
@submit="handleSubmit"
@error="handleError"
/>
</template>
<script setup lang="ts">
import { MicroFeedbackWidget } from '@my-better-t-app/embed-vue';
const handleSubmit = (data: any) => {
console.log('Feedback submitted:', data);
};
const handleError = (error: Error) => {
console.error('Widget error:', error);
};
</script>Vue 2 (Options API)
<template>
<MicroFeedbackWidget
:widget-id="widgetId"
:api-key="apiKey"
@submit="handleSubmit"
@error="handleError"
/>
</template>
<script>
import { MicroFeedbackWidget } from '@my-better-t-app/embed-vue';
export default {
components: {
MicroFeedbackWidget,
},
data() {
return {
widgetId: 'your-widget-id',
apiKey: 'your-api-key',
};
},
methods: {
handleSubmit(data) {
console.log('Feedback submitted:', data);
},
handleError(error) {
console.error('Widget error:', error);
},
},
};
</script>Global Installation
Vue 3
import { createApp } from 'vue';
import { MicroFeedbackPlugin } from '@my-better-t-app/embed-vue';
import App from './App.vue';
const app = createApp(App);
app.use(MicroFeedbackPlugin);
app.mount('#app');Vue 2
import Vue from 'vue';
import { install as MicroFeedbackInstall } from '@my-better-t-app/embed-vue';
import App from './App.vue';
Vue.use(MicroFeedbackInstall);
new Vue({
render: h => h(App),
}).$mount('#app');Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| widgetId | string | Required | Your widget ID from MicroFeedback dashboard |
| apiKey | string | Required | Your API key for authentication |
| apiUrl | string | '/api/embed' | Base URL for the MicroFeedback API |
| displayMode | 'floating' \| 'inline' | 'floating' | Display mode of the widget |
| title | string | 'Send Feedback' | Widget title text |
| description | string | 'Help us improve by sharing your thoughts' | Widget description text |
| placeholder | string | 'Your feedback...' | Textarea placeholder text |
| triggerText | string | 'Feedback' | Floating trigger button text |
| triggerLabel | string | 'Open feedback widget' | Floating trigger button aria-label |
| submitText | string | 'Send Feedback' | Submit button text |
| successMessage | string | 'Thank you for your feedback!' | Success message text |
| showEmail | boolean | false | Show optional email field |
| showCancel | boolean | true | Show cancel button (inline mode only) |
| autoClose | boolean | true | Auto-close widget after successful submission |
| autoCloseDelay | number | 3000 | Delay in milliseconds before auto-closing |
Events
| Event | Payload | Description |
|-------|---------|-------------|
| submit | { feedback: string, email?: string, result: any } | Emitted when feedback is successfully submitted |
| error | Error | Emitted when an error occurs |
| open | void | Emitted when the widget is opened (floating mode) |
| close | void | Emitted when the widget is closed (floating mode) |
| cancel | void | Emitted when the cancel button is clicked |
Display Modes
Floating Mode (Default)
The widget appears as a floating trigger button in the bottom-right corner. When clicked, it opens a floating dialog.
<MicroFeedbackWidget
widget-id="your-widget-id"
api-key="your-api-key"
display-mode="floating"
/>Inline Mode
The widget is embedded directly in your page content.
<MicroFeedbackWidget
widget-id="your-widget-id"
api-key="your-api-key"
display-mode="inline"
/>Composition API Usage
For Vue 3 projects, you can use the useMicroFeedback composable for more control:
<template>
<div>
<div v-if="loading">Loading widget configuration...</div>
<div v-else-if="error">Error: {{ error }}</div>
<div v-else :style="cssVariables">
<!-- Your custom widget UI -->
<form @submit.prevent="handleSubmit">
<textarea v-model="feedback" required></textarea>
<button type="submit" :disabled="submitting">
{{ submitting ? 'Sending...' : 'Send Feedback' }}
</button>
</form>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useMicroFeedback } from '@my-better-t-app/embed-vue';
const feedback = ref('');
const {
loading,
error,
submitting,
cssVariables,
submitFeedback,
} = useMicroFeedback({
widgetId: 'your-widget-id',
apiKey: 'your-api-key',
});
const handleSubmit = async () => {
try {
await submitFeedback({
feedback: feedback.value,
});
feedback.value = '';
console.log('Feedback submitted successfully!');
} catch (err) {
console.error('Failed to submit feedback:', err);
}
};
</script>Styling and Customization
The widget uses CSS custom properties (variables) for styling, which are automatically generated from your widget configuration in the MicroFeedback dashboard. You can override these variables to customize the appearance:
.my-custom-widget {
--mf-primary-color: #your-brand-color;
--mf-background-color: #ffffff;
--mf-text-color: #333333;
--mf-border-radius: 8px;
--mf-font-family: 'Your Font', sans-serif;
}Available CSS Variables
--mf-primary-color: Primary brand color--mf-secondary-color: Secondary brand color--mf-background-color: Widget background color--mf-text-color: Main text color--mf-border-color: Border color--mf-error-color: Error message color--mf-success-color: Success message color--mf-muted-color: Muted text color--mf-font-family: Font family--mf-font-size-*: Font sizes (small, base, large)--mf-font-weight-*: Font weights (normal, medium, bold)--mf-border-radius: Border radius--mf-padding-*: Padding sizes (small, medium, large)--mf-margin-*: Margin sizes (small, medium, large)--mf-transition-duration: Animation duration--mf-hover-opacity: Hover state opacity
Responsive Behavior
The widget automatically adapts to different screen sizes:
- Mobile (≤768px): Full-width layout with stacked buttons
- Tablet (769px-1024px): Optimized spacing and sizing
- Desktop (≥1025px): Full feature set with hover effects
Responsive CSS variables are also available:
--mf-mobile-*: Mobile-specific overrides--mf-tablet-*: Tablet-specific overrides
Accessibility
The widget is built with accessibility in mind:
- ✅ Keyboard navigation support
- ✅ Screen reader compatible
- ✅ Focus management
- ✅ ARIA labels and descriptions
- ✅ High contrast mode support
- ✅ Reduced motion support
Browser Support
- Vue 2.7+ or Vue 3.0+
- Modern browsers (Chrome, Firefox, Safari, Edge)
- IE11+ (with polyfills)
TypeScript Support
Full TypeScript definitions are included. Import types as needed:
import type {
WidgetStyleConfig,
ColorConfig,
TypographyConfig,
} from '@my-better-t-app/embed-vue';Examples
Custom Styling
<template>
<div class="custom-feedback-widget">
<MicroFeedbackWidget
widget-id="your-widget-id"
api-key="your-api-key"
display-mode="inline"
title="We'd love your feedback!"
description="Help us make our product better"
:show-email="true"
/>
</div>
</template>
<style>
.custom-feedback-widget {
--mf-primary-color: #6366f1;
--mf-border-radius: 12px;
--mf-font-family: 'Inter', sans-serif;
}
</style>Event Handling
<template>
<MicroFeedbackWidget
widget-id="your-widget-id"
api-key="your-api-key"
@submit="onSubmit"
@error="onError"
@open="onOpen"
@close="onClose"
/>
</template>
<script setup lang="ts">
const onSubmit = (data: any) => {
// Track feedback submission
analytics.track('feedback_submitted', {
feedback_length: data.feedback.length,
has_email: !!data.email,
});
};
const onError = (error: Error) => {
// Log error to monitoring service
console.error('Feedback widget error:', error);
};
const onOpen = () => {
analytics.track('feedback_widget_opened');
};
const onClose = () => {
analytics.track('feedback_widget_closed');
};
</script>License
MIT
