npm package: @madajoe6969/microfeedback-vue
Description: Vue widget component for MicroFeedback with unified styling
Author: MicroFeedback
Latest version: 1.0.0

# @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

```bash
bun add @my-better-t-app/embed-vue
```

## Quick Start

### Vue 3 (Composition API)

```vue
<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)

```vue
<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

```typescript
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

```javascript
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.

```vue
<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.

```vue
<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:

```vue
<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:

```css
.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:

```typescript
import type {
  WidgetStyleConfig,
  ColorConfig,
  TypographyConfig,
} from '@my-better-t-app/embed-vue';
```

## Examples

### Custom Styling

```vue
<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

```vue
<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