feedback-vos 1.0.34 → 1.0.36
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 +113 -14
- package/dist/index.js +46 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -18
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,30 +18,54 @@ npm install feedback-vos
|
|
|
18
18
|
|
|
19
19
|
## Quick Start
|
|
20
20
|
|
|
21
|
+
Since the Widget component requires client-side features, you need to create a client component wrapper.
|
|
22
|
+
|
|
23
|
+
**Step 1:** Create a client component wrapper:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// app/components/FeedbackWidget.tsx
|
|
27
|
+
'use client'
|
|
28
|
+
|
|
29
|
+
import { Widget } from 'feedback-vos'
|
|
30
|
+
import 'feedback-vos/styles'
|
|
31
|
+
|
|
32
|
+
export default function FeedbackWidget() {
|
|
33
|
+
return (
|
|
34
|
+
<Widget
|
|
35
|
+
integration="github"
|
|
36
|
+
githubConfig={{
|
|
37
|
+
token: process.env.NEXT_PUBLIC_GITHUB_TOKEN!,
|
|
38
|
+
owner: process.env.NEXT_PUBLIC_GITHUB_OWNER!,
|
|
39
|
+
repo: process.env.NEXT_PUBLIC_GITHUB_REPO!,
|
|
40
|
+
}}
|
|
41
|
+
position={process.env.NEXT_PUBLIC_FEEDBACK_POSITION as 'bottom-right' | 'bottom-left' | undefined}
|
|
42
|
+
language={process.env.NEXT_PUBLIC_FEEDBACK_LANG as 'en' | 'nl' | undefined}
|
|
43
|
+
theme={process.env.NEXT_PUBLIC_FEEDBACK_THEME as 'light' | 'dark' | undefined}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Important:**
|
|
50
|
+
- The `'use client'` directive must be at the very top of the file (before any imports)
|
|
51
|
+
- Both imports (`Widget` and `'feedback-vos/styles'`) are required
|
|
52
|
+
- Make sure the file is saved and your dev server is restarted after creating this component
|
|
53
|
+
|
|
54
|
+
**Step 2:** Use the wrapper in your layout:
|
|
55
|
+
|
|
21
56
|
```tsx
|
|
22
57
|
// app/layout.tsx
|
|
23
|
-
import
|
|
24
|
-
import 'feedback-vos/styles';
|
|
58
|
+
import FeedbackWidget from './components/FeedbackWidget'
|
|
25
59
|
|
|
26
60
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
27
61
|
return (
|
|
28
62
|
<html lang="en">
|
|
29
63
|
<body>
|
|
30
64
|
{children}
|
|
31
|
-
<
|
|
32
|
-
integration="github"
|
|
33
|
-
githubConfig={{
|
|
34
|
-
token: process.env.NEXT_PUBLIC_GITHUB_TOKEN!,
|
|
35
|
-
owner: process.env.NEXT_PUBLIC_GITHUB_OWNER!,
|
|
36
|
-
repo: process.env.NEXT_PUBLIC_GITHUB_REPO!,
|
|
37
|
-
}}
|
|
38
|
-
position={process.env.NEXT_PUBLIC_FEEDBACK_POSITION as 'bottom-right' | 'bottom-left' | undefined}
|
|
39
|
-
language={process.env.NEXT_PUBLIC_FEEDBACK_LANG as 'en' | 'nl' | undefined}
|
|
40
|
-
theme={process.env.NEXT_PUBLIC_FEEDBACK_THEME as 'light' | 'dark' | undefined}
|
|
41
|
-
/>
|
|
65
|
+
<FeedbackWidget />
|
|
42
66
|
</body>
|
|
43
67
|
</html>
|
|
44
|
-
)
|
|
68
|
+
)
|
|
45
69
|
}
|
|
46
70
|
```
|
|
47
71
|
|
|
@@ -105,6 +129,57 @@ When feedback is submitted:
|
|
|
105
129
|
|
|
106
130
|
## Troubleshooting
|
|
107
131
|
|
|
132
|
+
### Widget Not Visible
|
|
133
|
+
|
|
134
|
+
The widget uses inline styles to ensure it's always visible, even with CSS conflicts. If the widget is still not showing up, check the following:
|
|
135
|
+
|
|
136
|
+
1. **Verify the client component wrapper is created correctly:**
|
|
137
|
+
- Ensure `'use client'` directive is at the top of your `FeedbackWidget.tsx`
|
|
138
|
+
- Verify the component is imported and used in `layout.tsx`
|
|
139
|
+
|
|
140
|
+
2. **Check environment variables:**
|
|
141
|
+
- Ensure all `NEXT_PUBLIC_*` variables are in `.env.local` (not `.env`)
|
|
142
|
+
- Restart your Next.js dev server after adding/changing environment variables
|
|
143
|
+
- Verify `NEXT_PUBLIC_FEEDBACK_ENABLED` is not set to `'false'` or `'0'`
|
|
144
|
+
|
|
145
|
+
3. **Verify styles are imported:**
|
|
146
|
+
- Ensure `import 'feedback-vos/styles'` is in your `FeedbackWidget.tsx`
|
|
147
|
+
- Check browser console for CSS loading errors
|
|
148
|
+
|
|
149
|
+
4. **Check for CSS conflicts:**
|
|
150
|
+
- The widget uses `z-50` for positioning - ensure no other styles override this
|
|
151
|
+
- Verify Tailwind CSS is properly configured in your project
|
|
152
|
+
- **CRITICAL:** The widget requires `brand` colors in your Tailwind config (see Requirements section below)
|
|
153
|
+
- **Widget outside viewport or not visible:** If the widget appears outside the screen or is not visible, add this CSS to your global stylesheet (e.g., `globals.css`):
|
|
154
|
+
```css
|
|
155
|
+
[data-feedback-widget="true"] {
|
|
156
|
+
position: fixed !important;
|
|
157
|
+
bottom: 1rem !important;
|
|
158
|
+
right: 1rem !important;
|
|
159
|
+
z-index: 9999 !important;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
This ensures the widget is always visible regardless of CSS conflicts or parent container transforms.
|
|
163
|
+
|
|
164
|
+
5. **Debug in browser console:**
|
|
165
|
+
```javascript
|
|
166
|
+
// Check if widget element exists
|
|
167
|
+
document.querySelector('[data-feedback-widget="true"]')
|
|
168
|
+
|
|
169
|
+
// Check environment variable (client-side)
|
|
170
|
+
console.log(process.env.NEXT_PUBLIC_FEEDBACK_ENABLED)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
6. **Common mistakes:**
|
|
174
|
+
- ❌ Forgetting to add `'use client'` directive
|
|
175
|
+
- ❌ Not importing `'feedback-vos/styles'`
|
|
176
|
+
- ❌ Using `.env` instead of `.env.local` for environment variables
|
|
177
|
+
- ❌ Not restarting the dev server after adding environment variables
|
|
178
|
+
- ❌ Importing `Widget` directly in `layout.tsx` instead of using the wrapper component
|
|
179
|
+
- ❌ **Missing `brand` colors in Tailwind config (widget button will be invisible!)**
|
|
180
|
+
|
|
181
|
+
### GitHub Integration Issues
|
|
182
|
+
|
|
108
183
|
- **404:** Check repository exists, case-sensitive `owner/repo`, token access, Issues enabled
|
|
109
184
|
- **401:** Invalid/expired token or missing scope
|
|
110
185
|
- **403:** No issue permissions, Issues disabled, or rate limit exceeded
|
|
@@ -115,6 +190,30 @@ When feedback is submitted:
|
|
|
115
190
|
- React 18+ or 19+
|
|
116
191
|
- Tailwind CSS
|
|
117
192
|
|
|
193
|
+
### Tailwind CSS Configuration
|
|
194
|
+
|
|
195
|
+
The widget uses custom brand colors. Add these to your `tailwind.config.js`:
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
/** @type {import('tailwindcss').Config} */
|
|
199
|
+
module.exports = {
|
|
200
|
+
// ... your existing config
|
|
201
|
+
theme: {
|
|
202
|
+
extend: {
|
|
203
|
+
colors: {
|
|
204
|
+
brand: {
|
|
205
|
+
300: '#E86A4A',
|
|
206
|
+
400: '#E86A4A', // Optional, for hover states
|
|
207
|
+
500: '#D4421E',
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Important:** Without these brand colors, the widget button will not be visible!
|
|
216
|
+
|
|
118
217
|
## License
|
|
119
218
|
|
|
120
219
|
MIT License
|
package/dist/index.js
CHANGED
|
@@ -1412,7 +1412,7 @@ function getDefaultLanguage() {
|
|
|
1412
1412
|
}
|
|
1413
1413
|
function isWidgetEnabled() {
|
|
1414
1414
|
if (typeof process !== "undefined" && process.env.NEXT_PUBLIC_FEEDBACK_ENABLED !== void 0) {
|
|
1415
|
-
const enabled = process.env.NEXT_PUBLIC_FEEDBACK_ENABLED.toLowerCase();
|
|
1415
|
+
const enabled = String(process.env.NEXT_PUBLIC_FEEDBACK_ENABLED).toLowerCase().trim();
|
|
1416
1416
|
return enabled !== "false" && enabled !== "0";
|
|
1417
1417
|
}
|
|
1418
1418
|
return true;
|
|
@@ -1440,24 +1440,52 @@ function Widget({
|
|
|
1440
1440
|
const isLeft = position.includes("left");
|
|
1441
1441
|
const panelPositionClass = isTop ? "absolute top-full mt-2" : "absolute bottom-full mb-2";
|
|
1442
1442
|
const panelAlignmentClass = isLeft ? "left-0" : "right-0";
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1443
|
+
const getPositionStyles = () => {
|
|
1444
|
+
const baseStyles = {
|
|
1445
|
+
position: "fixed",
|
|
1446
|
+
zIndex: 9999
|
|
1447
|
+
};
|
|
1448
|
+
if (position === "bottom-right") {
|
|
1449
|
+
baseStyles.bottom = "1rem";
|
|
1450
|
+
baseStyles.right = "1rem";
|
|
1451
|
+
} else if (position === "bottom-left") {
|
|
1452
|
+
baseStyles.bottom = "1rem";
|
|
1453
|
+
baseStyles.left = "1rem";
|
|
1454
|
+
} else if (position === "top-right") {
|
|
1455
|
+
baseStyles.top = "1rem";
|
|
1456
|
+
baseStyles.right = "1rem";
|
|
1457
|
+
} else if (position === "top-left") {
|
|
1458
|
+
baseStyles.top = "1rem";
|
|
1459
|
+
baseStyles.left = "1rem";
|
|
1460
|
+
}
|
|
1461
|
+
return baseStyles;
|
|
1462
|
+
};
|
|
1463
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1464
|
+
"div",
|
|
1465
|
+
{
|
|
1466
|
+
"data-feedback-widget": "true",
|
|
1467
|
+
className: `fixed ${positionClasses[position]} z-50`,
|
|
1468
|
+
style: getPositionStyles(),
|
|
1469
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(react.Popover, { className: "relative", children: [
|
|
1470
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Popover.Panel, { className: `${panelPositionClass} ${panelAlignmentClass}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1471
|
+
WidgetForm,
|
|
1472
|
+
{
|
|
1473
|
+
integration,
|
|
1474
|
+
githubConfig,
|
|
1475
|
+
language: finalLanguage,
|
|
1476
|
+
theme: finalTheme
|
|
1477
|
+
}
|
|
1478
|
+
) }),
|
|
1479
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Popover.Button, { className: "bg-brand-500 rounded-full px-3 md:px-3 h-12 text-white flex items-center group focus:outline-none shadow-lg hover:shadow-xl transition-shadow", children: [
|
|
1480
|
+
/* @__PURE__ */ jsxRuntime.jsx(phosphorReact.ChatTeardropDots, { className: "w-6 h-6 flex-shrink-0" }),
|
|
1481
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "max-w-0 overflow-hidden group-hover:max-w-xs md:group-hover:max-w-xs transition-all duration-500 ease-linear hidden md:block", children: [
|
|
1482
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pl-2" }),
|
|
1483
|
+
t.widget.button
|
|
1484
|
+
] })
|
|
1485
|
+
] })
|
|
1458
1486
|
] })
|
|
1459
|
-
|
|
1460
|
-
|
|
1487
|
+
}
|
|
1488
|
+
);
|
|
1461
1489
|
}
|
|
1462
1490
|
|
|
1463
1491
|
exports.Widget = Widget;
|