@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.
Files changed (2) hide show
  1. package/README.md +122 -5
  2. 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.0",
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": "^0.1.0"
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
+ }