@feedvalue/vue 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -5
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -50,6 +50,48 @@ const { open, isReady, isOpen } = useFeedValue();
|
|
|
50
50
|
</template>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
### Headless Mode
|
|
54
|
+
|
|
55
|
+
For complete UI control, use headless mode. The SDK fetches config and provides all API methods but renders no DOM elements:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// main.ts
|
|
59
|
+
app.use(createFeedValue({
|
|
60
|
+
widgetId: 'your-widget-id',
|
|
61
|
+
headless: true, // No trigger button or modal rendered
|
|
62
|
+
}));
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<script setup>
|
|
67
|
+
import { ref } from 'vue';
|
|
68
|
+
import { useFeedValue } from '@feedvalue/vue';
|
|
69
|
+
|
|
70
|
+
const { isReady, isOpen, open, close, submit, isSubmitting, isHeadless } = useFeedValue();
|
|
71
|
+
const message = ref('');
|
|
72
|
+
|
|
73
|
+
async function handleSubmit() {
|
|
74
|
+
await submit({ message: message.value });
|
|
75
|
+
message.value = '';
|
|
76
|
+
close();
|
|
77
|
+
}
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<template>
|
|
81
|
+
<button @click="open" :disabled="!isReady">
|
|
82
|
+
Feedback
|
|
83
|
+
</button>
|
|
84
|
+
|
|
85
|
+
<div v-if="isOpen" class="my-modal">
|
|
86
|
+
<textarea v-model="message" placeholder="Your feedback..." />
|
|
87
|
+
<button @click="handleSubmit" :disabled="isSubmitting">
|
|
88
|
+
{{ isSubmitting ? 'Sending...' : 'Submit' }}
|
|
89
|
+
</button>
|
|
90
|
+
<button @click="close">Cancel</button>
|
|
91
|
+
</div>
|
|
92
|
+
</template>
|
|
93
|
+
```
|
|
94
|
+
|
|
53
95
|
### Standalone Usage (No Plugin)
|
|
54
96
|
|
|
55
97
|
```vue
|
|
@@ -99,8 +141,53 @@ async function handleSubmit() {
|
|
|
99
141
|
</template>
|
|
100
142
|
```
|
|
101
143
|
|
|
144
|
+
### Custom Fields
|
|
145
|
+
|
|
146
|
+
Custom fields allow you to collect structured data beyond the main feedback message. **Custom fields must be defined in your widget configuration on the FeedValue dashboard before use.**
|
|
147
|
+
|
|
148
|
+
1. Go to your widget settings in the FeedValue dashboard
|
|
149
|
+
2. Add custom fields with types: `text`, `email`, or `emoji`
|
|
150
|
+
3. Use `customFieldValues` when submitting:
|
|
151
|
+
|
|
152
|
+
```vue
|
|
153
|
+
<script setup>
|
|
154
|
+
import { ref } from 'vue';
|
|
155
|
+
import { useFeedValue } from '@feedvalue/vue';
|
|
156
|
+
|
|
157
|
+
const { submit, isReady } = useFeedValue();
|
|
158
|
+
const name = ref('');
|
|
159
|
+
const category = ref('feature');
|
|
160
|
+
|
|
161
|
+
async function handleSubmit() {
|
|
162
|
+
await submit({
|
|
163
|
+
message: 'Detailed feedback',
|
|
164
|
+
customFieldValues: {
|
|
165
|
+
// Field IDs must match those defined in your widget configuration
|
|
166
|
+
name: name.value,
|
|
167
|
+
category: category.value,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
</script>
|
|
172
|
+
|
|
173
|
+
<template>
|
|
174
|
+
<form @submit.prevent="handleSubmit">
|
|
175
|
+
<input v-model="name" placeholder="Your name" />
|
|
176
|
+
<select v-model="category">
|
|
177
|
+
<option value="bug">Bug Report</option>
|
|
178
|
+
<option value="feature">Feature Request</option>
|
|
179
|
+
</select>
|
|
180
|
+
<button type="submit" :disabled="!isReady">Submit</button>
|
|
181
|
+
</form>
|
|
182
|
+
</template>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
> **Important**: The field IDs in `customFieldValues` must match the field IDs defined in your widget configuration on the dashboard.
|
|
186
|
+
|
|
102
187
|
### User Identification
|
|
103
188
|
|
|
189
|
+
Attach user context to feedback submissions. This data is **not shown in the widget UI** but is stored with the submission and visible in your FeedValue dashboard:
|
|
190
|
+
|
|
104
191
|
```vue
|
|
105
192
|
<script setup>
|
|
106
193
|
import { watch } from 'vue';
|
|
@@ -124,6 +211,10 @@ watch(() => props.user, (user) => {
|
|
|
124
211
|
</script>
|
|
125
212
|
```
|
|
126
213
|
|
|
214
|
+
> **User Data vs Custom Fields**
|
|
215
|
+
> - **User data** (`identify`/`setData`): Hidden from users, automatically attached to submissions. Use for internal context like user IDs, subscription plans, etc.
|
|
216
|
+
> - **Custom fields** (`customFieldValues`): Shown as form inputs in the widget. Users fill these in themselves. Must be defined in widget configuration first.
|
|
217
|
+
|
|
127
218
|
### Options API Support
|
|
128
219
|
|
|
129
220
|
```vue
|
|
@@ -149,11 +240,12 @@ export default {
|
|
|
149
240
|
|
|
150
241
|
Creates a Vue plugin for FeedValue.
|
|
151
242
|
|
|
152
|
-
| Option | Type | Required | Description |
|
|
153
|
-
|
|
154
|
-
| `widgetId` | `string` | Yes | Widget ID from FeedValue dashboard |
|
|
155
|
-
| `apiBaseUrl` | `string` | No | Custom API URL (for self-hosted) |
|
|
156
|
-
| `config` | `Partial<FeedValueConfig>` | No | Configuration overrides |
|
|
243
|
+
| Option | Type | Required | Default | Description |
|
|
244
|
+
|--------|------|----------|---------|-------------|
|
|
245
|
+
| `widgetId` | `string` | Yes | - | Widget ID from FeedValue dashboard |
|
|
246
|
+
| `apiBaseUrl` | `string` | No | Production URL | Custom API URL (for self-hosted) |
|
|
247
|
+
| `config` | `Partial<FeedValueConfig>` | No | - | Configuration overrides |
|
|
248
|
+
| `headless` | `boolean` | No | `false` | Disable all DOM rendering |
|
|
157
249
|
|
|
158
250
|
### `useFeedValue(widgetId?, config?)`
|
|
159
251
|
|
|
@@ -176,6 +268,7 @@ Composable to access FeedValue functionality.
|
|
|
176
268
|
| `isVisible` | `Readonly<Ref<boolean>>` | Trigger is visible |
|
|
177
269
|
| `error` | `Readonly<Ref<Error \| null>>` | Current error |
|
|
178
270
|
| `isSubmitting` | `Readonly<Ref<boolean>>` | Submission in progress |
|
|
271
|
+
| `isHeadless` | `Readonly<Ref<boolean>>` | Running in headless mode |
|
|
179
272
|
| `open` | `() => void` | Open modal |
|
|
180
273
|
| `close` | `() => void` | Close modal |
|
|
181
274
|
| `toggle` | `() => void` | Toggle modal |
|
|
@@ -216,6 +309,18 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
216
309
|
});
|
|
217
310
|
```
|
|
218
311
|
|
|
312
|
+
For headless mode in Nuxt:
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// plugins/feedvalue.client.ts
|
|
316
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
317
|
+
nuxtApp.vueApp.use(createFeedValue({
|
|
318
|
+
widgetId: 'your-widget-id',
|
|
319
|
+
headless: true, // Build your own UI
|
|
320
|
+
}));
|
|
321
|
+
});
|
|
322
|
+
```
|
|
323
|
+
|
|
219
324
|
The `.client.ts` suffix ensures the plugin only runs on the client side.
|
|
220
325
|
|
|
221
326
|
## SSR Support
|
|
@@ -239,6 +344,18 @@ const { isReady } = useFeedValue();
|
|
|
239
344
|
</template>
|
|
240
345
|
```
|
|
241
346
|
|
|
347
|
+
## Default vs Headless Mode
|
|
348
|
+
|
|
349
|
+
| Feature | Default Mode | Headless Mode |
|
|
350
|
+
|---------|--------------|---------------|
|
|
351
|
+
| Trigger button | Dashboard-styled | You build it |
|
|
352
|
+
| Modal | Dashboard-styled | You build it |
|
|
353
|
+
| API methods | Available | Available |
|
|
354
|
+
| User tracking | Available | Available |
|
|
355
|
+
| Dashboard config | Fetched | Fetched |
|
|
356
|
+
|
|
357
|
+
Use `headless: true` when you want complete control over the UI.
|
|
358
|
+
|
|
242
359
|
## Requirements
|
|
243
360
|
|
|
244
361
|
- Vue 3.3.0 or higher
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feedvalue/vue",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "FeedValue Vue 3 SDK - Plugin and Composables for Vue 3+",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -23,17 +23,26 @@
|
|
|
23
23
|
"README.md"
|
|
24
24
|
],
|
|
25
25
|
"sideEffects": false,
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"dev": "tsup --watch",
|
|
29
|
+
"lint": "eslint src",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"test:coverage": "vitest run --coverage",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"clean": "rm -rf dist"
|
|
35
|
+
},
|
|
26
36
|
"peerDependencies": {
|
|
27
37
|
"vue": ">=3.3.0"
|
|
28
38
|
},
|
|
29
39
|
"dependencies": {
|
|
30
|
-
"@feedvalue/core": "
|
|
40
|
+
"@feedvalue/core": "workspace:^"
|
|
31
41
|
},
|
|
32
42
|
"devDependencies": {
|
|
33
43
|
"@vitejs/plugin-vue": "^5.2.0",
|
|
34
44
|
"@vitest/coverage-v8": "^2.1.0",
|
|
35
45
|
"@vue/test-utils": "^2.4.0",
|
|
36
|
-
"eslint": "^9.17.0",
|
|
37
46
|
"happy-dom": "^15.11.0",
|
|
38
47
|
"tsup": "^8.3.0",
|
|
39
48
|
"typescript": "^5.7.0",
|
|
@@ -65,15 +74,5 @@
|
|
|
65
74
|
],
|
|
66
75
|
"engines": {
|
|
67
76
|
"node": ">=18"
|
|
68
|
-
},
|
|
69
|
-
"scripts": {
|
|
70
|
-
"build": "tsup",
|
|
71
|
-
"dev": "tsup --watch",
|
|
72
|
-
"lint": "eslint src --ext .ts",
|
|
73
|
-
"test": "vitest run",
|
|
74
|
-
"test:watch": "vitest",
|
|
75
|
-
"test:coverage": "vitest run --coverage",
|
|
76
|
-
"typecheck": "tsc --noEmit",
|
|
77
|
-
"clean": "rm -rf dist"
|
|
78
77
|
}
|
|
79
|
-
}
|
|
78
|
+
}
|