@feedvalue/react 0.1.0 → 0.1.1
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 +83 -33
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @feedvalue/react
|
|
2
2
|
|
|
3
|
-
React SDK for FeedValue feedback widget. Provides Provider
|
|
3
|
+
React SDK for FeedValue feedback widget. Provides Provider and Hooks for React 18+.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -55,25 +55,71 @@ export function FeedbackButton() {
|
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### Headless Mode
|
|
59
|
+
|
|
60
|
+
For complete UI control, use headless mode. The SDK fetches config and provides all API methods but renders no trigger button or modal:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
// app/layout.tsx
|
|
64
|
+
import { FeedValueProvider } from '@feedvalue/react';
|
|
65
|
+
|
|
66
|
+
export default function RootLayout({ children }) {
|
|
67
|
+
return (
|
|
68
|
+
<html>
|
|
69
|
+
<body>
|
|
70
|
+
<FeedValueProvider widgetId="your-widget-id" headless>
|
|
71
|
+
{children}
|
|
72
|
+
</FeedValueProvider>
|
|
73
|
+
</body>
|
|
74
|
+
</html>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
59
78
|
|
|
60
79
|
```tsx
|
|
80
|
+
// components/custom-feedback.tsx
|
|
61
81
|
'use client';
|
|
62
82
|
|
|
63
|
-
import {
|
|
83
|
+
import { useState } from 'react';
|
|
84
|
+
import { useFeedValue } from '@feedvalue/react';
|
|
85
|
+
|
|
86
|
+
export function CustomFeedback() {
|
|
87
|
+
const { isReady, isOpen, open, close, submit, isSubmitting, isHeadless } = useFeedValue();
|
|
88
|
+
const [message, setMessage] = useState('');
|
|
89
|
+
|
|
90
|
+
const handleSubmit = async () => {
|
|
91
|
+
await submit({ message });
|
|
92
|
+
setMessage('');
|
|
93
|
+
close();
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (!isReady) return null;
|
|
64
97
|
|
|
65
|
-
// Standalone widget (no Provider needed)
|
|
66
|
-
export function FeedbackWidget() {
|
|
67
98
|
return (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
99
|
+
<>
|
|
100
|
+
<button onClick={open}>Feedback</button>
|
|
101
|
+
|
|
102
|
+
{isOpen && (
|
|
103
|
+
<dialog open className="feedback-modal">
|
|
104
|
+
<textarea
|
|
105
|
+
value={message}
|
|
106
|
+
onChange={(e) => setMessage(e.target.value)}
|
|
107
|
+
placeholder="Your feedback..."
|
|
108
|
+
/>
|
|
109
|
+
<div>
|
|
110
|
+
<button onClick={handleSubmit} disabled={isSubmitting}>
|
|
111
|
+
{isSubmitting ? 'Sending...' : 'Submit'}
|
|
112
|
+
</button>
|
|
113
|
+
<button onClick={close}>Cancel</button>
|
|
114
|
+
</div>
|
|
115
|
+
</dialog>
|
|
116
|
+
)}
|
|
117
|
+
</>
|
|
72
118
|
);
|
|
73
119
|
}
|
|
74
120
|
```
|
|
75
121
|
|
|
76
|
-
### Programmatic
|
|
122
|
+
### Programmatic Submission
|
|
77
123
|
|
|
78
124
|
```tsx
|
|
79
125
|
'use client';
|
|
@@ -109,6 +155,8 @@ export function FeedbackForm() {
|
|
|
109
155
|
|
|
110
156
|
### User Identification
|
|
111
157
|
|
|
158
|
+
User data is automatically included with feedback submissions:
|
|
159
|
+
|
|
112
160
|
```tsx
|
|
113
161
|
'use client';
|
|
114
162
|
|
|
@@ -141,16 +189,17 @@ export function UserIdentifier({ user }) {
|
|
|
141
189
|
|
|
142
190
|
Provider component for FeedValue context.
|
|
143
191
|
|
|
144
|
-
| Prop | Type | Required | Description |
|
|
145
|
-
|
|
146
|
-
| `widgetId` | `string` | Yes | Widget ID from FeedValue dashboard |
|
|
147
|
-
| `apiBaseUrl` | `string` | No | Custom API URL (for self-hosted) |
|
|
148
|
-
| `config` | `Partial<FeedValueConfig>` | No | Configuration overrides |
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
192
|
+
| Prop | Type | Required | Default | Description |
|
|
193
|
+
|------|------|----------|---------|-------------|
|
|
194
|
+
| `widgetId` | `string` | Yes | - | Widget ID from FeedValue dashboard |
|
|
195
|
+
| `apiBaseUrl` | `string` | No | Production URL | Custom API URL (for self-hosted) |
|
|
196
|
+
| `config` | `Partial<FeedValueConfig>` | No | - | Configuration overrides |
|
|
197
|
+
| `headless` | `boolean` | No | `false` | Disable all DOM rendering |
|
|
198
|
+
| `onReady` | `() => void` | No | - | Called when widget is ready |
|
|
199
|
+
| `onOpen` | `() => void` | No | - | Called when modal opens |
|
|
200
|
+
| `onClose` | `() => void` | No | - | Called when modal closes |
|
|
201
|
+
| `onSubmit` | `(feedback: FeedbackData) => void` | No | - | Called when feedback is submitted |
|
|
202
|
+
| `onError` | `(error: Error) => void` | No | - | Called on errors |
|
|
154
203
|
|
|
155
204
|
### `useFeedValue()`
|
|
156
205
|
|
|
@@ -160,11 +209,13 @@ Returns:
|
|
|
160
209
|
|
|
161
210
|
| Property | Type | Description |
|
|
162
211
|
|----------|------|-------------|
|
|
212
|
+
| `instance` | `FeedValue \| null` | Raw FeedValue instance (advanced usage) |
|
|
163
213
|
| `isReady` | `boolean` | Widget is initialized |
|
|
164
214
|
| `isOpen` | `boolean` | Modal is open |
|
|
165
215
|
| `isVisible` | `boolean` | Trigger button is visible |
|
|
166
216
|
| `error` | `Error \| null` | Current error |
|
|
167
217
|
| `isSubmitting` | `boolean` | Submission in progress |
|
|
218
|
+
| `isHeadless` | `boolean` | Running in headless mode |
|
|
168
219
|
| `open` | `() => void` | Open the modal |
|
|
169
220
|
| `close` | `() => void` | Close the modal |
|
|
170
221
|
| `toggle` | `() => void` | Toggle modal |
|
|
@@ -179,19 +230,6 @@ Returns:
|
|
|
179
230
|
|
|
180
231
|
Same as `useFeedValue()` but returns `null` if used outside provider instead of throwing.
|
|
181
232
|
|
|
182
|
-
### `<FeedValueWidget>`
|
|
183
|
-
|
|
184
|
-
Standalone widget component that doesn't require a provider.
|
|
185
|
-
|
|
186
|
-
| Prop | Type | Required | Description |
|
|
187
|
-
|------|------|----------|-------------|
|
|
188
|
-
| `widgetId` | `string` | Yes | Widget ID from FeedValue dashboard |
|
|
189
|
-
| `apiBaseUrl` | `string` | No | Custom API URL |
|
|
190
|
-
| `config` | `Partial<FeedValueConfig>` | No | Configuration overrides |
|
|
191
|
-
| `onReady` | `() => void` | No | Ready callback |
|
|
192
|
-
| `onSubmit` | `(feedback) => void` | No | Submit callback |
|
|
193
|
-
| `onError` | `(error) => void` | No | Error callback |
|
|
194
|
-
|
|
195
233
|
## Server-Side Rendering
|
|
196
234
|
|
|
197
235
|
The SDK is fully SSR-compatible. It uses `useSyncExternalStore` for concurrent mode support and returns safe default values during server rendering.
|
|
@@ -214,6 +252,18 @@ export function FeedbackButton() {
|
|
|
214
252
|
}
|
|
215
253
|
```
|
|
216
254
|
|
|
255
|
+
## Default vs Headless Mode
|
|
256
|
+
|
|
257
|
+
| Feature | Default Mode | Headless Mode |
|
|
258
|
+
|---------|--------------|---------------|
|
|
259
|
+
| Trigger button | Dashboard-styled | You build it |
|
|
260
|
+
| Modal | Dashboard-styled | You build it |
|
|
261
|
+
| API methods | Available | Available |
|
|
262
|
+
| User tracking | Available | Available |
|
|
263
|
+
| Dashboard config | Fetched | Fetched |
|
|
264
|
+
|
|
265
|
+
Use `headless={true}` when you want complete control over the UI.
|
|
266
|
+
|
|
217
267
|
## Requirements
|
|
218
268
|
|
|
219
269
|
- React 18.0.0 or higher
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feedvalue/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "FeedValue React SDK - Provider, Hooks, and Components for React 18+",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -23,12 +23,22 @@
|
|
|
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
|
"react": ">=18.0.0",
|
|
28
38
|
"react-dom": ">=18.0.0"
|
|
29
39
|
},
|
|
30
40
|
"dependencies": {
|
|
31
|
-
"@feedvalue/core": "
|
|
41
|
+
"@feedvalue/core": "workspace:^"
|
|
32
42
|
},
|
|
33
43
|
"devDependencies": {
|
|
34
44
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -36,7 +46,6 @@
|
|
|
36
46
|
"@types/react": "^19.0.0",
|
|
37
47
|
"@types/react-dom": "^19.0.0",
|
|
38
48
|
"@vitest/coverage-v8": "^2.1.0",
|
|
39
|
-
"eslint": "^9.17.0",
|
|
40
49
|
"happy-dom": "^15.11.0",
|
|
41
50
|
"react": "^19.0.0",
|
|
42
51
|
"react-dom": "^19.0.0",
|
|
@@ -68,15 +77,5 @@
|
|
|
68
77
|
],
|
|
69
78
|
"engines": {
|
|
70
79
|
"node": ">=18"
|
|
71
|
-
},
|
|
72
|
-
"scripts": {
|
|
73
|
-
"build": "tsup",
|
|
74
|
-
"dev": "tsup --watch",
|
|
75
|
-
"lint": "eslint src --ext .ts,.tsx",
|
|
76
|
-
"test": "vitest run",
|
|
77
|
-
"test:watch": "vitest",
|
|
78
|
-
"test:coverage": "vitest run --coverage",
|
|
79
|
-
"typecheck": "tsc --noEmit",
|
|
80
|
-
"clean": "rm -rf dist"
|
|
81
80
|
}
|
|
82
|
-
}
|
|
81
|
+
}
|